1 /* 2 * Copyright (C) 2010 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 "ACodec" 19 20 #ifdef __LP64__ 21 #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 22 #endif 23 24 #include <inttypes.h> 25 #include <utils/Trace.h> 26 27 #include <gui/Surface.h> 28 29 #include <media/stagefright/ACodec.h> 30 31 #include <binder/MemoryDealer.h> 32 33 #include <media/stagefright/foundation/hexdump.h> 34 #include <media/stagefright/foundation/ABuffer.h> 35 #include <media/stagefright/foundation/ADebug.h> 36 #include <media/stagefright/foundation/AMessage.h> 37 #include <media/stagefright/foundation/AUtils.h> 38 39 #include <media/stagefright/BufferProducerWrapper.h> 40 #include <media/stagefright/MediaCodec.h> 41 #include <media/stagefright/MediaCodecList.h> 42 #include <media/stagefright/MediaDefs.h> 43 #include <media/stagefright/OMXClient.h> 44 #include <media/stagefright/PersistentSurface.h> 45 #include <media/stagefright/SurfaceUtils.h> 46 #include <media/hardware/HardwareAPI.h> 47 #include <media/OMXBuffer.h> 48 #include <media/omx/1.0/WOmxNode.h> 49 50 #include <hidlmemory/mapping.h> 51 52 #include <OMX_AudioExt.h> 53 #include <OMX_VideoExt.h> 54 #include <OMX_Component.h> 55 #include <OMX_IndexExt.h> 56 #include <OMX_AsString.h> 57 58 #include "include/avc_utils.h" 59 #include "include/ACodecBufferChannel.h" 60 #include "include/DataConverter.h" 61 #include "include/SecureBuffer.h" 62 #include "include/SharedMemoryBuffer.h" 63 #include "omx/OMXUtils.h" 64 65 #include <android/hidl/allocator/1.0/IAllocator.h> 66 #include <android/hidl/memory/1.0/IMemory.h> 67 68 namespace android { 69 70 using binder::Status; 71 72 enum { 73 kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles 74 }; 75 76 // OMX errors are directly mapped into status_t range if 77 // there is no corresponding MediaError status code. 78 // Use the statusFromOMXError(int32_t omxError) function. 79 // 80 // Currently this is a direct map. 81 // See frameworks/native/include/media/openmax/OMX_Core.h 82 // 83 // Vendor OMX errors from 0x90000000 - 0x9000FFFF 84 // Extension OMX errors from 0x8F000000 - 0x90000000 85 // Standard OMX errors from 0x80001000 - 0x80001024 (0x80001024 current) 86 // 87 88 // returns true if err is a recognized OMX error code. 89 // as OMX error is OMX_S32, this is an int32_t type 90 static inline bool isOMXError(int32_t err) { 91 return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX); 92 } 93 94 // converts an OMX error to a status_t 95 static inline status_t statusFromOMXError(int32_t omxError) { 96 switch (omxError) { 97 case OMX_ErrorInvalidComponentName: 98 case OMX_ErrorComponentNotFound: 99 return NAME_NOT_FOUND; // can trigger illegal argument error for provided names. 100 default: 101 return isOMXError(omxError) ? omxError : 0; // no translation required 102 } 103 } 104 105 static inline status_t statusFromBinderStatus(const Status &status) { 106 if (status.isOk()) { 107 return OK; 108 } 109 status_t err; 110 if ((err = status.serviceSpecificErrorCode()) != OK) { 111 return err; 112 } 113 if ((err = status.transactionError()) != OK) { 114 return err; 115 } 116 // Other exception 117 return UNKNOWN_ERROR; 118 } 119 120 // checks and converts status_t to a non-side-effect status_t 121 static inline status_t makeNoSideEffectStatus(status_t err) { 122 switch (err) { 123 // the following errors have side effects and may come 124 // from other code modules. Remap for safety reasons. 125 case INVALID_OPERATION: 126 case DEAD_OBJECT: 127 return UNKNOWN_ERROR; 128 default: 129 return err; 130 } 131 } 132 133 struct MessageList : public RefBase { 134 MessageList() { 135 } 136 virtual ~MessageList() { 137 } 138 std::list<sp<AMessage> > &getList() { return mList; } 139 private: 140 std::list<sp<AMessage> > mList; 141 142 DISALLOW_EVIL_CONSTRUCTORS(MessageList); 143 }; 144 145 static sp<DataConverter> getCopyConverter() { 146 static pthread_once_t once = PTHREAD_ONCE_INIT; // const-inited 147 static sp<DataConverter> sCopyConverter; // zero-inited 148 pthread_once(&once, [](){ sCopyConverter = new DataConverter(); }); 149 return sCopyConverter; 150 } 151 152 struct CodecObserver : public BnOMXObserver { 153 CodecObserver() {} 154 155 void setNotificationMessage(const sp<AMessage> &msg) { 156 mNotify = msg; 157 } 158 159 // from IOMXObserver 160 virtual void onMessages(const std::list<omx_message> &messages) { 161 if (messages.empty()) { 162 return; 163 } 164 165 sp<AMessage> notify = mNotify->dup(); 166 sp<MessageList> msgList = new MessageList(); 167 for (std::list<omx_message>::const_iterator it = messages.cbegin(); 168 it != messages.cend(); ++it) { 169 const omx_message &omx_msg = *it; 170 171 sp<AMessage> msg = new AMessage; 172 msg->setInt32("type", omx_msg.type); 173 switch (omx_msg.type) { 174 case omx_message::EVENT: 175 { 176 msg->setInt32("event", omx_msg.u.event_data.event); 177 msg->setInt32("data1", omx_msg.u.event_data.data1); 178 msg->setInt32("data2", omx_msg.u.event_data.data2); 179 break; 180 } 181 182 case omx_message::EMPTY_BUFFER_DONE: 183 { 184 msg->setInt32("buffer", omx_msg.u.buffer_data.buffer); 185 msg->setInt32("fence_fd", omx_msg.fenceFd); 186 break; 187 } 188 189 case omx_message::FILL_BUFFER_DONE: 190 { 191 msg->setInt32( 192 "buffer", omx_msg.u.extended_buffer_data.buffer); 193 msg->setInt32( 194 "range_offset", 195 omx_msg.u.extended_buffer_data.range_offset); 196 msg->setInt32( 197 "range_length", 198 omx_msg.u.extended_buffer_data.range_length); 199 msg->setInt32( 200 "flags", 201 omx_msg.u.extended_buffer_data.flags); 202 msg->setInt64( 203 "timestamp", 204 omx_msg.u.extended_buffer_data.timestamp); 205 msg->setInt32( 206 "fence_fd", omx_msg.fenceFd); 207 break; 208 } 209 210 case omx_message::FRAME_RENDERED: 211 { 212 msg->setInt64( 213 "media_time_us", omx_msg.u.render_data.timestamp); 214 msg->setInt64( 215 "system_nano", omx_msg.u.render_data.nanoTime); 216 break; 217 } 218 219 default: 220 ALOGE("Unrecognized message type: %d", omx_msg.type); 221 break; 222 } 223 msgList->getList().push_back(msg); 224 } 225 notify->setObject("messages", msgList); 226 notify->post(); 227 } 228 229 protected: 230 virtual ~CodecObserver() {} 231 232 private: 233 sp<AMessage> mNotify; 234 235 DISALLOW_EVIL_CONSTRUCTORS(CodecObserver); 236 }; 237 238 //////////////////////////////////////////////////////////////////////////////// 239 240 struct ACodec::BaseState : public AState { 241 explicit BaseState(ACodec *codec, const sp<AState> &parentState = NULL); 242 243 protected: 244 enum PortMode { 245 KEEP_BUFFERS, 246 RESUBMIT_BUFFERS, 247 FREE_BUFFERS, 248 }; 249 250 ACodec *mCodec; 251 252 virtual PortMode getPortMode(OMX_U32 portIndex); 253 254 virtual void stateExited(); 255 virtual bool onMessageReceived(const sp<AMessage> &msg); 256 257 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 258 259 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 260 virtual void onInputBufferFilled(const sp<AMessage> &msg); 261 262 void postFillThisBuffer(BufferInfo *info); 263 264 private: 265 // Handles an OMX message. Returns true iff message was handled. 266 bool onOMXMessage(const sp<AMessage> &msg); 267 268 // Handles a list of messages. Returns true iff messages were handled. 269 bool onOMXMessageList(const sp<AMessage> &msg); 270 271 // returns true iff this message is for this component and the component is alive 272 bool checkOMXMessage(const sp<AMessage> &msg); 273 274 bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd); 275 276 bool onOMXFillBufferDone( 277 IOMX::buffer_id bufferID, 278 size_t rangeOffset, size_t rangeLength, 279 OMX_U32 flags, 280 int64_t timeUs, 281 int fenceFd); 282 283 virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); 284 285 void getMoreInputDataIfPossible(); 286 287 DISALLOW_EVIL_CONSTRUCTORS(BaseState); 288 }; 289 290 //////////////////////////////////////////////////////////////////////////////// 291 292 struct ACodec::DeathNotifier : 293 public IBinder::DeathRecipient, 294 public ::android::hardware::hidl_death_recipient { 295 explicit DeathNotifier(const sp<AMessage> ¬ify) 296 : mNotify(notify) { 297 } 298 299 virtual void binderDied(const wp<IBinder> &) { 300 mNotify->post(); 301 } 302 303 virtual void serviceDied( 304 uint64_t /* cookie */, 305 const wp<::android::hidl::base::V1_0::IBase>& /* who */) { 306 mNotify->post(); 307 } 308 309 protected: 310 virtual ~DeathNotifier() {} 311 312 private: 313 sp<AMessage> mNotify; 314 315 DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier); 316 }; 317 318 struct ACodec::UninitializedState : public ACodec::BaseState { 319 explicit UninitializedState(ACodec *codec); 320 321 protected: 322 virtual bool onMessageReceived(const sp<AMessage> &msg); 323 virtual void stateEntered(); 324 325 private: 326 void onSetup(const sp<AMessage> &msg); 327 bool onAllocateComponent(const sp<AMessage> &msg); 328 329 sp<DeathNotifier> mDeathNotifier; 330 331 DISALLOW_EVIL_CONSTRUCTORS(UninitializedState); 332 }; 333 334 //////////////////////////////////////////////////////////////////////////////// 335 336 struct ACodec::LoadedState : public ACodec::BaseState { 337 explicit LoadedState(ACodec *codec); 338 339 protected: 340 virtual bool onMessageReceived(const sp<AMessage> &msg); 341 virtual void stateEntered(); 342 343 private: 344 friend struct ACodec::UninitializedState; 345 346 bool onConfigureComponent(const sp<AMessage> &msg); 347 void onCreateInputSurface(const sp<AMessage> &msg); 348 void onSetInputSurface(const sp<AMessage> &msg); 349 void onStart(); 350 void onShutdown(bool keepComponentAllocated); 351 352 status_t setupInputSurface(); 353 354 DISALLOW_EVIL_CONSTRUCTORS(LoadedState); 355 }; 356 357 //////////////////////////////////////////////////////////////////////////////// 358 359 struct ACodec::LoadedToIdleState : public ACodec::BaseState { 360 explicit LoadedToIdleState(ACodec *codec); 361 362 protected: 363 virtual bool onMessageReceived(const sp<AMessage> &msg); 364 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 365 virtual void stateEntered(); 366 367 private: 368 status_t allocateBuffers(); 369 370 DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState); 371 }; 372 373 //////////////////////////////////////////////////////////////////////////////// 374 375 struct ACodec::IdleToExecutingState : public ACodec::BaseState { 376 explicit IdleToExecutingState(ACodec *codec); 377 378 protected: 379 virtual bool onMessageReceived(const sp<AMessage> &msg); 380 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 381 virtual void stateEntered(); 382 383 private: 384 DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState); 385 }; 386 387 //////////////////////////////////////////////////////////////////////////////// 388 389 struct ACodec::ExecutingState : public ACodec::BaseState { 390 explicit ExecutingState(ACodec *codec); 391 392 void submitRegularOutputBuffers(); 393 void submitOutputMetaBuffers(); 394 void submitOutputBuffers(); 395 396 // Submit output buffers to the decoder, submit input buffers to client 397 // to fill with data. 398 void resume(); 399 400 // Returns true iff input and output buffers are in play. 401 bool active() const { return mActive; } 402 403 protected: 404 virtual PortMode getPortMode(OMX_U32 portIndex); 405 virtual bool onMessageReceived(const sp<AMessage> &msg); 406 virtual void stateEntered(); 407 408 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 409 virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); 410 411 private: 412 bool mActive; 413 414 DISALLOW_EVIL_CONSTRUCTORS(ExecutingState); 415 }; 416 417 //////////////////////////////////////////////////////////////////////////////// 418 419 struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState { 420 explicit OutputPortSettingsChangedState(ACodec *codec); 421 422 protected: 423 virtual PortMode getPortMode(OMX_U32 portIndex); 424 virtual bool onMessageReceived(const sp<AMessage> &msg); 425 virtual void stateEntered(); 426 427 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 428 virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); 429 430 private: 431 DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState); 432 }; 433 434 //////////////////////////////////////////////////////////////////////////////// 435 436 struct ACodec::ExecutingToIdleState : public ACodec::BaseState { 437 explicit ExecutingToIdleState(ACodec *codec); 438 439 protected: 440 virtual bool onMessageReceived(const sp<AMessage> &msg); 441 virtual void stateEntered(); 442 443 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 444 445 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 446 virtual void onInputBufferFilled(const sp<AMessage> &msg); 447 448 private: 449 void changeStateIfWeOwnAllBuffers(); 450 451 bool mComponentNowIdle; 452 453 DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState); 454 }; 455 456 //////////////////////////////////////////////////////////////////////////////// 457 458 struct ACodec::IdleToLoadedState : public ACodec::BaseState { 459 explicit IdleToLoadedState(ACodec *codec); 460 461 protected: 462 virtual bool onMessageReceived(const sp<AMessage> &msg); 463 virtual void stateEntered(); 464 465 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 466 467 private: 468 DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState); 469 }; 470 471 //////////////////////////////////////////////////////////////////////////////// 472 473 struct ACodec::FlushingState : public ACodec::BaseState { 474 explicit FlushingState(ACodec *codec); 475 476 protected: 477 virtual bool onMessageReceived(const sp<AMessage> &msg); 478 virtual void stateEntered(); 479 480 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 481 482 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 483 virtual void onInputBufferFilled(const sp<AMessage> &msg); 484 485 private: 486 bool mFlushComplete[2]; 487 488 void changeStateIfWeOwnAllBuffers(); 489 490 DISALLOW_EVIL_CONSTRUCTORS(FlushingState); 491 }; 492 493 //////////////////////////////////////////////////////////////////////////////// 494 495 void ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) { 496 if (mFenceFd >= 0) { 497 ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s", 498 mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg); 499 } 500 mFenceFd = fenceFd; 501 mIsReadFence = false; 502 } 503 504 void ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) { 505 if (mFenceFd >= 0) { 506 ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s", 507 mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg); 508 } 509 mFenceFd = fenceFd; 510 mIsReadFence = true; 511 } 512 513 void ACodec::BufferInfo::checkWriteFence(const char *dbg) { 514 if (mFenceFd >= 0 && mIsReadFence) { 515 ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg); 516 } 517 } 518 519 void ACodec::BufferInfo::checkReadFence(const char *dbg) { 520 if (mFenceFd >= 0 && !mIsReadFence) { 521 ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg); 522 } 523 } 524 525 //////////////////////////////////////////////////////////////////////////////// 526 527 ACodec::ACodec() 528 : mSampleRate(0), 529 mNodeGeneration(0), 530 mUsingNativeWindow(false), 531 mNativeWindowUsageBits(0), 532 mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN), 533 mIsVideo(false), 534 mIsEncoder(false), 535 mFatalError(false), 536 mShutdownInProgress(false), 537 mExplicitShutdown(false), 538 mIsLegacyVP9Decoder(false), 539 mEncoderDelay(0), 540 mEncoderPadding(0), 541 mRotationDegrees(0), 542 mChannelMaskPresent(false), 543 mChannelMask(0), 544 mDequeueCounter(0), 545 mMetadataBuffersToSubmit(0), 546 mNumUndequeuedBuffers(0), 547 mRepeatFrameDelayUs(-1ll), 548 mMaxPtsGapUs(-1ll), 549 mMaxFps(-1), 550 mFps(-1.0), 551 mCaptureFps(-1.0), 552 mCreateInputBuffersSuspended(false), 553 mLatency(0), 554 mTunneled(false), 555 mDescribeColorAspectsIndex((OMX_INDEXTYPE)0), 556 mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0), 557 mStateGeneration(0), 558 mVendorExtensionsStatus(kExtensionsUnchecked) { 559 mUninitializedState = new UninitializedState(this); 560 mLoadedState = new LoadedState(this); 561 mLoadedToIdleState = new LoadedToIdleState(this); 562 mIdleToExecutingState = new IdleToExecutingState(this); 563 mExecutingState = new ExecutingState(this); 564 565 mOutputPortSettingsChangedState = 566 new OutputPortSettingsChangedState(this); 567 568 mExecutingToIdleState = new ExecutingToIdleState(this); 569 mIdleToLoadedState = new IdleToLoadedState(this); 570 mFlushingState = new FlushingState(this); 571 572 mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false; 573 mInputEOSResult = OK; 574 575 mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer; 576 mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer; 577 578 memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop)); 579 580 changeState(mUninitializedState); 581 582 mTrebleFlag = false; 583 } 584 585 ACodec::~ACodec() { 586 } 587 588 void ACodec::initiateSetup(const sp<AMessage> &msg) { 589 msg->setWhat(kWhatSetup); 590 msg->setTarget(this); 591 msg->post(); 592 } 593 594 std::shared_ptr<BufferChannelBase> ACodec::getBufferChannel() { 595 if (!mBufferChannel) { 596 mBufferChannel = std::make_shared<ACodecBufferChannel>( 597 new AMessage(kWhatInputBufferFilled, this), 598 new AMessage(kWhatOutputBufferDrained, this)); 599 } 600 return mBufferChannel; 601 } 602 603 void ACodec::signalSetParameters(const sp<AMessage> ¶ms) { 604 sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 605 msg->setMessage("params", params); 606 msg->post(); 607 } 608 609 void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) { 610 msg->setWhat(kWhatAllocateComponent); 611 msg->setTarget(this); 612 msg->post(); 613 } 614 615 void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) { 616 msg->setWhat(kWhatConfigureComponent); 617 msg->setTarget(this); 618 msg->post(); 619 } 620 621 status_t ACodec::setSurface(const sp<Surface> &surface) { 622 sp<AMessage> msg = new AMessage(kWhatSetSurface, this); 623 msg->setObject("surface", surface); 624 625 sp<AMessage> response; 626 status_t err = msg->postAndAwaitResponse(&response); 627 628 if (err == OK) { 629 (void)response->findInt32("err", &err); 630 } 631 return err; 632 } 633 634 void ACodec::initiateCreateInputSurface() { 635 (new AMessage(kWhatCreateInputSurface, this))->post(); 636 } 637 638 void ACodec::initiateSetInputSurface( 639 const sp<PersistentSurface> &surface) { 640 sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this); 641 msg->setObject("input-surface", surface); 642 msg->post(); 643 } 644 645 void ACodec::signalEndOfInputStream() { 646 (new AMessage(kWhatSignalEndOfInputStream, this))->post(); 647 } 648 649 void ACodec::initiateStart() { 650 (new AMessage(kWhatStart, this))->post(); 651 } 652 653 void ACodec::signalFlush() { 654 ALOGV("[%s] signalFlush", mComponentName.c_str()); 655 (new AMessage(kWhatFlush, this))->post(); 656 } 657 658 void ACodec::signalResume() { 659 (new AMessage(kWhatResume, this))->post(); 660 } 661 662 void ACodec::initiateShutdown(bool keepComponentAllocated) { 663 sp<AMessage> msg = new AMessage(kWhatShutdown, this); 664 msg->setInt32("keepComponentAllocated", keepComponentAllocated); 665 msg->post(); 666 if (!keepComponentAllocated) { 667 // ensure shutdown completes in 3 seconds 668 (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000); 669 } 670 } 671 672 void ACodec::signalRequestIDRFrame() { 673 (new AMessage(kWhatRequestIDRFrame, this))->post(); 674 } 675 676 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 677 // Some codecs may return input buffers before having them processed. 678 // This causes a halt if we already signaled an EOS on the input 679 // port. For now keep submitting an output buffer if there was an 680 // EOS on the input port, but not yet on the output port. 681 void ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() { 682 if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] && 683 mMetadataBuffersToSubmit > 0) { 684 (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post(); 685 } 686 } 687 688 status_t ACodec::handleSetSurface(const sp<Surface> &surface) { 689 // allow keeping unset surface 690 if (surface == NULL) { 691 if (mNativeWindow != NULL) { 692 ALOGW("cannot unset a surface"); 693 return INVALID_OPERATION; 694 } 695 return OK; 696 } 697 698 // cannot switch from bytebuffers to surface 699 if (mNativeWindow == NULL) { 700 ALOGW("component was not configured with a surface"); 701 return INVALID_OPERATION; 702 } 703 704 ANativeWindow *nativeWindow = surface.get(); 705 // if we have not yet started the codec, we can simply set the native window 706 if (mBuffers[kPortIndexInput].size() == 0) { 707 mNativeWindow = surface; 708 return OK; 709 } 710 711 // we do not support changing a tunneled surface after start 712 if (mTunneled) { 713 ALOGW("cannot change tunneled surface"); 714 return INVALID_OPERATION; 715 } 716 717 int usageBits = 0; 718 // no need to reconnect as we will not dequeue all buffers 719 status_t err = setupNativeWindowSizeFormatAndUsage( 720 nativeWindow, &usageBits, !storingMetadataInDecodedBuffers()); 721 if (err != OK) { 722 return err; 723 } 724 725 int ignoredFlags = kVideoGrallocUsage; 726 // New output surface is not allowed to add new usage flag except ignored ones. 727 if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) { 728 ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits); 729 return BAD_VALUE; 730 } 731 732 // get min undequeued count. We cannot switch to a surface that has a higher 733 // undequeued count than we allocated. 734 int minUndequeuedBuffers = 0; 735 err = nativeWindow->query( 736 nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 737 &minUndequeuedBuffers); 738 if (err != 0) { 739 ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 740 strerror(-err), -err); 741 return err; 742 } 743 if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) { 744 ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)", 745 minUndequeuedBuffers, mNumUndequeuedBuffers); 746 return BAD_VALUE; 747 } 748 749 // we cannot change the number of output buffers while OMX is running 750 // set up surface to the same count 751 Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput]; 752 ALOGV("setting up surface for %zu buffers", buffers.size()); 753 754 err = native_window_set_buffer_count(nativeWindow, buffers.size()); 755 if (err != 0) { 756 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 757 -err); 758 return err; 759 } 760 761 // need to enable allocation when attaching 762 surface->getIGraphicBufferProducer()->allowAllocation(true); 763 764 // for meta data mode, we move dequeud buffers to the new surface. 765 // for non-meta mode, we must move all registered buffers 766 for (size_t i = 0; i < buffers.size(); ++i) { 767 const BufferInfo &info = buffers[i]; 768 // skip undequeued buffers for meta data mode 769 if (storingMetadataInDecodedBuffers() 770 && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 771 ALOGV("skipping buffer"); 772 continue; 773 } 774 ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer()); 775 776 err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer()); 777 if (err != OK) { 778 ALOGE("failed to attach buffer %p to the new surface: %s (%d)", 779 info.mGraphicBuffer->getNativeBuffer(), 780 strerror(-err), -err); 781 return err; 782 } 783 } 784 785 // cancel undequeued buffers to new surface 786 if (!storingMetadataInDecodedBuffers()) { 787 for (size_t i = 0; i < buffers.size(); ++i) { 788 BufferInfo &info = buffers.editItemAt(i); 789 if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 790 ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer()); 791 err = nativeWindow->cancelBuffer( 792 nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd); 793 info.mFenceFd = -1; 794 if (err != OK) { 795 ALOGE("failed to cancel buffer %p to the new surface: %s (%d)", 796 info.mGraphicBuffer->getNativeBuffer(), 797 strerror(-err), -err); 798 return err; 799 } 800 } 801 } 802 // disallow further allocation 803 (void)surface->getIGraphicBufferProducer()->allowAllocation(false); 804 } 805 806 // push blank buffers to previous window if requested 807 if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) { 808 pushBlankBuffersToNativeWindow(mNativeWindow.get()); 809 } 810 811 mNativeWindow = nativeWindow; 812 mNativeWindowUsageBits = usageBits; 813 return OK; 814 } 815 816 status_t ACodec::setPortMode(int32_t portIndex, IOMX::PortMode mode) { 817 status_t err = mOMXNode->setPortMode(portIndex, mode); 818 if (err != OK) { 819 ALOGE("[%s] setPortMode on %s to %s failed w/ err %d", 820 mComponentName.c_str(), 821 portIndex == kPortIndexInput ? "input" : "output", 822 asString(mode), 823 err); 824 return err; 825 } 826 827 mPortMode[portIndex] = mode; 828 return OK; 829 } 830 831 status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) { 832 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 833 834 if (getTrebleFlag()) { 835 CHECK(mAllocator[portIndex] == NULL); 836 } else { 837 CHECK(mDealer[portIndex] == NULL); 838 } 839 CHECK(mBuffers[portIndex].isEmpty()); 840 841 status_t err; 842 if (mNativeWindow != NULL && portIndex == kPortIndexOutput) { 843 if (storingMetadataInDecodedBuffers()) { 844 err = allocateOutputMetadataBuffers(); 845 } else { 846 err = allocateOutputBuffersFromNativeWindow(); 847 } 848 } else { 849 OMX_PARAM_PORTDEFINITIONTYPE def; 850 InitOMXParams(&def); 851 def.nPortIndex = portIndex; 852 853 err = mOMXNode->getParameter( 854 OMX_IndexParamPortDefinition, &def, sizeof(def)); 855 856 if (err == OK) { 857 const IOMX::PortMode &mode = mPortMode[portIndex]; 858 size_t bufSize = def.nBufferSize; 859 // Always allocate VideoNativeMetadata if using ANWBuffer. 860 // OMX might use gralloc source internally, but we don't share 861 // metadata buffer with OMX, OMX has its own headers. 862 if (mode == IOMX::kPortModeDynamicANWBuffer) { 863 bufSize = sizeof(VideoNativeMetadata); 864 } else if (mode == IOMX::kPortModeDynamicNativeHandle) { 865 bufSize = sizeof(VideoNativeHandleMetadata); 866 } 867 868 size_t conversionBufferSize = 0; 869 870 sp<DataConverter> converter = mConverter[portIndex]; 871 if (converter != NULL) { 872 // here we assume sane conversions of max 4:1, so result fits in int32 873 if (portIndex == kPortIndexInput) { 874 conversionBufferSize = converter->sourceSize(bufSize); 875 } else { 876 conversionBufferSize = converter->targetSize(bufSize); 877 } 878 } 879 880 size_t alignment = MemoryDealer::getAllocationAlignment(); 881 882 ALOGV("[%s] Allocating %u buffers of size %zu (from %u using %s) on %s port", 883 mComponentName.c_str(), 884 def.nBufferCountActual, bufSize, def.nBufferSize, asString(mode), 885 portIndex == kPortIndexInput ? "input" : "output"); 886 887 // verify buffer sizes to avoid overflow in align() 888 if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) { 889 ALOGE("b/22885421"); 890 return NO_MEMORY; 891 } 892 893 // don't modify bufSize as OMX may not expect it to increase after negotiation 894 size_t alignedSize = align(bufSize, alignment); 895 size_t alignedConvSize = align(conversionBufferSize, alignment); 896 if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) { 897 ALOGE("b/22885421"); 898 return NO_MEMORY; 899 } 900 901 if (mode != IOMX::kPortModePresetSecureBuffer) { 902 if (getTrebleFlag()) { 903 mAllocator[portIndex] = TAllocator::getService("ashmem"); 904 if (mAllocator[portIndex] == nullptr) { 905 ALOGE("hidl allocator on port %d is null", 906 (int)portIndex); 907 return NO_MEMORY; 908 } 909 } else { 910 size_t totalSize = def.nBufferCountActual * 911 (alignedSize + alignedConvSize); 912 mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec"); 913 } 914 } 915 916 const sp<AMessage> &format = 917 portIndex == kPortIndexInput ? mInputFormat : mOutputFormat; 918 for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) { 919 hidl_memory hidlMemToken; 920 sp<TMemory> hidlMem; 921 sp<IMemory> mem; 922 923 BufferInfo info; 924 info.mStatus = BufferInfo::OWNED_BY_US; 925 info.mFenceFd = -1; 926 info.mRenderInfo = NULL; 927 info.mGraphicBuffer = NULL; 928 info.mNewGraphicBuffer = false; 929 930 if (mode == IOMX::kPortModePresetSecureBuffer) { 931 void *ptr = NULL; 932 sp<NativeHandle> native_handle; 933 err = mOMXNode->allocateSecureBuffer( 934 portIndex, bufSize, &info.mBufferID, 935 &ptr, &native_handle); 936 937 info.mData = (native_handle == NULL) 938 ? new SecureBuffer(format, ptr, bufSize) 939 : new SecureBuffer(format, native_handle, bufSize); 940 info.mCodecData = info.mData; 941 } else { 942 if (getTrebleFlag()) { 943 bool success; 944 auto transStatus = mAllocator[portIndex]->allocate( 945 bufSize, 946 [&success, &hidlMemToken]( 947 bool s, 948 hidl_memory const& m) { 949 success = s; 950 hidlMemToken = m; 951 }); 952 953 if (!transStatus.isOk()) { 954 ALOGE("hidl's AshmemAllocator failed at the " 955 "transport: %s", 956 transStatus.description().c_str()); 957 return NO_MEMORY; 958 } 959 if (!success) { 960 return NO_MEMORY; 961 } 962 hidlMem = mapMemory(hidlMemToken); 963 964 err = mOMXNode->useBuffer( 965 portIndex, hidlMemToken, &info.mBufferID); 966 } else { 967 mem = mDealer[portIndex]->allocate(bufSize); 968 if (mem == NULL || mem->pointer() == NULL) { 969 return NO_MEMORY; 970 } 971 972 err = mOMXNode->useBuffer( 973 portIndex, mem, &info.mBufferID); 974 } 975 976 if (mode == IOMX::kPortModeDynamicANWBuffer) { 977 VideoNativeMetadata* metaData = (VideoNativeMetadata*)( 978 getTrebleFlag() ? 979 (void*)hidlMem->getPointer() : mem->pointer()); 980 metaData->nFenceFd = -1; 981 } 982 983 if (getTrebleFlag()) { 984 info.mCodecData = new SharedMemoryBuffer( 985 format, hidlMem); 986 info.mCodecRef = hidlMem; 987 } else { 988 info.mCodecData = new SharedMemoryBuffer( 989 format, mem); 990 info.mCodecRef = mem; 991 } 992 993 // if we require conversion, allocate conversion buffer for client use; 994 // otherwise, reuse codec buffer 995 if (mConverter[portIndex] != NULL) { 996 CHECK_GT(conversionBufferSize, (size_t)0); 997 if (getTrebleFlag()) { 998 bool success; 999 mAllocator[portIndex]->allocate( 1000 conversionBufferSize, 1001 [&success, &hidlMemToken]( 1002 bool s, 1003 hidl_memory const& m) { 1004 success = s; 1005 hidlMemToken = m; 1006 }); 1007 if (!success) { 1008 return NO_MEMORY; 1009 } 1010 hidlMem = mapMemory(hidlMemToken); 1011 info.mData = new SharedMemoryBuffer(format, hidlMem); 1012 info.mMemRef = hidlMem; 1013 } else { 1014 mem = mDealer[portIndex]->allocate( 1015 conversionBufferSize); 1016 if (mem == NULL|| mem->pointer() == NULL) { 1017 return NO_MEMORY; 1018 } 1019 info.mData = new SharedMemoryBuffer(format, mem); 1020 info.mMemRef = mem; 1021 } 1022 } else { 1023 info.mData = info.mCodecData; 1024 info.mMemRef = info.mCodecRef; 1025 } 1026 } 1027 1028 mBuffers[portIndex].push(info); 1029 } 1030 } 1031 } 1032 1033 if (err != OK) { 1034 return err; 1035 } 1036 1037 std::vector<ACodecBufferChannel::BufferAndId> array(mBuffers[portIndex].size()); 1038 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 1039 array[i] = {mBuffers[portIndex][i].mData, mBuffers[portIndex][i].mBufferID}; 1040 } 1041 if (portIndex == kPortIndexInput) { 1042 mBufferChannel->setInputBufferArray(array); 1043 } else if (portIndex == kPortIndexOutput) { 1044 mBufferChannel->setOutputBufferArray(array); 1045 } else { 1046 TRESPASS(); 1047 } 1048 1049 return OK; 1050 } 1051 1052 status_t ACodec::setupNativeWindowSizeFormatAndUsage( 1053 ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */, 1054 bool reconnect) { 1055 OMX_PARAM_PORTDEFINITIONTYPE def; 1056 InitOMXParams(&def); 1057 def.nPortIndex = kPortIndexOutput; 1058 1059 status_t err = mOMXNode->getParameter( 1060 OMX_IndexParamPortDefinition, &def, sizeof(def)); 1061 1062 if (err != OK) { 1063 return err; 1064 } 1065 1066 OMX_INDEXTYPE index; 1067 err = mOMXNode->getExtensionIndex( 1068 "OMX.google.android.index.AndroidNativeBufferConsumerUsage", 1069 &index); 1070 1071 if (err != OK) { 1072 // allow failure 1073 err = OK; 1074 } else { 1075 int usageBits = 0; 1076 if (nativeWindow->query( 1077 nativeWindow, 1078 NATIVE_WINDOW_CONSUMER_USAGE_BITS, 1079 &usageBits) == OK) { 1080 OMX_PARAM_U32TYPE params; 1081 InitOMXParams(¶ms); 1082 params.nPortIndex = kPortIndexOutput; 1083 params.nU32 = (OMX_U32)usageBits; 1084 1085 err = mOMXNode->setParameter(index, ¶ms, sizeof(params)); 1086 1087 if (err != OK) { 1088 ALOGE("Fail to set AndroidNativeBufferConsumerUsage: %d", err); 1089 return err; 1090 } 1091 } 1092 } 1093 1094 OMX_U32 usage = 0; 1095 err = mOMXNode->getGraphicBufferUsage(kPortIndexOutput, &usage); 1096 if (err != 0) { 1097 ALOGW("querying usage flags from OMX IL component failed: %d", err); 1098 // XXX: Currently this error is logged, but not fatal. 1099 usage = 0; 1100 } 1101 int omxUsage = usage; 1102 1103 if (mFlags & kFlagIsGrallocUsageProtected) { 1104 usage |= GRALLOC_USAGE_PROTECTED; 1105 } 1106 1107 usage |= kVideoGrallocUsage; 1108 *finalUsage = usage; 1109 1110 memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop)); 1111 mLastNativeWindowDataSpace = HAL_DATASPACE_UNKNOWN; 1112 1113 ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage); 1114 return setNativeWindowSizeFormatAndUsage( 1115 nativeWindow, 1116 def.format.video.nFrameWidth, 1117 def.format.video.nFrameHeight, 1118 def.format.video.eColorFormat, 1119 mRotationDegrees, 1120 usage, 1121 reconnect); 1122 } 1123 1124 status_t ACodec::configureOutputBuffersFromNativeWindow( 1125 OMX_U32 *bufferCount, OMX_U32 *bufferSize, 1126 OMX_U32 *minUndequeuedBuffers, bool preregister) { 1127 1128 OMX_PARAM_PORTDEFINITIONTYPE def; 1129 InitOMXParams(&def); 1130 def.nPortIndex = kPortIndexOutput; 1131 1132 status_t err = mOMXNode->getParameter( 1133 OMX_IndexParamPortDefinition, &def, sizeof(def)); 1134 1135 if (err == OK) { 1136 err = setupNativeWindowSizeFormatAndUsage( 1137 mNativeWindow.get(), &mNativeWindowUsageBits, 1138 preregister && !mTunneled /* reconnect */); 1139 } 1140 if (err != OK) { 1141 mNativeWindowUsageBits = 0; 1142 return err; 1143 } 1144 1145 // Exits here for tunneled video playback codecs -- i.e. skips native window 1146 // buffer allocation step as this is managed by the tunneled OMX omponent 1147 // itself and explicitly sets def.nBufferCountActual to 0. 1148 if (mTunneled) { 1149 ALOGV("Tunneled Playback: skipping native window buffer allocation."); 1150 def.nBufferCountActual = 0; 1151 err = mOMXNode->setParameter( 1152 OMX_IndexParamPortDefinition, &def, sizeof(def)); 1153 1154 *minUndequeuedBuffers = 0; 1155 *bufferCount = 0; 1156 *bufferSize = 0; 1157 return err; 1158 } 1159 1160 *minUndequeuedBuffers = 0; 1161 err = mNativeWindow->query( 1162 mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 1163 (int *)minUndequeuedBuffers); 1164 1165 if (err != 0) { 1166 ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 1167 strerror(-err), -err); 1168 return err; 1169 } 1170 1171 // FIXME: assume that surface is controlled by app (native window 1172 // returns the number for the case when surface is not controlled by app) 1173 // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported 1174 // For now, try to allocate 1 more buffer, but don't fail if unsuccessful 1175 1176 // Use conservative allocation while also trying to reduce starvation 1177 // 1178 // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the 1179 // minimum needed for the consumer to be able to work 1180 // 2. try to allocate two (2) additional buffers to reduce starvation from 1181 // the consumer 1182 // plus an extra buffer to account for incorrect minUndequeuedBufs 1183 for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) { 1184 OMX_U32 newBufferCount = 1185 def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers; 1186 def.nBufferCountActual = newBufferCount; 1187 err = mOMXNode->setParameter( 1188 OMX_IndexParamPortDefinition, &def, sizeof(def)); 1189 1190 if (err == OK) { 1191 *minUndequeuedBuffers += extraBuffers; 1192 break; 1193 } 1194 1195 ALOGW("[%s] setting nBufferCountActual to %u failed: %d", 1196 mComponentName.c_str(), newBufferCount, err); 1197 /* exit condition */ 1198 if (extraBuffers == 0) { 1199 return err; 1200 } 1201 } 1202 1203 err = native_window_set_buffer_count( 1204 mNativeWindow.get(), def.nBufferCountActual); 1205 1206 if (err != 0) { 1207 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 1208 -err); 1209 return err; 1210 } 1211 1212 *bufferCount = def.nBufferCountActual; 1213 *bufferSize = def.nBufferSize; 1214 return err; 1215 } 1216 1217 status_t ACodec::allocateOutputBuffersFromNativeWindow() { 1218 // This method only handles the non-metadata mode (or simulating legacy 1219 // mode with metadata, which is transparent to ACodec). 1220 CHECK(!storingMetadataInDecodedBuffers()); 1221 1222 OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers; 1223 status_t err = configureOutputBuffersFromNativeWindow( 1224 &bufferCount, &bufferSize, &minUndequeuedBuffers, true /* preregister */); 1225 if (err != 0) 1226 return err; 1227 mNumUndequeuedBuffers = minUndequeuedBuffers; 1228 1229 static_cast<Surface*>(mNativeWindow.get()) 1230 ->getIGraphicBufferProducer()->allowAllocation(true); 1231 1232 ALOGV("[%s] Allocating %u buffers from a native window of size %u on " 1233 "output port", 1234 mComponentName.c_str(), bufferCount, bufferSize); 1235 1236 // Dequeue buffers and send them to OMX 1237 for (OMX_U32 i = 0; i < bufferCount; i++) { 1238 ANativeWindowBuffer *buf; 1239 int fenceFd; 1240 err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd); 1241 if (err != 0) { 1242 ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 1243 break; 1244 } 1245 1246 sp<GraphicBuffer> graphicBuffer(GraphicBuffer::from(buf)); 1247 BufferInfo info; 1248 info.mStatus = BufferInfo::OWNED_BY_US; 1249 info.mFenceFd = fenceFd; 1250 info.mIsReadFence = false; 1251 info.mRenderInfo = NULL; 1252 info.mGraphicBuffer = graphicBuffer; 1253 info.mNewGraphicBuffer = false; 1254 1255 // TODO: We shouln't need to create MediaCodecBuffer. In metadata mode 1256 // OMX doesn't use the shared memory buffer, but some code still 1257 // access info.mData. Create an ABuffer as a placeholder. 1258 info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize)); 1259 info.mCodecData = info.mData; 1260 1261 mBuffers[kPortIndexOutput].push(info); 1262 1263 IOMX::buffer_id bufferId; 1264 err = mOMXNode->useBuffer(kPortIndexOutput, graphicBuffer, &bufferId); 1265 if (err != 0) { 1266 ALOGE("registering GraphicBuffer %u with OMX IL component failed: " 1267 "%d", i, err); 1268 break; 1269 } 1270 1271 mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId; 1272 1273 ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)", 1274 mComponentName.c_str(), 1275 bufferId, graphicBuffer.get()); 1276 } 1277 1278 OMX_U32 cancelStart; 1279 OMX_U32 cancelEnd; 1280 1281 if (err != OK) { 1282 // If an error occurred while dequeuing we need to cancel any buffers 1283 // that were dequeued. Also cancel all if we're in legacy metadata mode. 1284 cancelStart = 0; 1285 cancelEnd = mBuffers[kPortIndexOutput].size(); 1286 } else { 1287 // Return the required minimum undequeued buffers to the native window. 1288 cancelStart = bufferCount - minUndequeuedBuffers; 1289 cancelEnd = bufferCount; 1290 } 1291 1292 for (OMX_U32 i = cancelStart; i < cancelEnd; i++) { 1293 BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 1294 if (info->mStatus == BufferInfo::OWNED_BY_US) { 1295 status_t error = cancelBufferToNativeWindow(info); 1296 if (err == 0) { 1297 err = error; 1298 } 1299 } 1300 } 1301 1302 static_cast<Surface*>(mNativeWindow.get()) 1303 ->getIGraphicBufferProducer()->allowAllocation(false); 1304 1305 return err; 1306 } 1307 1308 status_t ACodec::allocateOutputMetadataBuffers() { 1309 CHECK(storingMetadataInDecodedBuffers()); 1310 1311 OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers; 1312 status_t err = configureOutputBuffersFromNativeWindow( 1313 &bufferCount, &bufferSize, &minUndequeuedBuffers, 1314 false /* preregister */); 1315 if (err != OK) 1316 return err; 1317 mNumUndequeuedBuffers = minUndequeuedBuffers; 1318 1319 ALOGV("[%s] Allocating %u meta buffers on output port", 1320 mComponentName.c_str(), bufferCount); 1321 1322 for (OMX_U32 i = 0; i < bufferCount; i++) { 1323 BufferInfo info; 1324 info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 1325 info.mFenceFd = -1; 1326 info.mRenderInfo = NULL; 1327 info.mGraphicBuffer = NULL; 1328 info.mNewGraphicBuffer = false; 1329 info.mDequeuedAt = mDequeueCounter; 1330 1331 info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize)); 1332 1333 // Initialize fence fd to -1 to avoid warning in freeBuffer(). 1334 ((VideoNativeMetadata *)info.mData->base())->nFenceFd = -1; 1335 1336 info.mCodecData = info.mData; 1337 1338 err = mOMXNode->useBuffer(kPortIndexOutput, OMXBuffer::sPreset, &info.mBufferID); 1339 mBuffers[kPortIndexOutput].push(info); 1340 1341 ALOGV("[%s] allocated meta buffer with ID %u", 1342 mComponentName.c_str(), info.mBufferID); 1343 } 1344 1345 mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers; 1346 return err; 1347 } 1348 1349 status_t ACodec::submitOutputMetadataBuffer() { 1350 CHECK(storingMetadataInDecodedBuffers()); 1351 if (mMetadataBuffersToSubmit == 0) 1352 return OK; 1353 1354 BufferInfo *info = dequeueBufferFromNativeWindow(); 1355 if (info == NULL) { 1356 return ERROR_IO; 1357 } 1358 1359 ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p", 1360 mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer->handle); 1361 1362 --mMetadataBuffersToSubmit; 1363 info->checkWriteFence("submitOutputMetadataBuffer"); 1364 return fillBuffer(info); 1365 } 1366 1367 status_t ACodec::waitForFence(int fd, const char *dbg ) { 1368 status_t res = OK; 1369 if (fd >= 0) { 1370 sp<Fence> fence = new Fence(fd); 1371 res = fence->wait(IOMX::kFenceTimeoutMs); 1372 ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg); 1373 } 1374 return res; 1375 } 1376 1377 // static 1378 const char *ACodec::_asString(BufferInfo::Status s) { 1379 switch (s) { 1380 case BufferInfo::OWNED_BY_US: return "OUR"; 1381 case BufferInfo::OWNED_BY_COMPONENT: return "COMPONENT"; 1382 case BufferInfo::OWNED_BY_UPSTREAM: return "UPSTREAM"; 1383 case BufferInfo::OWNED_BY_DOWNSTREAM: return "DOWNSTREAM"; 1384 case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE"; 1385 case BufferInfo::UNRECOGNIZED: return "UNRECOGNIZED"; 1386 default: return "?"; 1387 } 1388 } 1389 1390 void ACodec::dumpBuffers(OMX_U32 portIndex) { 1391 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1392 ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(), 1393 portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size()); 1394 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 1395 const BufferInfo &info = mBuffers[portIndex][i]; 1396 ALOGI(" slot %2zu: #%8u %p/%p %s(%d) dequeued:%u", 1397 i, info.mBufferID, info.mGraphicBuffer.get(), 1398 info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(), 1399 _asString(info.mStatus), info.mStatus, info.mDequeuedAt); 1400 } 1401 } 1402 1403 status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) { 1404 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 1405 1406 ALOGV("[%s] Calling cancelBuffer on buffer %u", 1407 mComponentName.c_str(), info->mBufferID); 1408 1409 info->checkWriteFence("cancelBufferToNativeWindow"); 1410 int err = mNativeWindow->cancelBuffer( 1411 mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd); 1412 info->mFenceFd = -1; 1413 1414 ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window", 1415 mComponentName.c_str(), info->mBufferID); 1416 // change ownership even if cancelBuffer fails 1417 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 1418 1419 return err; 1420 } 1421 1422 void ACodec::updateRenderInfoForDequeuedBuffer( 1423 ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) { 1424 1425 info->mRenderInfo = 1426 mRenderTracker.updateInfoForDequeuedBuffer( 1427 buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]); 1428 1429 // check for any fences already signaled 1430 notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo); 1431 } 1432 1433 void ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { 1434 if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) { 1435 mRenderTracker.dumpRenderQueue(); 1436 } 1437 } 1438 1439 void ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) { 1440 std::list<FrameRenderTracker::Info> done = 1441 mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete); 1442 1443 // unlink untracked frames 1444 for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin(); 1445 it != done.cend(); ++it) { 1446 ssize_t index = it->getIndex(); 1447 if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) { 1448 mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL; 1449 } else if (index >= 0) { 1450 // THIS SHOULD NEVER HAPPEN 1451 ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size()); 1452 } 1453 } 1454 1455 mCallback->onOutputFramesRendered(done); 1456 } 1457 1458 ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() { 1459 ANativeWindowBuffer *buf; 1460 CHECK(mNativeWindow.get() != NULL); 1461 1462 if (mTunneled) { 1463 ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel" 1464 " video playback mode mode!"); 1465 return NULL; 1466 } 1467 1468 if (mFatalError) { 1469 ALOGW("not dequeuing from native window due to fatal error"); 1470 return NULL; 1471 } 1472 1473 int fenceFd = -1; 1474 do { 1475 status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd); 1476 if (err != 0) { 1477 ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err); 1478 return NULL; 1479 } 1480 1481 bool stale = false; 1482 for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) { 1483 i--; 1484 BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 1485 1486 if (info->mGraphicBuffer != NULL && 1487 info->mGraphicBuffer->handle == buf->handle) { 1488 // Since consumers can attach buffers to BufferQueues, it is possible 1489 // that a known yet stale buffer can return from a surface that we 1490 // once used. We can simply ignore this as we have already dequeued 1491 // this buffer properly. NOTE: this does not eliminate all cases, 1492 // e.g. it is possible that we have queued the valid buffer to the 1493 // NW, and a stale copy of the same buffer gets dequeued - which will 1494 // be treated as the valid buffer by ACodec. 1495 if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 1496 ALOGI("dequeued stale buffer %p. discarding", buf); 1497 stale = true; 1498 break; 1499 } 1500 1501 ALOGV("dequeued buffer #%u with age %u, graphicBuffer %p", 1502 (unsigned)(info - &mBuffers[kPortIndexOutput][0]), 1503 mDequeueCounter - info->mDequeuedAt, 1504 info->mGraphicBuffer->handle); 1505 1506 info->mStatus = BufferInfo::OWNED_BY_US; 1507 info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow"); 1508 updateRenderInfoForDequeuedBuffer(buf, fenceFd, info); 1509 return info; 1510 } 1511 } 1512 1513 // It is also possible to receive a previously unregistered buffer 1514 // in non-meta mode. These should be treated as stale buffers. The 1515 // same is possible in meta mode, in which case, it will be treated 1516 // as a normal buffer, which is not desirable. 1517 // TODO: fix this. 1518 if (!stale && !storingMetadataInDecodedBuffers()) { 1519 ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf); 1520 stale = true; 1521 } 1522 if (stale) { 1523 // TODO: detach stale buffer, but there is no API yet to do it. 1524 buf = NULL; 1525 } 1526 } while (buf == NULL); 1527 1528 // get oldest undequeued buffer 1529 BufferInfo *oldest = NULL; 1530 for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) { 1531 i--; 1532 BufferInfo *info = 1533 &mBuffers[kPortIndexOutput].editItemAt(i); 1534 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW && 1535 (oldest == NULL || 1536 // avoid potential issues from counter rolling over 1537 mDequeueCounter - info->mDequeuedAt > 1538 mDequeueCounter - oldest->mDequeuedAt)) { 1539 oldest = info; 1540 } 1541 } 1542 1543 // it is impossible dequeue a buffer when there are no buffers with ANW 1544 CHECK(oldest != NULL); 1545 // it is impossible to dequeue an unknown buffer in non-meta mode, as the 1546 // while loop above does not complete 1547 CHECK(storingMetadataInDecodedBuffers()); 1548 1549 // discard buffer in LRU info and replace with new buffer 1550 oldest->mGraphicBuffer = GraphicBuffer::from(buf); 1551 oldest->mNewGraphicBuffer = true; 1552 oldest->mStatus = BufferInfo::OWNED_BY_US; 1553 oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest"); 1554 mRenderTracker.untrackFrame(oldest->mRenderInfo); 1555 oldest->mRenderInfo = NULL; 1556 1557 ALOGV("replaced oldest buffer #%u with age %u, graphicBuffer %p", 1558 (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]), 1559 mDequeueCounter - oldest->mDequeuedAt, 1560 oldest->mGraphicBuffer->handle); 1561 1562 updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest); 1563 return oldest; 1564 } 1565 1566 status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) { 1567 if (portIndex == kPortIndexInput) { 1568 mBufferChannel->setInputBufferArray({}); 1569 } else { 1570 mBufferChannel->setOutputBufferArray({}); 1571 } 1572 1573 status_t err = OK; 1574 for (size_t i = mBuffers[portIndex].size(); i > 0;) { 1575 i--; 1576 status_t err2 = freeBuffer(portIndex, i); 1577 if (err == OK) { 1578 err = err2; 1579 } 1580 } 1581 1582 if (getTrebleFlag()) { 1583 mAllocator[portIndex].clear(); 1584 } else { 1585 mDealer[portIndex].clear(); 1586 } 1587 return err; 1588 } 1589 1590 status_t ACodec::freeOutputBuffersNotOwnedByComponent() { 1591 status_t err = OK; 1592 for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) { 1593 i--; 1594 BufferInfo *info = 1595 &mBuffers[kPortIndexOutput].editItemAt(i); 1596 1597 // At this time some buffers may still be with the component 1598 // or being drained. 1599 if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT && 1600 info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) { 1601 status_t err2 = freeBuffer(kPortIndexOutput, i); 1602 if (err == OK) { 1603 err = err2; 1604 } 1605 } 1606 } 1607 1608 return err; 1609 } 1610 1611 status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) { 1612 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 1613 status_t err = OK; 1614 1615 // there should not be any fences in the metadata 1616 if (mPortMode[portIndex] == IOMX::kPortModeDynamicANWBuffer && info->mCodecData != NULL 1617 && info->mCodecData->size() >= sizeof(VideoNativeMetadata)) { 1618 int fenceFd = ((VideoNativeMetadata *)info->mCodecData->base())->nFenceFd; 1619 if (fenceFd >= 0) { 1620 ALOGW("unreleased fence (%d) in %s metadata buffer %zu", 1621 fenceFd, portIndex == kPortIndexInput ? "input" : "output", i); 1622 } 1623 } 1624 1625 switch (info->mStatus) { 1626 case BufferInfo::OWNED_BY_US: 1627 if (portIndex == kPortIndexOutput && mNativeWindow != NULL) { 1628 (void)cancelBufferToNativeWindow(info); 1629 } 1630 // fall through 1631 1632 case BufferInfo::OWNED_BY_NATIVE_WINDOW: 1633 err = mOMXNode->freeBuffer(portIndex, info->mBufferID); 1634 break; 1635 1636 default: 1637 ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus); 1638 err = FAILED_TRANSACTION; 1639 break; 1640 } 1641 1642 if (info->mFenceFd >= 0) { 1643 ::close(info->mFenceFd); 1644 } 1645 1646 if (portIndex == kPortIndexOutput) { 1647 mRenderTracker.untrackFrame(info->mRenderInfo, i); 1648 info->mRenderInfo = NULL; 1649 } 1650 1651 // remove buffer even if mOMXNode->freeBuffer fails 1652 mBuffers[portIndex].removeAt(i); 1653 return err; 1654 } 1655 1656 ACodec::BufferInfo *ACodec::findBufferByID( 1657 uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) { 1658 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 1659 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 1660 1661 if (info->mBufferID == bufferID) { 1662 if (index != NULL) { 1663 *index = i; 1664 } 1665 return info; 1666 } 1667 } 1668 1669 ALOGE("Could not find buffer with ID %u", bufferID); 1670 return NULL; 1671 } 1672 1673 status_t ACodec::fillBuffer(BufferInfo *info) { 1674 status_t err; 1675 // Even in dynamic ANW buffer mode, if the graphic buffer is not changing, 1676 // send sPreset instead of the same graphic buffer, so that OMX server 1677 // side doesn't update the meta. In theory it should make no difference, 1678 // however when the same buffer is parcelled again, a new handle could be 1679 // created on server side, and some decoder doesn't recognize the handle 1680 // even if it's the same buffer. 1681 if (!storingMetadataInDecodedBuffers() || !info->mNewGraphicBuffer) { 1682 err = mOMXNode->fillBuffer( 1683 info->mBufferID, OMXBuffer::sPreset, info->mFenceFd); 1684 } else { 1685 err = mOMXNode->fillBuffer( 1686 info->mBufferID, info->mGraphicBuffer, info->mFenceFd); 1687 } 1688 1689 info->mNewGraphicBuffer = false; 1690 info->mFenceFd = -1; 1691 if (err == OK) { 1692 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 1693 } 1694 return err; 1695 } 1696 1697 status_t ACodec::setComponentRole( 1698 bool isEncoder, const char *mime) { 1699 const char *role = GetComponentRole(isEncoder, mime); 1700 if (role == NULL) { 1701 return BAD_VALUE; 1702 } 1703 status_t err = SetComponentRole(mOMXNode, role); 1704 if (err != OK) { 1705 ALOGW("[%s] Failed to set standard component role '%s'.", 1706 mComponentName.c_str(), role); 1707 } 1708 return err; 1709 } 1710 1711 status_t ACodec::configureCodec( 1712 const char *mime, const sp<AMessage> &msg) { 1713 int32_t encoder; 1714 if (!msg->findInt32("encoder", &encoder)) { 1715 encoder = false; 1716 } 1717 1718 sp<AMessage> inputFormat = new AMessage; 1719 sp<AMessage> outputFormat = new AMessage; 1720 mConfigFormat = msg; 1721 1722 mIsEncoder = encoder; 1723 1724 mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer; 1725 mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer; 1726 1727 status_t err = setComponentRole(encoder /* isEncoder */, mime); 1728 1729 if (err != OK) { 1730 return err; 1731 } 1732 1733 int32_t bitRate = 0; 1734 // FLAC encoder doesn't need a bitrate, other encoders do 1735 if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC) 1736 && !msg->findInt32("bitrate", &bitRate)) { 1737 return INVALID_OPERATION; 1738 } 1739 1740 // propagate bitrate to the output so that the muxer has it 1741 if (encoder && msg->findInt32("bitrate", &bitRate)) { 1742 // Technically ISO spec says that 'bitrate' should be 0 for VBR even though it is the 1743 // average bitrate. We've been setting both bitrate and max-bitrate to this same value. 1744 outputFormat->setInt32("bitrate", bitRate); 1745 outputFormat->setInt32("max-bitrate", bitRate); 1746 } 1747 1748 int32_t storeMeta; 1749 if (encoder 1750 && msg->findInt32("android._input-metadata-buffer-type", &storeMeta) 1751 && storeMeta != kMetadataBufferTypeInvalid) { 1752 IOMX::PortMode mode; 1753 if (storeMeta == kMetadataBufferTypeNativeHandleSource) { 1754 mode = IOMX::kPortModeDynamicNativeHandle; 1755 } else if (storeMeta == kMetadataBufferTypeANWBuffer || 1756 storeMeta == kMetadataBufferTypeGrallocSource) { 1757 mode = IOMX::kPortModeDynamicANWBuffer; 1758 } else { 1759 return BAD_VALUE; 1760 } 1761 err = setPortMode(kPortIndexInput, mode); 1762 if (err != OK) { 1763 return err; 1764 } 1765 1766 uint32_t usageBits; 1767 if (mOMXNode->getParameter( 1768 (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, 1769 &usageBits, sizeof(usageBits)) == OK) { 1770 inputFormat->setInt32( 1771 "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN)); 1772 } 1773 } 1774 1775 int32_t prependSPSPPS = 0; 1776 if (encoder 1777 && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS) 1778 && prependSPSPPS != 0) { 1779 OMX_INDEXTYPE index; 1780 err = mOMXNode->getExtensionIndex( 1781 "OMX.google.android.index.prependSPSPPSToIDRFrames", &index); 1782 1783 if (err == OK) { 1784 PrependSPSPPSToIDRFramesParams params; 1785 InitOMXParams(¶ms); 1786 params.bEnable = OMX_TRUE; 1787 1788 err = mOMXNode->setParameter(index, ¶ms, sizeof(params)); 1789 } 1790 1791 if (err != OK) { 1792 ALOGE("Encoder could not be configured to emit SPS/PPS before " 1793 "IDR frames. (err %d)", err); 1794 1795 return err; 1796 } 1797 } 1798 1799 // Only enable metadata mode on encoder output if encoder can prepend 1800 // sps/pps to idr frames, since in metadata mode the bitstream is in an 1801 // opaque handle, to which we don't have access. 1802 int32_t video = !strncasecmp(mime, "video/", 6); 1803 mIsVideo = video; 1804 if (encoder && video) { 1805 OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS 1806 && msg->findInt32("android._store-metadata-in-buffers-output", &storeMeta) 1807 && storeMeta != 0); 1808 if (mFlags & kFlagIsSecure) { 1809 enable = OMX_TRUE; 1810 } 1811 1812 err = setPortMode(kPortIndexOutput, enable ? 1813 IOMX::kPortModePresetSecureBuffer : IOMX::kPortModePresetByteBuffer); 1814 if (err != OK) { 1815 return err; 1816 } 1817 1818 if (!msg->findInt64( 1819 "repeat-previous-frame-after", 1820 &mRepeatFrameDelayUs)) { 1821 mRepeatFrameDelayUs = -1ll; 1822 } 1823 1824 // only allow 32-bit value, since we pass it as U32 to OMX. 1825 if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) { 1826 mMaxPtsGapUs = -1ll; 1827 } else if (mMaxPtsGapUs > INT32_MAX || mMaxPtsGapUs < 0) { 1828 ALOGW("Unsupported value for max pts gap %lld", (long long) mMaxPtsGapUs); 1829 mMaxPtsGapUs = -1ll; 1830 } 1831 1832 if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) { 1833 mMaxFps = -1; 1834 } 1835 1836 if (!msg->findDouble("time-lapse-fps", &mCaptureFps)) { 1837 mCaptureFps = -1.0; 1838 } 1839 1840 if (!msg->findInt32( 1841 "create-input-buffers-suspended", 1842 (int32_t*)&mCreateInputBuffersSuspended)) { 1843 mCreateInputBuffersSuspended = false; 1844 } 1845 } 1846 1847 // NOTE: we only use native window for video decoders 1848 sp<RefBase> obj; 1849 bool haveNativeWindow = msg->findObject("native-window", &obj) 1850 && obj != NULL && video && !encoder; 1851 mUsingNativeWindow = haveNativeWindow; 1852 if (video && !encoder) { 1853 inputFormat->setInt32("adaptive-playback", false); 1854 1855 int32_t usageProtected; 1856 if (msg->findInt32("protected", &usageProtected) && usageProtected) { 1857 if (!haveNativeWindow) { 1858 ALOGE("protected output buffers must be sent to an ANativeWindow"); 1859 return PERMISSION_DENIED; 1860 } 1861 mFlags |= kFlagIsGrallocUsageProtected; 1862 mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 1863 } 1864 1865 if (mFlags & kFlagIsSecure) { 1866 // use native_handles for secure input buffers 1867 err = setPortMode(kPortIndexInput, IOMX::kPortModePresetSecureBuffer); 1868 1869 if (err != OK) { 1870 ALOGI("falling back to non-native_handles"); 1871 setPortMode(kPortIndexInput, IOMX::kPortModePresetByteBuffer); 1872 err = OK; // ignore error for now 1873 } 1874 } 1875 } 1876 if (haveNativeWindow) { 1877 sp<ANativeWindow> nativeWindow = 1878 static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get())); 1879 1880 // START of temporary support for automatic FRC - THIS WILL BE REMOVED 1881 int32_t autoFrc; 1882 if (msg->findInt32("auto-frc", &autoFrc)) { 1883 bool enabled = autoFrc; 1884 OMX_CONFIG_BOOLEANTYPE config; 1885 InitOMXParams(&config); 1886 config.bEnabled = (OMX_BOOL)enabled; 1887 status_t temp = mOMXNode->setConfig( 1888 (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion, 1889 &config, sizeof(config)); 1890 if (temp == OK) { 1891 outputFormat->setInt32("auto-frc", enabled); 1892 } else if (enabled) { 1893 ALOGI("codec does not support requested auto-frc (err %d)", temp); 1894 } 1895 } 1896 // END of temporary support for automatic FRC 1897 1898 int32_t tunneled; 1899 if (msg->findInt32("feature-tunneled-playback", &tunneled) && 1900 tunneled != 0) { 1901 ALOGI("Configuring TUNNELED video playback."); 1902 mTunneled = true; 1903 1904 int32_t audioHwSync = 0; 1905 if (!msg->findInt32("audio-hw-sync", &audioHwSync)) { 1906 ALOGW("No Audio HW Sync provided for video tunnel"); 1907 } 1908 err = configureTunneledVideoPlayback(audioHwSync, nativeWindow); 1909 if (err != OK) { 1910 ALOGE("configureTunneledVideoPlayback(%d,%p) failed!", 1911 audioHwSync, nativeWindow.get()); 1912 return err; 1913 } 1914 1915 int32_t maxWidth = 0, maxHeight = 0; 1916 if (msg->findInt32("max-width", &maxWidth) && 1917 msg->findInt32("max-height", &maxHeight)) { 1918 1919 err = mOMXNode->prepareForAdaptivePlayback( 1920 kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight); 1921 if (err != OK) { 1922 ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d", 1923 mComponentName.c_str(), err); 1924 // allow failure 1925 err = OK; 1926 } else { 1927 inputFormat->setInt32("max-width", maxWidth); 1928 inputFormat->setInt32("max-height", maxHeight); 1929 inputFormat->setInt32("adaptive-playback", true); 1930 } 1931 } 1932 } else { 1933 ALOGV("Configuring CPU controlled video playback."); 1934 mTunneled = false; 1935 1936 // Explicity reset the sideband handle of the window for 1937 // non-tunneled video in case the window was previously used 1938 // for a tunneled video playback. 1939 err = native_window_set_sideband_stream(nativeWindow.get(), NULL); 1940 if (err != OK) { 1941 ALOGE("set_sideband_stream(NULL) failed! (err %d).", err); 1942 return err; 1943 } 1944 1945 err = setPortMode(kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer); 1946 if (err != OK) { 1947 // if adaptive playback has been requested, try JB fallback 1948 // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS 1949 // LARGE MEMORY REQUIREMENT 1950 1951 // we will not do adaptive playback on software accessed 1952 // surfaces as they never had to respond to changes in the 1953 // crop window, and we don't trust that they will be able to. 1954 int usageBits = 0; 1955 bool canDoAdaptivePlayback; 1956 1957 if (nativeWindow->query( 1958 nativeWindow.get(), 1959 NATIVE_WINDOW_CONSUMER_USAGE_BITS, 1960 &usageBits) != OK) { 1961 canDoAdaptivePlayback = false; 1962 } else { 1963 canDoAdaptivePlayback = 1964 (usageBits & 1965 (GRALLOC_USAGE_SW_READ_MASK | 1966 GRALLOC_USAGE_SW_WRITE_MASK)) == 0; 1967 } 1968 1969 int32_t maxWidth = 0, maxHeight = 0; 1970 if (canDoAdaptivePlayback && 1971 msg->findInt32("max-width", &maxWidth) && 1972 msg->findInt32("max-height", &maxHeight)) { 1973 ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)", 1974 mComponentName.c_str(), maxWidth, maxHeight); 1975 1976 err = mOMXNode->prepareForAdaptivePlayback( 1977 kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight); 1978 ALOGW_IF(err != OK, 1979 "[%s] prepareForAdaptivePlayback failed w/ err %d", 1980 mComponentName.c_str(), err); 1981 1982 if (err == OK) { 1983 inputFormat->setInt32("max-width", maxWidth); 1984 inputFormat->setInt32("max-height", maxHeight); 1985 inputFormat->setInt32("adaptive-playback", true); 1986 } 1987 } 1988 // allow failure 1989 err = OK; 1990 } else { 1991 ALOGV("[%s] setPortMode on output to %s succeeded", 1992 mComponentName.c_str(), asString(IOMX::kPortModeDynamicANWBuffer)); 1993 CHECK(storingMetadataInDecodedBuffers()); 1994 inputFormat->setInt32("adaptive-playback", true); 1995 } 1996 1997 int32_t push; 1998 if (msg->findInt32("push-blank-buffers-on-shutdown", &push) 1999 && push != 0) { 2000 mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 2001 } 2002 } 2003 2004 int32_t rotationDegrees; 2005 if (msg->findInt32("rotation-degrees", &rotationDegrees)) { 2006 mRotationDegrees = rotationDegrees; 2007 } else { 2008 mRotationDegrees = 0; 2009 } 2010 } 2011 2012 AudioEncoding pcmEncoding = kAudioEncodingPcm16bit; 2013 (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding); 2014 // invalid encodings will default to PCM-16bit in setupRawAudioFormat. 2015 2016 if (video) { 2017 // determine need for software renderer 2018 bool usingSwRenderer = false; 2019 if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) { 2020 usingSwRenderer = true; 2021 haveNativeWindow = false; 2022 (void)setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer); 2023 } else if (haveNativeWindow && !storingMetadataInDecodedBuffers()) { 2024 err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetANWBuffer); 2025 if (err != OK) { 2026 return err; 2027 } 2028 } 2029 2030 if (encoder) { 2031 err = setupVideoEncoder(mime, msg, outputFormat, inputFormat); 2032 } else { 2033 err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat); 2034 } 2035 2036 if (err != OK) { 2037 return err; 2038 } 2039 2040 if (haveNativeWindow) { 2041 mNativeWindow = static_cast<Surface *>(obj.get()); 2042 2043 // fallback for devices that do not handle flex-YUV for native buffers 2044 int32_t requestedColorFormat = OMX_COLOR_FormatUnused; 2045 if (msg->findInt32("color-format", &requestedColorFormat) && 2046 requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) { 2047 status_t err = getPortFormat(kPortIndexOutput, outputFormat); 2048 if (err != OK) { 2049 return err; 2050 } 2051 int32_t colorFormat = OMX_COLOR_FormatUnused; 2052 OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused; 2053 if (!outputFormat->findInt32("color-format", &colorFormat)) { 2054 ALOGE("ouptut port did not have a color format (wrong domain?)"); 2055 return BAD_VALUE; 2056 } 2057 ALOGD("[%s] Requested output format %#x and got %#x.", 2058 mComponentName.c_str(), requestedColorFormat, colorFormat); 2059 if (!IsFlexibleColorFormat( 2060 mOMXNode, colorFormat, haveNativeWindow, &flexibleEquivalent) 2061 || flexibleEquivalent != (OMX_U32)requestedColorFormat) { 2062 // device did not handle flex-YUV request for native window, fall back 2063 // to SW renderer 2064 ALOGI("[%s] Falling back to software renderer", mComponentName.c_str()); 2065 mNativeWindow.clear(); 2066 mNativeWindowUsageBits = 0; 2067 haveNativeWindow = false; 2068 usingSwRenderer = true; 2069 // TODO: implement adaptive-playback support for bytebuffer mode. 2070 // This is done by SW codecs, but most HW codecs don't support it. 2071 err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer); 2072 inputFormat->setInt32("adaptive-playback", false); 2073 if (mFlags & kFlagIsGrallocUsageProtected) { 2074 // fallback is not supported for protected playback 2075 err = PERMISSION_DENIED; 2076 } else if (err == OK) { 2077 err = setupVideoDecoder( 2078 mime, msg, haveNativeWindow, usingSwRenderer, outputFormat); 2079 } 2080 } 2081 } 2082 } 2083 2084 if (usingSwRenderer) { 2085 outputFormat->setInt32("using-sw-renderer", 1); 2086 } 2087 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { 2088 int32_t numChannels, sampleRate; 2089 if (!msg->findInt32("channel-count", &numChannels) 2090 || !msg->findInt32("sample-rate", &sampleRate)) { 2091 // Since we did not always check for these, leave them optional 2092 // and have the decoder figure it all out. 2093 err = OK; 2094 } else { 2095 err = setupRawAudioFormat( 2096 encoder ? kPortIndexInput : kPortIndexOutput, 2097 sampleRate, 2098 numChannels); 2099 } 2100 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 2101 int32_t numChannels, sampleRate; 2102 if (!msg->findInt32("channel-count", &numChannels) 2103 || !msg->findInt32("sample-rate", &sampleRate)) { 2104 err = INVALID_OPERATION; 2105 } else { 2106 int32_t isADTS, aacProfile; 2107 int32_t sbrMode; 2108 int32_t maxOutputChannelCount; 2109 int32_t pcmLimiterEnable; 2110 drcParams_t drc; 2111 if (!msg->findInt32("is-adts", &isADTS)) { 2112 isADTS = 0; 2113 } 2114 if (!msg->findInt32("aac-profile", &aacProfile)) { 2115 aacProfile = OMX_AUDIO_AACObjectNull; 2116 } 2117 if (!msg->findInt32("aac-sbr-mode", &sbrMode)) { 2118 sbrMode = -1; 2119 } 2120 2121 if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) { 2122 maxOutputChannelCount = -1; 2123 } 2124 if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) { 2125 // value is unknown 2126 pcmLimiterEnable = -1; 2127 } 2128 if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) { 2129 // value is unknown 2130 drc.encodedTargetLevel = -1; 2131 } 2132 if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) { 2133 // value is unknown 2134 drc.drcCut = -1; 2135 } 2136 if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) { 2137 // value is unknown 2138 drc.drcBoost = -1; 2139 } 2140 if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) { 2141 // value is unknown 2142 drc.heavyCompression = -1; 2143 } 2144 if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) { 2145 // value is unknown 2146 drc.targetRefLevel = -1; 2147 } 2148 2149 err = setupAACCodec( 2150 encoder, numChannels, sampleRate, bitRate, aacProfile, 2151 isADTS != 0, sbrMode, maxOutputChannelCount, drc, 2152 pcmLimiterEnable); 2153 } 2154 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 2155 err = setupAMRCodec(encoder, false /* isWAMR */, bitRate); 2156 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 2157 err = setupAMRCodec(encoder, true /* isWAMR */, bitRate); 2158 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW) 2159 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) { 2160 // These are PCM-like formats with a fixed sample rate but 2161 // a variable number of channels. 2162 2163 int32_t numChannels; 2164 if (!msg->findInt32("channel-count", &numChannels)) { 2165 err = INVALID_OPERATION; 2166 } else { 2167 int32_t sampleRate; 2168 if (!msg->findInt32("sample-rate", &sampleRate)) { 2169 sampleRate = 8000; 2170 } 2171 err = setupG711Codec(encoder, sampleRate, numChannels); 2172 } 2173 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) { 2174 int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1; 2175 if (encoder && 2176 (!msg->findInt32("channel-count", &numChannels) 2177 || !msg->findInt32("sample-rate", &sampleRate))) { 2178 ALOGE("missing channel count or sample rate for FLAC encoder"); 2179 err = INVALID_OPERATION; 2180 } else { 2181 if (encoder) { 2182 if (!msg->findInt32( 2183 "complexity", &compressionLevel) && 2184 !msg->findInt32( 2185 "flac-compression-level", &compressionLevel)) { 2186 compressionLevel = 5; // default FLAC compression level 2187 } else if (compressionLevel < 0) { 2188 ALOGW("compression level %d outside [0..8] range, " 2189 "using 0", 2190 compressionLevel); 2191 compressionLevel = 0; 2192 } else if (compressionLevel > 8) { 2193 ALOGW("compression level %d outside [0..8] range, " 2194 "using 8", 2195 compressionLevel); 2196 compressionLevel = 8; 2197 } 2198 } 2199 err = setupFlacCodec( 2200 encoder, numChannels, sampleRate, compressionLevel); 2201 } 2202 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) { 2203 int32_t numChannels, sampleRate; 2204 if (encoder 2205 || !msg->findInt32("channel-count", &numChannels) 2206 || !msg->findInt32("sample-rate", &sampleRate)) { 2207 err = INVALID_OPERATION; 2208 } else { 2209 err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding); 2210 } 2211 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) { 2212 int32_t numChannels; 2213 int32_t sampleRate; 2214 if (!msg->findInt32("channel-count", &numChannels) 2215 || !msg->findInt32("sample-rate", &sampleRate)) { 2216 err = INVALID_OPERATION; 2217 } else { 2218 err = setupAC3Codec(encoder, numChannels, sampleRate); 2219 } 2220 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) { 2221 int32_t numChannels; 2222 int32_t sampleRate; 2223 if (!msg->findInt32("channel-count", &numChannels) 2224 || !msg->findInt32("sample-rate", &sampleRate)) { 2225 err = INVALID_OPERATION; 2226 } else { 2227 err = setupEAC3Codec(encoder, numChannels, sampleRate); 2228 } 2229 } 2230 2231 if (err != OK) { 2232 return err; 2233 } 2234 2235 if (!msg->findInt32("encoder-delay", &mEncoderDelay)) { 2236 mEncoderDelay = 0; 2237 } 2238 2239 if (!msg->findInt32("encoder-padding", &mEncoderPadding)) { 2240 mEncoderPadding = 0; 2241 } 2242 2243 if (msg->findInt32("channel-mask", &mChannelMask)) { 2244 mChannelMaskPresent = true; 2245 } else { 2246 mChannelMaskPresent = false; 2247 } 2248 2249 int32_t maxInputSize; 2250 if (msg->findInt32("max-input-size", &maxInputSize)) { 2251 err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize); 2252 err = OK; // ignore error 2253 } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) { 2254 err = setMinBufferSize(kPortIndexInput, 8192); // XXX 2255 err = OK; // ignore error 2256 } 2257 2258 int32_t priority; 2259 if (msg->findInt32("priority", &priority)) { 2260 err = setPriority(priority); 2261 err = OK; // ignore error 2262 } 2263 2264 int32_t rateInt = -1; 2265 float rateFloat = -1; 2266 if (!msg->findFloat("operating-rate", &rateFloat)) { 2267 msg->findInt32("operating-rate", &rateInt); 2268 rateFloat = (float)rateInt; // 16MHz (FLINTMAX) is OK for upper bound. 2269 } 2270 if (rateFloat > 0) { 2271 err = setOperatingRate(rateFloat, video); 2272 err = OK; // ignore errors 2273 } 2274 2275 if (err == OK) { 2276 err = setVendorParameters(msg); 2277 if (err != OK) { 2278 return err; 2279 } 2280 } 2281 2282 // NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame. 2283 mBaseOutputFormat = outputFormat; 2284 mLastOutputFormat.clear(); 2285 2286 err = getPortFormat(kPortIndexInput, inputFormat); 2287 if (err == OK) { 2288 err = getPortFormat(kPortIndexOutput, outputFormat); 2289 if (err == OK) { 2290 mInputFormat = inputFormat; 2291 mOutputFormat = outputFormat; 2292 } 2293 } 2294 2295 // create data converters if needed 2296 if (!video && err == OK) { 2297 AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit; 2298 if (encoder) { 2299 (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding); 2300 mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding); 2301 if (mConverter[kPortIndexInput] != NULL) { 2302 mInputFormat->setInt32("pcm-encoding", pcmEncoding); 2303 } 2304 } else { 2305 (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding); 2306 mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding); 2307 if (mConverter[kPortIndexOutput] != NULL) { 2308 mOutputFormat->setInt32("pcm-encoding", pcmEncoding); 2309 } 2310 } 2311 } 2312 2313 return err; 2314 } 2315 2316 status_t ACodec::setLatency(uint32_t latency) { 2317 OMX_PARAM_U32TYPE config; 2318 InitOMXParams(&config); 2319 config.nPortIndex = kPortIndexInput; 2320 config.nU32 = (OMX_U32)latency; 2321 status_t err = mOMXNode->setConfig( 2322 (OMX_INDEXTYPE)OMX_IndexConfigLatency, 2323 &config, sizeof(config)); 2324 return err; 2325 } 2326 2327 status_t ACodec::getLatency(uint32_t *latency) { 2328 OMX_PARAM_U32TYPE config; 2329 InitOMXParams(&config); 2330 config.nPortIndex = kPortIndexInput; 2331 status_t err = mOMXNode->getConfig( 2332 (OMX_INDEXTYPE)OMX_IndexConfigLatency, 2333 &config, sizeof(config)); 2334 if (err == OK) { 2335 *latency = config.nU32; 2336 } 2337 return err; 2338 } 2339 2340 status_t ACodec::setPriority(int32_t priority) { 2341 if (priority < 0) { 2342 return BAD_VALUE; 2343 } 2344 OMX_PARAM_U32TYPE config; 2345 InitOMXParams(&config); 2346 config.nU32 = (OMX_U32)priority; 2347 status_t temp = mOMXNode->setConfig( 2348 (OMX_INDEXTYPE)OMX_IndexConfigPriority, 2349 &config, sizeof(config)); 2350 if (temp != OK) { 2351 ALOGI("codec does not support config priority (err %d)", temp); 2352 } 2353 return OK; 2354 } 2355 2356 status_t ACodec::setOperatingRate(float rateFloat, bool isVideo) { 2357 if (rateFloat < 0) { 2358 return BAD_VALUE; 2359 } 2360 OMX_U32 rate; 2361 if (isVideo) { 2362 if (rateFloat > 65535) { 2363 return BAD_VALUE; 2364 } 2365 rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f); 2366 } else { 2367 if (rateFloat > UINT_MAX) { 2368 return BAD_VALUE; 2369 } 2370 rate = (OMX_U32)(rateFloat); 2371 } 2372 OMX_PARAM_U32TYPE config; 2373 InitOMXParams(&config); 2374 config.nU32 = rate; 2375 status_t err = mOMXNode->setConfig( 2376 (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate, 2377 &config, sizeof(config)); 2378 if (err != OK) { 2379 ALOGI("codec does not support config operating rate (err %d)", err); 2380 } 2381 return OK; 2382 } 2383 2384 status_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) { 2385 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params; 2386 InitOMXParams(¶ms); 2387 params.nPortIndex = kPortIndexOutput; 2388 status_t err = mOMXNode->getConfig( 2389 (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, ¶ms, sizeof(params)); 2390 if (err == OK) { 2391 *intraRefreshPeriod = params.nRefreshPeriod; 2392 return OK; 2393 } 2394 2395 // Fallback to query through standard OMX index. 2396 OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams; 2397 InitOMXParams(&refreshParams); 2398 refreshParams.nPortIndex = kPortIndexOutput; 2399 refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic; 2400 err = mOMXNode->getParameter( 2401 OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams)); 2402 if (err != OK || refreshParams.nCirMBs == 0) { 2403 *intraRefreshPeriod = 0; 2404 return OK; 2405 } 2406 2407 // Calculate period based on width and height 2408 uint32_t width, height; 2409 OMX_PARAM_PORTDEFINITIONTYPE def; 2410 InitOMXParams(&def); 2411 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2412 def.nPortIndex = kPortIndexOutput; 2413 err = mOMXNode->getParameter( 2414 OMX_IndexParamPortDefinition, &def, sizeof(def)); 2415 if (err != OK) { 2416 *intraRefreshPeriod = 0; 2417 return err; 2418 } 2419 width = video_def->nFrameWidth; 2420 height = video_def->nFrameHeight; 2421 // Use H.264/AVC MacroBlock size 16x16 2422 *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs); 2423 2424 return OK; 2425 } 2426 2427 status_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) { 2428 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params; 2429 InitOMXParams(¶ms); 2430 params.nPortIndex = kPortIndexOutput; 2431 params.nRefreshPeriod = intraRefreshPeriod; 2432 status_t err = mOMXNode->setConfig( 2433 (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, ¶ms, sizeof(params)); 2434 if (err == OK) { 2435 return OK; 2436 } 2437 2438 // Only in configure state, a component could invoke setParameter. 2439 if (!inConfigure) { 2440 return INVALID_OPERATION; 2441 } else { 2442 ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str()); 2443 } 2444 2445 OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams; 2446 InitOMXParams(&refreshParams); 2447 refreshParams.nPortIndex = kPortIndexOutput; 2448 refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic; 2449 2450 if (intraRefreshPeriod == 0) { 2451 // 0 means disable intra refresh. 2452 refreshParams.nCirMBs = 0; 2453 } else { 2454 // Calculate macroblocks that need to be intra coded base on width and height 2455 uint32_t width, height; 2456 OMX_PARAM_PORTDEFINITIONTYPE def; 2457 InitOMXParams(&def); 2458 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2459 def.nPortIndex = kPortIndexOutput; 2460 err = mOMXNode->getParameter( 2461 OMX_IndexParamPortDefinition, &def, sizeof(def)); 2462 if (err != OK) { 2463 return err; 2464 } 2465 width = video_def->nFrameWidth; 2466 height = video_def->nFrameHeight; 2467 // Use H.264/AVC MacroBlock size 16x16 2468 refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod); 2469 } 2470 2471 err = mOMXNode->setParameter( 2472 OMX_IndexParamVideoIntraRefresh, 2473 &refreshParams, sizeof(refreshParams)); 2474 if (err != OK) { 2475 return err; 2476 } 2477 2478 return OK; 2479 } 2480 2481 status_t ACodec::configureTemporalLayers( 2482 const sp<AMessage> &msg, bool inConfigure, sp<AMessage> &outputFormat) { 2483 if (!mIsVideo || !mIsEncoder) { 2484 return INVALID_OPERATION; 2485 } 2486 2487 AString tsSchema; 2488 if (!msg->findString("ts-schema", &tsSchema)) { 2489 return OK; 2490 } 2491 2492 unsigned int numLayers = 0; 2493 unsigned int numBLayers = 0; 2494 int tags; 2495 char dummy; 2496 OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE pattern = 2497 OMX_VIDEO_AndroidTemporalLayeringPatternNone; 2498 if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1 2499 && numLayers > 0) { 2500 pattern = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC; 2501 } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c", 2502 &numLayers, &dummy, &numBLayers, &dummy)) 2503 && (tags == 1 || (tags == 3 && dummy == '+')) 2504 && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) { 2505 numLayers += numBLayers; 2506 pattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid; 2507 } else { 2508 ALOGI("Ignoring unsupported ts-schema [%s]", tsSchema.c_str()); 2509 return BAD_VALUE; 2510 } 2511 2512 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layerParams; 2513 InitOMXParams(&layerParams); 2514 layerParams.nPortIndex = kPortIndexOutput; 2515 2516 status_t err = mOMXNode->getParameter( 2517 (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering, 2518 &layerParams, sizeof(layerParams)); 2519 2520 if (err != OK) { 2521 return err; 2522 } else if (!(layerParams.eSupportedPatterns & pattern)) { 2523 return BAD_VALUE; 2524 } 2525 2526 numLayers = min(numLayers, layerParams.nLayerCountMax); 2527 numBLayers = min(numBLayers, layerParams.nBLayerCountMax); 2528 2529 if (!inConfigure) { 2530 OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE layerConfig; 2531 InitOMXParams(&layerConfig); 2532 layerConfig.nPortIndex = kPortIndexOutput; 2533 layerConfig.ePattern = pattern; 2534 layerConfig.nPLayerCountActual = numLayers - numBLayers; 2535 layerConfig.nBLayerCountActual = numBLayers; 2536 layerConfig.bBitrateRatiosSpecified = OMX_FALSE; 2537 2538 err = mOMXNode->setConfig( 2539 (OMX_INDEXTYPE)OMX_IndexConfigAndroidVideoTemporalLayering, 2540 &layerConfig, sizeof(layerConfig)); 2541 } else { 2542 layerParams.ePattern = pattern; 2543 layerParams.nPLayerCountActual = numLayers - numBLayers; 2544 layerParams.nBLayerCountActual = numBLayers; 2545 layerParams.bBitrateRatiosSpecified = OMX_FALSE; 2546 2547 err = mOMXNode->setParameter( 2548 (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering, 2549 &layerParams, sizeof(layerParams)); 2550 } 2551 2552 AString configSchema; 2553 if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid) { 2554 configSchema = AStringPrintf("android.generic.%u+%u", numLayers - numBLayers, numBLayers); 2555 } else if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) { 2556 configSchema = AStringPrintf("webrtc.vp8.%u", numLayers); 2557 } 2558 2559 if (err != OK) { 2560 ALOGW("Failed to set temporal layers to %s (requested %s)", 2561 configSchema.c_str(), tsSchema.c_str()); 2562 return err; 2563 } 2564 2565 err = mOMXNode->getParameter( 2566 (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering, 2567 &layerParams, sizeof(layerParams)); 2568 2569 if (err == OK) { 2570 ALOGD("Temporal layers requested:%s configured:%s got:%s(%u: P=%u, B=%u)", 2571 tsSchema.c_str(), configSchema.c_str(), 2572 asString(layerParams.ePattern), layerParams.ePattern, 2573 layerParams.nPLayerCountActual, layerParams.nBLayerCountActual); 2574 2575 if (outputFormat.get() == mOutputFormat.get()) { 2576 mOutputFormat = mOutputFormat->dup(); // trigger an output format change event 2577 } 2578 // assume we got what we configured 2579 outputFormat->setString("ts-schema", configSchema); 2580 } 2581 return err; 2582 } 2583 2584 status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) { 2585 OMX_PARAM_PORTDEFINITIONTYPE def; 2586 InitOMXParams(&def); 2587 def.nPortIndex = portIndex; 2588 2589 status_t err = mOMXNode->getParameter( 2590 OMX_IndexParamPortDefinition, &def, sizeof(def)); 2591 2592 if (err != OK) { 2593 return err; 2594 } 2595 2596 if (def.nBufferSize >= size) { 2597 return OK; 2598 } 2599 2600 def.nBufferSize = size; 2601 2602 err = mOMXNode->setParameter( 2603 OMX_IndexParamPortDefinition, &def, sizeof(def)); 2604 2605 if (err != OK) { 2606 return err; 2607 } 2608 2609 err = mOMXNode->getParameter( 2610 OMX_IndexParamPortDefinition, &def, sizeof(def)); 2611 2612 if (err != OK) { 2613 return err; 2614 } 2615 2616 if (def.nBufferSize < size) { 2617 ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize); 2618 return FAILED_TRANSACTION; 2619 } 2620 2621 return OK; 2622 } 2623 2624 status_t ACodec::selectAudioPortFormat( 2625 OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) { 2626 OMX_AUDIO_PARAM_PORTFORMATTYPE format; 2627 InitOMXParams(&format); 2628 2629 format.nPortIndex = portIndex; 2630 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 2631 format.nIndex = index; 2632 status_t err = mOMXNode->getParameter( 2633 OMX_IndexParamAudioPortFormat, &format, sizeof(format)); 2634 2635 if (err != OK) { 2636 return err; 2637 } 2638 2639 if (format.eEncoding == desiredFormat) { 2640 break; 2641 } 2642 2643 if (index == kMaxIndicesToCheck) { 2644 ALOGW("[%s] stopping checking formats after %u: %s(%x)", 2645 mComponentName.c_str(), index, 2646 asString(format.eEncoding), format.eEncoding); 2647 return ERROR_UNSUPPORTED; 2648 } 2649 } 2650 2651 return mOMXNode->setParameter( 2652 OMX_IndexParamAudioPortFormat, &format, sizeof(format)); 2653 } 2654 2655 status_t ACodec::setupAACCodec( 2656 bool encoder, int32_t numChannels, int32_t sampleRate, 2657 int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode, 2658 int32_t maxOutputChannelCount, const drcParams_t& drc, 2659 int32_t pcmLimiterEnable) { 2660 if (encoder && isADTS) { 2661 return -EINVAL; 2662 } 2663 2664 status_t err = setupRawAudioFormat( 2665 encoder ? kPortIndexInput : kPortIndexOutput, 2666 sampleRate, 2667 numChannels); 2668 2669 if (err != OK) { 2670 return err; 2671 } 2672 2673 if (encoder) { 2674 err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC); 2675 2676 if (err != OK) { 2677 return err; 2678 } 2679 2680 OMX_PARAM_PORTDEFINITIONTYPE def; 2681 InitOMXParams(&def); 2682 def.nPortIndex = kPortIndexOutput; 2683 2684 err = mOMXNode->getParameter( 2685 OMX_IndexParamPortDefinition, &def, sizeof(def)); 2686 2687 if (err != OK) { 2688 return err; 2689 } 2690 2691 def.format.audio.bFlagErrorConcealment = OMX_TRUE; 2692 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 2693 2694 err = mOMXNode->setParameter( 2695 OMX_IndexParamPortDefinition, &def, sizeof(def)); 2696 2697 if (err != OK) { 2698 return err; 2699 } 2700 2701 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 2702 InitOMXParams(&profile); 2703 profile.nPortIndex = kPortIndexOutput; 2704 2705 err = mOMXNode->getParameter( 2706 OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2707 2708 if (err != OK) { 2709 return err; 2710 } 2711 2712 profile.nChannels = numChannels; 2713 2714 profile.eChannelMode = 2715 (numChannels == 1) 2716 ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo; 2717 2718 profile.nSampleRate = sampleRate; 2719 profile.nBitRate = bitRate; 2720 profile.nAudioBandWidth = 0; 2721 profile.nFrameLength = 0; 2722 profile.nAACtools = OMX_AUDIO_AACToolAll; 2723 profile.nAACERtools = OMX_AUDIO_AACERNone; 2724 profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile; 2725 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; 2726 switch (sbrMode) { 2727 case 0: 2728 // disable sbr 2729 profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR; 2730 profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR; 2731 break; 2732 case 1: 2733 // enable single-rate sbr 2734 profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR; 2735 profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR; 2736 break; 2737 case 2: 2738 // enable dual-rate sbr 2739 profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR; 2740 profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR; 2741 break; 2742 case -1: 2743 // enable both modes -> the codec will decide which mode should be used 2744 profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR; 2745 profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR; 2746 break; 2747 default: 2748 // unsupported sbr mode 2749 return BAD_VALUE; 2750 } 2751 2752 2753 err = mOMXNode->setParameter( 2754 OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2755 2756 if (err != OK) { 2757 return err; 2758 } 2759 2760 return err; 2761 } 2762 2763 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 2764 InitOMXParams(&profile); 2765 profile.nPortIndex = kPortIndexInput; 2766 2767 err = mOMXNode->getParameter( 2768 OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2769 2770 if (err != OK) { 2771 return err; 2772 } 2773 2774 profile.nChannels = numChannels; 2775 profile.nSampleRate = sampleRate; 2776 2777 profile.eAACStreamFormat = 2778 isADTS 2779 ? OMX_AUDIO_AACStreamFormatMP4ADTS 2780 : OMX_AUDIO_AACStreamFormatMP4FF; 2781 2782 OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation; 2783 InitOMXParams(&presentation); 2784 presentation.nMaxOutputChannels = maxOutputChannelCount; 2785 presentation.nDrcCut = drc.drcCut; 2786 presentation.nDrcBoost = drc.drcBoost; 2787 presentation.nHeavyCompression = drc.heavyCompression; 2788 presentation.nTargetReferenceLevel = drc.targetRefLevel; 2789 presentation.nEncodedTargetLevel = drc.encodedTargetLevel; 2790 presentation.nPCMLimiterEnable = pcmLimiterEnable; 2791 2792 status_t res = mOMXNode->setParameter( 2793 OMX_IndexParamAudioAac, &profile, sizeof(profile)); 2794 if (res == OK) { 2795 // optional parameters, will not cause configuration failure 2796 mOMXNode->setParameter( 2797 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation, 2798 &presentation, sizeof(presentation)); 2799 } else { 2800 ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res); 2801 } 2802 mSampleRate = sampleRate; 2803 return res; 2804 } 2805 2806 status_t ACodec::setupAC3Codec( 2807 bool encoder, int32_t numChannels, int32_t sampleRate) { 2808 status_t err = setupRawAudioFormat( 2809 encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels); 2810 2811 if (err != OK) { 2812 return err; 2813 } 2814 2815 if (encoder) { 2816 ALOGW("AC3 encoding is not supported."); 2817 return INVALID_OPERATION; 2818 } 2819 2820 OMX_AUDIO_PARAM_ANDROID_AC3TYPE def; 2821 InitOMXParams(&def); 2822 def.nPortIndex = kPortIndexInput; 2823 2824 err = mOMXNode->getParameter( 2825 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def)); 2826 2827 if (err != OK) { 2828 return err; 2829 } 2830 2831 def.nChannels = numChannels; 2832 def.nSampleRate = sampleRate; 2833 2834 return mOMXNode->setParameter( 2835 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def)); 2836 } 2837 2838 status_t ACodec::setupEAC3Codec( 2839 bool encoder, int32_t numChannels, int32_t sampleRate) { 2840 status_t err = setupRawAudioFormat( 2841 encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels); 2842 2843 if (err != OK) { 2844 return err; 2845 } 2846 2847 if (encoder) { 2848 ALOGW("EAC3 encoding is not supported."); 2849 return INVALID_OPERATION; 2850 } 2851 2852 OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def; 2853 InitOMXParams(&def); 2854 def.nPortIndex = kPortIndexInput; 2855 2856 err = mOMXNode->getParameter( 2857 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def)); 2858 2859 if (err != OK) { 2860 return err; 2861 } 2862 2863 def.nChannels = numChannels; 2864 def.nSampleRate = sampleRate; 2865 2866 return mOMXNode->setParameter( 2867 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def)); 2868 } 2869 2870 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate( 2871 bool isAMRWB, int32_t bps) { 2872 if (isAMRWB) { 2873 if (bps <= 6600) { 2874 return OMX_AUDIO_AMRBandModeWB0; 2875 } else if (bps <= 8850) { 2876 return OMX_AUDIO_AMRBandModeWB1; 2877 } else if (bps <= 12650) { 2878 return OMX_AUDIO_AMRBandModeWB2; 2879 } else if (bps <= 14250) { 2880 return OMX_AUDIO_AMRBandModeWB3; 2881 } else if (bps <= 15850) { 2882 return OMX_AUDIO_AMRBandModeWB4; 2883 } else if (bps <= 18250) { 2884 return OMX_AUDIO_AMRBandModeWB5; 2885 } else if (bps <= 19850) { 2886 return OMX_AUDIO_AMRBandModeWB6; 2887 } else if (bps <= 23050) { 2888 return OMX_AUDIO_AMRBandModeWB7; 2889 } 2890 2891 // 23850 bps 2892 return OMX_AUDIO_AMRBandModeWB8; 2893 } else { // AMRNB 2894 if (bps <= 4750) { 2895 return OMX_AUDIO_AMRBandModeNB0; 2896 } else if (bps <= 5150) { 2897 return OMX_AUDIO_AMRBandModeNB1; 2898 } else if (bps <= 5900) { 2899 return OMX_AUDIO_AMRBandModeNB2; 2900 } else if (bps <= 6700) { 2901 return OMX_AUDIO_AMRBandModeNB3; 2902 } else if (bps <= 7400) { 2903 return OMX_AUDIO_AMRBandModeNB4; 2904 } else if (bps <= 7950) { 2905 return OMX_AUDIO_AMRBandModeNB5; 2906 } else if (bps <= 10200) { 2907 return OMX_AUDIO_AMRBandModeNB6; 2908 } 2909 2910 // 12200 bps 2911 return OMX_AUDIO_AMRBandModeNB7; 2912 } 2913 } 2914 2915 status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) { 2916 OMX_AUDIO_PARAM_AMRTYPE def; 2917 InitOMXParams(&def); 2918 def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput; 2919 2920 status_t err = mOMXNode->getParameter( 2921 OMX_IndexParamAudioAmr, &def, sizeof(def)); 2922 2923 if (err != OK) { 2924 return err; 2925 } 2926 2927 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 2928 def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate); 2929 2930 err = mOMXNode->setParameter( 2931 OMX_IndexParamAudioAmr, &def, sizeof(def)); 2932 2933 if (err != OK) { 2934 return err; 2935 } 2936 2937 return setupRawAudioFormat( 2938 encoder ? kPortIndexInput : kPortIndexOutput, 2939 isWAMR ? 16000 : 8000 /* sampleRate */, 2940 1 /* numChannels */); 2941 } 2942 2943 status_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) { 2944 if (encoder) { 2945 return INVALID_OPERATION; 2946 } 2947 2948 return setupRawAudioFormat( 2949 kPortIndexInput, sampleRate, numChannels); 2950 } 2951 2952 status_t ACodec::setupFlacCodec( 2953 bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) { 2954 2955 if (encoder) { 2956 OMX_AUDIO_PARAM_FLACTYPE def; 2957 InitOMXParams(&def); 2958 def.nPortIndex = kPortIndexOutput; 2959 2960 // configure compression level 2961 status_t err = mOMXNode->getParameter(OMX_IndexParamAudioFlac, &def, sizeof(def)); 2962 if (err != OK) { 2963 ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err); 2964 return err; 2965 } 2966 def.nCompressionLevel = compressionLevel; 2967 err = mOMXNode->setParameter(OMX_IndexParamAudioFlac, &def, sizeof(def)); 2968 if (err != OK) { 2969 ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err); 2970 return err; 2971 } 2972 } 2973 2974 return setupRawAudioFormat( 2975 encoder ? kPortIndexInput : kPortIndexOutput, 2976 sampleRate, 2977 numChannels); 2978 } 2979 2980 status_t ACodec::setupRawAudioFormat( 2981 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) { 2982 OMX_PARAM_PORTDEFINITIONTYPE def; 2983 InitOMXParams(&def); 2984 def.nPortIndex = portIndex; 2985 2986 status_t err = mOMXNode->getParameter( 2987 OMX_IndexParamPortDefinition, &def, sizeof(def)); 2988 2989 if (err != OK) { 2990 return err; 2991 } 2992 2993 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 2994 2995 err = mOMXNode->setParameter( 2996 OMX_IndexParamPortDefinition, &def, sizeof(def)); 2997 2998 if (err != OK) { 2999 return err; 3000 } 3001 3002 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 3003 InitOMXParams(&pcmParams); 3004 pcmParams.nPortIndex = portIndex; 3005 3006 err = mOMXNode->getParameter( 3007 OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 3008 3009 if (err != OK) { 3010 return err; 3011 } 3012 3013 pcmParams.nChannels = numChannels; 3014 switch (encoding) { 3015 case kAudioEncodingPcm8bit: 3016 pcmParams.eNumData = OMX_NumericalDataUnsigned; 3017 pcmParams.nBitPerSample = 8; 3018 break; 3019 case kAudioEncodingPcmFloat: 3020 pcmParams.eNumData = OMX_NumericalDataFloat; 3021 pcmParams.nBitPerSample = 32; 3022 break; 3023 case kAudioEncodingPcm16bit: 3024 pcmParams.eNumData = OMX_NumericalDataSigned; 3025 pcmParams.nBitPerSample = 16; 3026 break; 3027 default: 3028 return BAD_VALUE; 3029 } 3030 pcmParams.bInterleaved = OMX_TRUE; 3031 pcmParams.nSamplingRate = sampleRate; 3032 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 3033 3034 if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) { 3035 return OMX_ErrorNone; 3036 } 3037 3038 err = mOMXNode->setParameter( 3039 OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 3040 // if we could not set up raw format to non-16-bit, try with 16-bit 3041 // NOTE: we will also verify this via readback, in case codec ignores these fields 3042 if (err != OK && encoding != kAudioEncodingPcm16bit) { 3043 pcmParams.eNumData = OMX_NumericalDataSigned; 3044 pcmParams.nBitPerSample = 16; 3045 err = mOMXNode->setParameter( 3046 OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 3047 } 3048 return err; 3049 } 3050 3051 status_t ACodec::configureTunneledVideoPlayback( 3052 int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) { 3053 native_handle_t* sidebandHandle; 3054 3055 status_t err = mOMXNode->configureVideoTunnelMode( 3056 kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle); 3057 if (err != OK) { 3058 ALOGE("configureVideoTunnelMode failed! (err %d).", err); 3059 return err; 3060 } 3061 3062 err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle); 3063 if (err != OK) { 3064 ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).", 3065 sidebandHandle, err); 3066 return err; 3067 } 3068 3069 return OK; 3070 } 3071 3072 status_t ACodec::setVideoPortFormatType( 3073 OMX_U32 portIndex, 3074 OMX_VIDEO_CODINGTYPE compressionFormat, 3075 OMX_COLOR_FORMATTYPE colorFormat, 3076 bool usingNativeBuffers) { 3077 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 3078 InitOMXParams(&format); 3079 format.nPortIndex = portIndex; 3080 format.nIndex = 0; 3081 bool found = false; 3082 3083 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 3084 format.nIndex = index; 3085 status_t err = mOMXNode->getParameter( 3086 OMX_IndexParamVideoPortFormat, 3087 &format, sizeof(format)); 3088 3089 if (err != OK) { 3090 return err; 3091 } 3092 3093 // substitute back flexible color format to codec supported format 3094 OMX_U32 flexibleEquivalent; 3095 if (compressionFormat == OMX_VIDEO_CodingUnused 3096 && IsFlexibleColorFormat( 3097 mOMXNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent) 3098 && colorFormat == flexibleEquivalent) { 3099 ALOGI("[%s] using color format %#x in place of %#x", 3100 mComponentName.c_str(), format.eColorFormat, colorFormat); 3101 colorFormat = format.eColorFormat; 3102 } 3103 3104 // The following assertion is violated by TI's video decoder. 3105 // CHECK_EQ(format.nIndex, index); 3106 3107 if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) { 3108 if (portIndex == kPortIndexInput 3109 && colorFormat == format.eColorFormat) { 3110 // eCompressionFormat does not seem right. 3111 found = true; 3112 break; 3113 } 3114 if (portIndex == kPortIndexOutput 3115 && compressionFormat == format.eCompressionFormat) { 3116 // eColorFormat does not seem right. 3117 found = true; 3118 break; 3119 } 3120 } 3121 3122 if (format.eCompressionFormat == compressionFormat 3123 && format.eColorFormat == colorFormat) { 3124 found = true; 3125 break; 3126 } 3127 3128 if (index == kMaxIndicesToCheck) { 3129 ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)", 3130 mComponentName.c_str(), index, 3131 asString(format.eCompressionFormat), format.eCompressionFormat, 3132 asString(format.eColorFormat), format.eColorFormat); 3133 } 3134 } 3135 3136 if (!found) { 3137 return UNKNOWN_ERROR; 3138 } 3139 3140 status_t err = mOMXNode->setParameter( 3141 OMX_IndexParamVideoPortFormat, &format, sizeof(format)); 3142 3143 return err; 3144 } 3145 3146 // Set optimal output format. OMX component lists output formats in the order 3147 // of preference, but this got more complicated since the introduction of flexible 3148 // YUV formats. We support a legacy behavior for applications that do not use 3149 // surface output, do not specify an output format, but expect a "usable" standard 3150 // OMX format. SW readable and standard formats must be flex-YUV. 3151 // 3152 // Suggested preference order: 3153 // - optimal format for texture rendering (mediaplayer behavior) 3154 // - optimal SW readable & texture renderable format (flex-YUV support) 3155 // - optimal SW readable non-renderable format (flex-YUV bytebuffer support) 3156 // - legacy "usable" standard formats 3157 // 3158 // For legacy support, we prefer a standard format, but will settle for a SW readable 3159 // flex-YUV format. 3160 status_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) { 3161 OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat; 3162 InitOMXParams(&format); 3163 format.nPortIndex = kPortIndexOutput; 3164 3165 InitOMXParams(&legacyFormat); 3166 // this field will change when we find a suitable legacy format 3167 legacyFormat.eColorFormat = OMX_COLOR_FormatUnused; 3168 3169 for (OMX_U32 index = 0; ; ++index) { 3170 format.nIndex = index; 3171 status_t err = mOMXNode->getParameter( 3172 OMX_IndexParamVideoPortFormat, &format, sizeof(format)); 3173 if (err != OK) { 3174 // no more formats, pick legacy format if found 3175 if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) { 3176 memcpy(&format, &legacyFormat, sizeof(format)); 3177 break; 3178 } 3179 return err; 3180 } 3181 if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) { 3182 return OMX_ErrorBadParameter; 3183 } 3184 if (!getLegacyFlexibleFormat) { 3185 break; 3186 } 3187 // standard formats that were exposed to users before 3188 if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar 3189 || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar 3190 || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar 3191 || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar 3192 || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { 3193 break; 3194 } 3195 // find best legacy non-standard format 3196 OMX_U32 flexibleEquivalent; 3197 if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused 3198 && IsFlexibleColorFormat( 3199 mOMXNode, format.eColorFormat, false /* usingNativeBuffers */, 3200 &flexibleEquivalent) 3201 && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) { 3202 memcpy(&legacyFormat, &format, sizeof(format)); 3203 } 3204 } 3205 return mOMXNode->setParameter( 3206 OMX_IndexParamVideoPortFormat, &format, sizeof(format)); 3207 } 3208 3209 static const struct VideoCodingMapEntry { 3210 const char *mMime; 3211 OMX_VIDEO_CODINGTYPE mVideoCodingType; 3212 } kVideoCodingMapEntry[] = { 3213 { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC }, 3214 { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC }, 3215 { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 }, 3216 { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 }, 3217 { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 }, 3218 { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 }, 3219 { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 }, 3220 { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision }, 3221 }; 3222 3223 static status_t GetVideoCodingTypeFromMime( 3224 const char *mime, OMX_VIDEO_CODINGTYPE *codingType) { 3225 for (size_t i = 0; 3226 i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]); 3227 ++i) { 3228 if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) { 3229 *codingType = kVideoCodingMapEntry[i].mVideoCodingType; 3230 return OK; 3231 } 3232 } 3233 3234 *codingType = OMX_VIDEO_CodingUnused; 3235 3236 return ERROR_UNSUPPORTED; 3237 } 3238 3239 static status_t GetMimeTypeForVideoCoding( 3240 OMX_VIDEO_CODINGTYPE codingType, AString *mime) { 3241 for (size_t i = 0; 3242 i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]); 3243 ++i) { 3244 if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) { 3245 *mime = kVideoCodingMapEntry[i].mMime; 3246 return OK; 3247 } 3248 } 3249 3250 mime->clear(); 3251 3252 return ERROR_UNSUPPORTED; 3253 } 3254 3255 status_t ACodec::setPortBufferNum(OMX_U32 portIndex, int bufferNum) { 3256 OMX_PARAM_PORTDEFINITIONTYPE def; 3257 InitOMXParams(&def); 3258 def.nPortIndex = portIndex; 3259 status_t err; 3260 ALOGD("Setting [%s] %s port buffer number: %d", mComponentName.c_str(), 3261 portIndex == kPortIndexInput ? "input" : "output", bufferNum); 3262 err = mOMXNode->getParameter( 3263 OMX_IndexParamPortDefinition, &def, sizeof(def)); 3264 if (err != OK) { 3265 return err; 3266 } 3267 def.nBufferCountActual = bufferNum; 3268 err = mOMXNode->setParameter( 3269 OMX_IndexParamPortDefinition, &def, sizeof(def)); 3270 if (err != OK) { 3271 // Component could reject this request. 3272 ALOGW("Fail to set [%s] %s port buffer number: %d", mComponentName.c_str(), 3273 portIndex == kPortIndexInput ? "input" : "output", bufferNum); 3274 } 3275 return OK; 3276 } 3277 3278 status_t ACodec::setupVideoDecoder( 3279 const char *mime, const sp<AMessage> &msg, bool haveNativeWindow, 3280 bool usingSwRenderer, sp<AMessage> &outputFormat) { 3281 int32_t width, height; 3282 if (!msg->findInt32("width", &width) 3283 || !msg->findInt32("height", &height)) { 3284 return INVALID_OPERATION; 3285 } 3286 3287 OMX_VIDEO_CODINGTYPE compressionFormat; 3288 status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat); 3289 3290 if (err != OK) { 3291 return err; 3292 } 3293 3294 if (compressionFormat == OMX_VIDEO_CodingVP9) { 3295 OMX_VIDEO_PARAM_PROFILELEVELTYPE params; 3296 InitOMXParams(¶ms); 3297 params.nPortIndex = kPortIndexInput; 3298 // Check if VP9 decoder advertises supported profiles. 3299 params.nProfileIndex = 0; 3300 status_t err = mOMXNode->getParameter( 3301 OMX_IndexParamVideoProfileLevelQuerySupported, 3302 ¶ms, sizeof(params)); 3303 mIsLegacyVP9Decoder = err != OK; 3304 } 3305 3306 err = setVideoPortFormatType( 3307 kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 3308 3309 if (err != OK) { 3310 return err; 3311 } 3312 3313 int32_t tmp; 3314 if (msg->findInt32("color-format", &tmp)) { 3315 OMX_COLOR_FORMATTYPE colorFormat = 3316 static_cast<OMX_COLOR_FORMATTYPE>(tmp); 3317 err = setVideoPortFormatType( 3318 kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow); 3319 if (err != OK) { 3320 ALOGW("[%s] does not support color format %d", 3321 mComponentName.c_str(), colorFormat); 3322 err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */); 3323 } 3324 } else { 3325 err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */); 3326 } 3327 3328 if (err != OK) { 3329 return err; 3330 } 3331 3332 // Set the component input buffer number to be |tmp|. If succeed, 3333 // component will set input port buffer number to be |tmp|. If fail, 3334 // component will keep the same buffer number as before. 3335 if (msg->findInt32("android._num-input-buffers", &tmp)) { 3336 err = setPortBufferNum(kPortIndexInput, tmp); 3337 if (err != OK) 3338 return err; 3339 } 3340 3341 // Set the component output buffer number to be |tmp|. If succeed, 3342 // component will set output port buffer number to be |tmp|. If fail, 3343 // component will keep the same buffer number as before. 3344 if (msg->findInt32("android._num-output-buffers", &tmp)) { 3345 err = setPortBufferNum(kPortIndexOutput, tmp); 3346 if (err != OK) 3347 return err; 3348 } 3349 3350 int32_t frameRateInt; 3351 float frameRateFloat; 3352 if (!msg->findFloat("frame-rate", &frameRateFloat)) { 3353 if (!msg->findInt32("frame-rate", &frameRateInt)) { 3354 frameRateInt = -1; 3355 } 3356 frameRateFloat = (float)frameRateInt; 3357 } 3358 3359 err = setVideoFormatOnPort( 3360 kPortIndexInput, width, height, compressionFormat, frameRateFloat); 3361 3362 if (err != OK) { 3363 return err; 3364 } 3365 3366 err = setVideoFormatOnPort( 3367 kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused); 3368 3369 if (err != OK) { 3370 return err; 3371 } 3372 3373 err = setColorAspectsForVideoDecoder( 3374 width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat); 3375 if (err == ERROR_UNSUPPORTED) { // support is optional 3376 err = OK; 3377 } 3378 3379 if (err != OK) { 3380 return err; 3381 } 3382 3383 err = setHDRStaticInfoForVideoCodec(kPortIndexOutput, msg, outputFormat); 3384 if (err == ERROR_UNSUPPORTED) { // support is optional 3385 err = OK; 3386 } 3387 return err; 3388 } 3389 3390 status_t ACodec::initDescribeColorAspectsIndex() { 3391 status_t err = mOMXNode->getExtensionIndex( 3392 "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex); 3393 if (err != OK) { 3394 mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0; 3395 } 3396 return err; 3397 } 3398 3399 status_t ACodec::setCodecColorAspects(DescribeColorAspectsParams ¶ms, bool verify) { 3400 status_t err = ERROR_UNSUPPORTED; 3401 if (mDescribeColorAspectsIndex) { 3402 err = mOMXNode->setConfig(mDescribeColorAspectsIndex, ¶ms, sizeof(params)); 3403 } 3404 ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)", 3405 mComponentName.c_str(), 3406 params.sAspects.mRange, asString(params.sAspects.mRange), 3407 params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries), 3408 params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs), 3409 params.sAspects.mTransfer, asString(params.sAspects.mTransfer), 3410 err, asString(err)); 3411 3412 if (verify && err == OK) { 3413 err = getCodecColorAspects(params); 3414 } 3415 3416 ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex, 3417 "[%s] setting color aspects failed even though codec advertises support", 3418 mComponentName.c_str()); 3419 return err; 3420 } 3421 3422 status_t ACodec::setColorAspectsForVideoDecoder( 3423 int32_t width, int32_t height, bool usingNativeWindow, 3424 const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) { 3425 DescribeColorAspectsParams params; 3426 InitOMXParams(¶ms); 3427 params.nPortIndex = kPortIndexOutput; 3428 3429 getColorAspectsFromFormat(configFormat, params.sAspects); 3430 if (usingNativeWindow) { 3431 setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height); 3432 // The default aspects will be set back to the output format during the 3433 // getFormat phase of configure(). Set non-Unspecified values back into the 3434 // format, in case component does not support this enumeration. 3435 setColorAspectsIntoFormat(params.sAspects, outputFormat); 3436 } 3437 3438 (void)initDescribeColorAspectsIndex(); 3439 3440 // communicate color aspects to codec 3441 return setCodecColorAspects(params); 3442 } 3443 3444 status_t ACodec::getCodecColorAspects(DescribeColorAspectsParams ¶ms) { 3445 status_t err = ERROR_UNSUPPORTED; 3446 if (mDescribeColorAspectsIndex) { 3447 err = mOMXNode->getConfig(mDescribeColorAspectsIndex, ¶ms, sizeof(params)); 3448 } 3449 ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)", 3450 mComponentName.c_str(), 3451 params.sAspects.mRange, asString(params.sAspects.mRange), 3452 params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries), 3453 params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs), 3454 params.sAspects.mTransfer, asString(params.sAspects.mTransfer), 3455 err, asString(err)); 3456 if (params.bRequestingDataSpace) { 3457 ALOGV("for dataspace %#x", params.nDataSpace); 3458 } 3459 if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex 3460 && !params.bRequestingDataSpace && !params.bDataSpaceChanged) { 3461 ALOGW("[%s] getting color aspects failed even though codec advertises support", 3462 mComponentName.c_str()); 3463 } 3464 return err; 3465 } 3466 3467 status_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) { 3468 DescribeColorAspectsParams params; 3469 InitOMXParams(¶ms); 3470 params.nPortIndex = kPortIndexInput; 3471 status_t err = getCodecColorAspects(params); 3472 if (err == OK) { 3473 // we only set encoder input aspects if codec supports them 3474 setColorAspectsIntoFormat(params.sAspects, format, true /* force */); 3475 } 3476 return err; 3477 } 3478 3479 status_t ACodec::getDataSpace( 3480 DescribeColorAspectsParams ¶ms, android_dataspace *dataSpace /* nonnull */, 3481 bool tryCodec) { 3482 status_t err = OK; 3483 if (tryCodec) { 3484 // request dataspace guidance from codec. 3485 params.bRequestingDataSpace = OMX_TRUE; 3486 err = getCodecColorAspects(params); 3487 params.bRequestingDataSpace = OMX_FALSE; 3488 if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) { 3489 *dataSpace = (android_dataspace)params.nDataSpace; 3490 return err; 3491 } else if (err == ERROR_UNSUPPORTED) { 3492 // ignore not-implemented error for dataspace requests 3493 err = OK; 3494 } 3495 } 3496 3497 // this returns legacy versions if available 3498 *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */); 3499 ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) " 3500 "and dataspace %#x", 3501 mComponentName.c_str(), 3502 params.sAspects.mRange, asString(params.sAspects.mRange), 3503 params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries), 3504 params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs), 3505 params.sAspects.mTransfer, asString(params.sAspects.mTransfer), 3506 *dataSpace); 3507 return err; 3508 } 3509 3510 3511 status_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder( 3512 int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, 3513 android_dataspace *dataSpace) { 3514 DescribeColorAspectsParams params; 3515 InitOMXParams(¶ms); 3516 params.nPortIndex = kPortIndexOutput; 3517 3518 // reset default format and get resulting format 3519 getColorAspectsFromFormat(configFormat, params.sAspects); 3520 if (dataSpace != NULL) { 3521 setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height); 3522 } 3523 status_t err = setCodecColorAspects(params, true /* readBack */); 3524 3525 // we always set specified aspects for decoders 3526 setColorAspectsIntoFormat(params.sAspects, outputFormat); 3527 3528 if (dataSpace != NULL) { 3529 status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */); 3530 if (err == OK) { 3531 err = res; 3532 } 3533 } 3534 3535 return err; 3536 } 3537 3538 // initial video encoder setup for bytebuffer mode 3539 status_t ACodec::setColorAspectsForVideoEncoder( 3540 const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) { 3541 // copy config to output format as this is not exposed via getFormat 3542 copyColorConfig(configFormat, outputFormat); 3543 3544 DescribeColorAspectsParams params; 3545 InitOMXParams(¶ms); 3546 params.nPortIndex = kPortIndexInput; 3547 getColorAspectsFromFormat(configFormat, params.sAspects); 3548 3549 (void)initDescribeColorAspectsIndex(); 3550 3551 int32_t usingRecorder; 3552 if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) { 3553 android_dataspace dataSpace = HAL_DATASPACE_BT709; 3554 int32_t width, height; 3555 if (configFormat->findInt32("width", &width) 3556 && configFormat->findInt32("height", &height)) { 3557 setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height); 3558 status_t err = getDataSpace( 3559 params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */); 3560 if (err != OK) { 3561 return err; 3562 } 3563 setColorAspectsIntoFormat(params.sAspects, outputFormat); 3564 } 3565 inputFormat->setInt32("android._dataspace", (int32_t)dataSpace); 3566 } 3567 3568 // communicate color aspects to codec, but do not allow change of the platform aspects 3569 ColorAspects origAspects = params.sAspects; 3570 for (int triesLeft = 2; --triesLeft >= 0; ) { 3571 status_t err = setCodecColorAspects(params, true /* readBack */); 3572 if (err != OK 3573 || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem( 3574 params.sAspects, origAspects, true /* usePlatformAspects */)) { 3575 return err; 3576 } 3577 ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.", 3578 mComponentName.c_str()); 3579 } 3580 return OK; 3581 } 3582 3583 status_t ACodec::setHDRStaticInfoForVideoCodec( 3584 OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) { 3585 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 3586 3587 DescribeHDRStaticInfoParams params; 3588 InitOMXParams(¶ms); 3589 params.nPortIndex = portIndex; 3590 3591 HDRStaticInfo *info = ¶ms.sInfo; 3592 if (getHDRStaticInfoFromFormat(configFormat, info)) { 3593 setHDRStaticInfoIntoFormat(params.sInfo, outputFormat); 3594 } 3595 3596 (void)initDescribeHDRStaticInfoIndex(); 3597 3598 // communicate HDR static Info to codec 3599 return setHDRStaticInfo(params); 3600 } 3601 3602 // subsequent initial video encoder setup for surface mode 3603 status_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace( 3604 android_dataspace *dataSpace /* nonnull */) { 3605 DescribeColorAspectsParams params; 3606 InitOMXParams(¶ms); 3607 params.nPortIndex = kPortIndexInput; 3608 ColorAspects &aspects = params.sAspects; 3609 3610 // reset default format and store resulting format into both input and output formats 3611 getColorAspectsFromFormat(mConfigFormat, aspects); 3612 int32_t width, height; 3613 if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) { 3614 setDefaultCodecColorAspectsIfNeeded(aspects, width, height); 3615 } 3616 setColorAspectsIntoFormat(aspects, mInputFormat); 3617 setColorAspectsIntoFormat(aspects, mOutputFormat); 3618 3619 // communicate color aspects to codec, but do not allow any change 3620 ColorAspects origAspects = aspects; 3621 status_t err = OK; 3622 for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) { 3623 status_t err = setCodecColorAspects(params, true /* readBack */); 3624 if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) { 3625 break; 3626 } 3627 ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.", 3628 mComponentName.c_str()); 3629 } 3630 3631 *dataSpace = HAL_DATASPACE_BT709; 3632 aspects = origAspects; // restore desired color aspects 3633 status_t res = getDataSpace( 3634 params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */); 3635 if (err == OK) { 3636 err = res; 3637 } 3638 mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace); 3639 mInputFormat->setBuffer( 3640 "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects))); 3641 3642 // update input format with codec supported color aspects (basically set unsupported 3643 // aspects to Unspecified) 3644 if (err == OK) { 3645 (void)getInputColorAspectsForVideoEncoder(mInputFormat); 3646 } 3647 3648 ALOGV("set default color aspects, updated input format to %s, output format to %s", 3649 mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str()); 3650 3651 return err; 3652 } 3653 3654 status_t ACodec::getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format) { 3655 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 3656 DescribeHDRStaticInfoParams params; 3657 InitOMXParams(¶ms); 3658 params.nPortIndex = portIndex; 3659 3660 status_t err = getHDRStaticInfo(params); 3661 if (err == OK) { 3662 // we only set decodec output HDRStaticInfo if codec supports them 3663 setHDRStaticInfoIntoFormat(params.sInfo, format); 3664 } 3665 return err; 3666 } 3667 3668 status_t ACodec::initDescribeHDRStaticInfoIndex() { 3669 status_t err = mOMXNode->getExtensionIndex( 3670 "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex); 3671 if (err != OK) { 3672 mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0; 3673 } 3674 return err; 3675 } 3676 3677 status_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams ¶ms) { 3678 status_t err = ERROR_UNSUPPORTED; 3679 if (mDescribeHDRStaticInfoIndex) { 3680 err = mOMXNode->setConfig(mDescribeHDRStaticInfoIndex, ¶ms, sizeof(params)); 3681 } 3682 3683 const HDRStaticInfo *info = ¶ms.sInfo; 3684 ALOGV("[%s] setting HDRStaticInfo (R: %u %u, G: %u %u, B: %u, %u, W: %u, %u, " 3685 "MaxDispL: %u, MinDispL: %u, MaxContentL: %u, MaxFrameAvgL: %u)", 3686 mComponentName.c_str(), 3687 info->sType1.mR.x, info->sType1.mR.y, info->sType1.mG.x, info->sType1.mG.y, 3688 info->sType1.mB.x, info->sType1.mB.y, info->sType1.mW.x, info->sType1.mW.y, 3689 info->sType1.mMaxDisplayLuminance, info->sType1.mMinDisplayLuminance, 3690 info->sType1.mMaxContentLightLevel, info->sType1.mMaxFrameAverageLightLevel); 3691 3692 ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex, 3693 "[%s] setting HDRStaticInfo failed even though codec advertises support", 3694 mComponentName.c_str()); 3695 return err; 3696 } 3697 3698 status_t ACodec::getHDRStaticInfo(DescribeHDRStaticInfoParams ¶ms) { 3699 status_t err = ERROR_UNSUPPORTED; 3700 if (mDescribeHDRStaticInfoIndex) { 3701 err = mOMXNode->getConfig(mDescribeHDRStaticInfoIndex, ¶ms, sizeof(params)); 3702 } 3703 3704 ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex, 3705 "[%s] getting HDRStaticInfo failed even though codec advertises support", 3706 mComponentName.c_str()); 3707 return err; 3708 } 3709 3710 status_t ACodec::setupVideoEncoder( 3711 const char *mime, const sp<AMessage> &msg, 3712 sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) { 3713 int32_t tmp; 3714 if (!msg->findInt32("color-format", &tmp)) { 3715 return INVALID_OPERATION; 3716 } 3717 3718 OMX_COLOR_FORMATTYPE colorFormat = 3719 static_cast<OMX_COLOR_FORMATTYPE>(tmp); 3720 3721 status_t err = setVideoPortFormatType( 3722 kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat); 3723 3724 if (err != OK) { 3725 ALOGE("[%s] does not support color format %d", 3726 mComponentName.c_str(), colorFormat); 3727 3728 return err; 3729 } 3730 3731 /* Input port configuration */ 3732 3733 OMX_PARAM_PORTDEFINITIONTYPE def; 3734 InitOMXParams(&def); 3735 3736 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 3737 3738 def.nPortIndex = kPortIndexInput; 3739 3740 err = mOMXNode->getParameter( 3741 OMX_IndexParamPortDefinition, &def, sizeof(def)); 3742 3743 if (err != OK) { 3744 return err; 3745 } 3746 3747 int32_t width, height, bitrate; 3748 if (!msg->findInt32("width", &width) 3749 || !msg->findInt32("height", &height) 3750 || !msg->findInt32("bitrate", &bitrate)) { 3751 return INVALID_OPERATION; 3752 } 3753 3754 video_def->nFrameWidth = width; 3755 video_def->nFrameHeight = height; 3756 3757 int32_t stride; 3758 if (!msg->findInt32("stride", &stride)) { 3759 stride = width; 3760 } 3761 3762 video_def->nStride = stride; 3763 3764 int32_t sliceHeight; 3765 if (!msg->findInt32("slice-height", &sliceHeight)) { 3766 sliceHeight = height; 3767 } 3768 3769 video_def->nSliceHeight = sliceHeight; 3770 3771 def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2; 3772 3773 float framerate; 3774 if (!msg->findFloat("frame-rate", &framerate)) { 3775 int32_t tmp; 3776 if (!msg->findInt32("frame-rate", &tmp)) { 3777 return INVALID_OPERATION; 3778 } 3779 mFps = (double)tmp; 3780 } else { 3781 mFps = (double)framerate; 3782 } 3783 3784 video_def->xFramerate = (OMX_U32)(mFps * 65536); 3785 video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; 3786 // this is redundant as it was already set up in setVideoPortFormatType 3787 // FIXME for now skip this only for flexible YUV formats 3788 if (colorFormat != OMX_COLOR_FormatYUV420Flexible) { 3789 video_def->eColorFormat = colorFormat; 3790 } 3791 3792 err = mOMXNode->setParameter( 3793 OMX_IndexParamPortDefinition, &def, sizeof(def)); 3794 3795 if (err != OK) { 3796 ALOGE("[%s] failed to set input port definition parameters.", 3797 mComponentName.c_str()); 3798 3799 return err; 3800 } 3801 3802 /* Output port configuration */ 3803 3804 OMX_VIDEO_CODINGTYPE compressionFormat; 3805 err = GetVideoCodingTypeFromMime(mime, &compressionFormat); 3806 3807 if (err != OK) { 3808 return err; 3809 } 3810 3811 err = setVideoPortFormatType( 3812 kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused); 3813 3814 if (err != OK) { 3815 ALOGE("[%s] does not support compression format %d", 3816 mComponentName.c_str(), compressionFormat); 3817 3818 return err; 3819 } 3820 3821 def.nPortIndex = kPortIndexOutput; 3822 3823 err = mOMXNode->getParameter( 3824 OMX_IndexParamPortDefinition, &def, sizeof(def)); 3825 3826 if (err != OK) { 3827 return err; 3828 } 3829 3830 video_def->nFrameWidth = width; 3831 video_def->nFrameHeight = height; 3832 video_def->xFramerate = 0; 3833 video_def->nBitrate = bitrate; 3834 video_def->eCompressionFormat = compressionFormat; 3835 video_def->eColorFormat = OMX_COLOR_FormatUnused; 3836 3837 err = mOMXNode->setParameter( 3838 OMX_IndexParamPortDefinition, &def, sizeof(def)); 3839 3840 if (err != OK) { 3841 ALOGE("[%s] failed to set output port definition parameters.", 3842 mComponentName.c_str()); 3843 3844 return err; 3845 } 3846 3847 int32_t intraRefreshPeriod = 0; 3848 if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod) 3849 && intraRefreshPeriod >= 0) { 3850 err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true); 3851 if (err != OK) { 3852 ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional", 3853 mComponentName.c_str()); 3854 err = OK; 3855 } 3856 } 3857 3858 configureEncoderLatency(msg); 3859 3860 switch (compressionFormat) { 3861 case OMX_VIDEO_CodingMPEG4: 3862 err = setupMPEG4EncoderParameters(msg); 3863 break; 3864 3865 case OMX_VIDEO_CodingH263: 3866 err = setupH263EncoderParameters(msg); 3867 break; 3868 3869 case OMX_VIDEO_CodingAVC: 3870 err = setupAVCEncoderParameters(msg); 3871 break; 3872 3873 case OMX_VIDEO_CodingHEVC: 3874 err = setupHEVCEncoderParameters(msg); 3875 break; 3876 3877 case OMX_VIDEO_CodingVP8: 3878 case OMX_VIDEO_CodingVP9: 3879 err = setupVPXEncoderParameters(msg, outputFormat); 3880 break; 3881 3882 default: 3883 break; 3884 } 3885 3886 if (err != OK) { 3887 return err; 3888 } 3889 3890 // Set up color aspects on input, but propagate them to the output format, as they will 3891 // not be read back from encoder. 3892 err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat); 3893 if (err == ERROR_UNSUPPORTED) { 3894 ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str()); 3895 err = OK; 3896 } 3897 3898 if (err != OK) { 3899 return err; 3900 } 3901 3902 err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat); 3903 if (err == ERROR_UNSUPPORTED) { // support is optional 3904 ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str()); 3905 err = OK; 3906 } 3907 3908 if (err != OK) { 3909 return err; 3910 } 3911 3912 switch (compressionFormat) { 3913 case OMX_VIDEO_CodingAVC: 3914 case OMX_VIDEO_CodingHEVC: 3915 err = configureTemporalLayers(msg, true /* inConfigure */, outputFormat); 3916 if (err != OK) { 3917 err = OK; // ignore failure 3918 } 3919 break; 3920 3921 case OMX_VIDEO_CodingVP8: 3922 case OMX_VIDEO_CodingVP9: 3923 // TODO: do we need to support android.generic layering? webrtc layering is 3924 // already set up in setupVPXEncoderParameters. 3925 break; 3926 3927 default: 3928 break; 3929 } 3930 3931 if (err == OK) { 3932 ALOGI("setupVideoEncoder succeeded"); 3933 } 3934 3935 return err; 3936 } 3937 3938 status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) { 3939 OMX_VIDEO_PARAM_INTRAREFRESHTYPE params; 3940 InitOMXParams(¶ms); 3941 params.nPortIndex = kPortIndexOutput; 3942 3943 params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode); 3944 3945 if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic || 3946 params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 3947 int32_t mbs; 3948 if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) { 3949 return INVALID_OPERATION; 3950 } 3951 params.nCirMBs = mbs; 3952 } 3953 3954 if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive || 3955 params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 3956 int32_t mbs; 3957 if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) { 3958 return INVALID_OPERATION; 3959 } 3960 params.nAirMBs = mbs; 3961 3962 int32_t ref; 3963 if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) { 3964 return INVALID_OPERATION; 3965 } 3966 params.nAirRef = ref; 3967 } 3968 3969 status_t err = mOMXNode->setParameter( 3970 OMX_IndexParamVideoIntraRefresh, ¶ms, sizeof(params)); 3971 return err; 3972 } 3973 3974 static OMX_U32 setPFramesSpacing( 3975 float iFramesInterval /* seconds */, int32_t frameRate, uint32_t BFramesSpacing = 0) { 3976 // BFramesSpacing is the number of B frames between I/P frames 3977 // PFramesSpacing (the value to be returned) is the number of P frames between I frames 3978 // 3979 // keyFrameInterval = ((PFramesSpacing + 1) * BFramesSpacing) + PFramesSpacing + 1 3980 // ^^^ ^^^ ^^^ 3981 // number of B frames number of P I frame 3982 // 3983 // = (PFramesSpacing + 1) * (BFramesSpacing + 1) 3984 // 3985 // E.g. 3986 // I P I : I-interval: 8, nPFrames 1, nBFrames 3 3987 // BBB BBB 3988 3989 if (iFramesInterval < 0) { // just 1 key frame 3990 return 0xFFFFFFFE; // don't use maxint as key-frame-interval calculation will add 1 3991 } else if (iFramesInterval == 0) { // just key frames 3992 return 0; 3993 } 3994 3995 // round down as key-frame-interval is an upper limit 3996 uint32_t keyFrameInterval = uint32_t(frameRate * iFramesInterval); 3997 OMX_U32 ret = keyFrameInterval / (BFramesSpacing + 1); 3998 return ret > 0 ? ret - 1 : 0; 3999 } 4000 4001 static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) { 4002 int32_t tmp; 4003 if (!msg->findInt32("bitrate-mode", &tmp)) { 4004 return OMX_Video_ControlRateVariable; 4005 } 4006 4007 return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp); 4008 } 4009 4010 status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) { 4011 int32_t bitrate; 4012 float iFrameInterval; 4013 if (!msg->findInt32("bitrate", &bitrate) 4014 || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) { 4015 return INVALID_OPERATION; 4016 } 4017 4018 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 4019 4020 float frameRate; 4021 if (!msg->findFloat("frame-rate", &frameRate)) { 4022 int32_t tmp; 4023 if (!msg->findInt32("frame-rate", &tmp)) { 4024 return INVALID_OPERATION; 4025 } 4026 frameRate = (float)tmp; 4027 } 4028 4029 OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type; 4030 InitOMXParams(&mpeg4type); 4031 mpeg4type.nPortIndex = kPortIndexOutput; 4032 4033 status_t err = mOMXNode->getParameter( 4034 OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 4035 4036 if (err != OK) { 4037 return err; 4038 } 4039 4040 mpeg4type.nSliceHeaderSpacing = 0; 4041 mpeg4type.bSVH = OMX_FALSE; 4042 mpeg4type.bGov = OMX_FALSE; 4043 4044 mpeg4type.nAllowedPictureTypes = 4045 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 4046 4047 mpeg4type.nBFrames = 0; 4048 mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, mpeg4type.nBFrames); 4049 if (mpeg4type.nPFrames == 0) { 4050 mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 4051 } 4052 mpeg4type.nIDCVLCThreshold = 0; 4053 mpeg4type.bACPred = OMX_TRUE; 4054 mpeg4type.nMaxPacketSize = 256; 4055 mpeg4type.nTimeIncRes = 1000; 4056 mpeg4type.nHeaderExtension = 0; 4057 mpeg4type.bReversibleVLC = OMX_FALSE; 4058 4059 int32_t profile; 4060 if (msg->findInt32("profile", &profile)) { 4061 int32_t level; 4062 if (!msg->findInt32("level", &level)) { 4063 return INVALID_OPERATION; 4064 } 4065 4066 err = verifySupportForProfileAndLevel(profile, level); 4067 4068 if (err != OK) { 4069 return err; 4070 } 4071 4072 mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile); 4073 mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level); 4074 } 4075 4076 err = mOMXNode->setParameter( 4077 OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 4078 4079 if (err != OK) { 4080 return err; 4081 } 4082 4083 err = configureBitrate(bitrate, bitrateMode); 4084 4085 if (err != OK) { 4086 return err; 4087 } 4088 4089 return setupErrorCorrectionParameters(); 4090 } 4091 4092 status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) { 4093 int32_t bitrate; 4094 float iFrameInterval; 4095 if (!msg->findInt32("bitrate", &bitrate) 4096 || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) { 4097 return INVALID_OPERATION; 4098 } 4099 4100 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 4101 4102 float frameRate; 4103 if (!msg->findFloat("frame-rate", &frameRate)) { 4104 int32_t tmp; 4105 if (!msg->findInt32("frame-rate", &tmp)) { 4106 return INVALID_OPERATION; 4107 } 4108 frameRate = (float)tmp; 4109 } 4110 4111 OMX_VIDEO_PARAM_H263TYPE h263type; 4112 InitOMXParams(&h263type); 4113 h263type.nPortIndex = kPortIndexOutput; 4114 4115 status_t err = mOMXNode->getParameter( 4116 OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 4117 4118 if (err != OK) { 4119 return err; 4120 } 4121 4122 h263type.nAllowedPictureTypes = 4123 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 4124 4125 h263type.nBFrames = 0; 4126 h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h263type.nBFrames); 4127 if (h263type.nPFrames == 0) { 4128 h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 4129 } 4130 4131 int32_t profile; 4132 if (msg->findInt32("profile", &profile)) { 4133 int32_t level; 4134 if (!msg->findInt32("level", &level)) { 4135 return INVALID_OPERATION; 4136 } 4137 4138 err = verifySupportForProfileAndLevel(profile, level); 4139 4140 if (err != OK) { 4141 return err; 4142 } 4143 4144 h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile); 4145 h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level); 4146 } 4147 4148 h263type.bPLUSPTYPEAllowed = OMX_FALSE; 4149 h263type.bForceRoundingTypeToZero = OMX_FALSE; 4150 h263type.nPictureHeaderRepetition = 0; 4151 h263type.nGOBHeaderInterval = 0; 4152 4153 err = mOMXNode->setParameter( 4154 OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 4155 4156 if (err != OK) { 4157 return err; 4158 } 4159 4160 err = configureBitrate(bitrate, bitrateMode); 4161 4162 if (err != OK) { 4163 return err; 4164 } 4165 4166 return setupErrorCorrectionParameters(); 4167 } 4168 4169 // static 4170 int /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor( 4171 int width, int height, int rate, int bitrate, 4172 OMX_VIDEO_AVCPROFILETYPE profile) { 4173 // convert bitrate to main/baseline profile kbps equivalent 4174 switch (profile) { 4175 case OMX_VIDEO_AVCProfileHigh10: 4176 bitrate = divUp(bitrate, 3000); break; 4177 case OMX_VIDEO_AVCProfileHigh: 4178 bitrate = divUp(bitrate, 1250); break; 4179 default: 4180 bitrate = divUp(bitrate, 1000); break; 4181 } 4182 4183 // convert size and rate to MBs 4184 width = divUp(width, 16); 4185 height = divUp(height, 16); 4186 int mbs = width * height; 4187 rate *= mbs; 4188 int maxDimension = max(width, height); 4189 4190 static const int limits[][5] = { 4191 /* MBps MB dim bitrate level */ 4192 { 1485, 99, 28, 64, OMX_VIDEO_AVCLevel1 }, 4193 { 1485, 99, 28, 128, OMX_VIDEO_AVCLevel1b }, 4194 { 3000, 396, 56, 192, OMX_VIDEO_AVCLevel11 }, 4195 { 6000, 396, 56, 384, OMX_VIDEO_AVCLevel12 }, 4196 { 11880, 396, 56, 768, OMX_VIDEO_AVCLevel13 }, 4197 { 11880, 396, 56, 2000, OMX_VIDEO_AVCLevel2 }, 4198 { 19800, 792, 79, 4000, OMX_VIDEO_AVCLevel21 }, 4199 { 20250, 1620, 113, 4000, OMX_VIDEO_AVCLevel22 }, 4200 { 40500, 1620, 113, 10000, OMX_VIDEO_AVCLevel3 }, 4201 { 108000, 3600, 169, 14000, OMX_VIDEO_AVCLevel31 }, 4202 { 216000, 5120, 202, 20000, OMX_VIDEO_AVCLevel32 }, 4203 { 245760, 8192, 256, 20000, OMX_VIDEO_AVCLevel4 }, 4204 { 245760, 8192, 256, 50000, OMX_VIDEO_AVCLevel41 }, 4205 { 522240, 8704, 263, 50000, OMX_VIDEO_AVCLevel42 }, 4206 { 589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5 }, 4207 { 983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 }, 4208 { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 }, 4209 }; 4210 4211 for (size_t i = 0; i < ARRAY_SIZE(limits); i++) { 4212 const int (&limit)[5] = limits[i]; 4213 if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2] 4214 && bitrate <= limit[3]) { 4215 return limit[4]; 4216 } 4217 } 4218 return 0; 4219 } 4220 4221 status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) { 4222 int32_t bitrate; 4223 float iFrameInterval; 4224 if (!msg->findInt32("bitrate", &bitrate) 4225 || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) { 4226 return INVALID_OPERATION; 4227 } 4228 4229 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 4230 4231 float frameRate; 4232 if (!msg->findFloat("frame-rate", &frameRate)) { 4233 int32_t tmp; 4234 if (!msg->findInt32("frame-rate", &tmp)) { 4235 return INVALID_OPERATION; 4236 } 4237 frameRate = (float)tmp; 4238 } 4239 4240 status_t err = OK; 4241 int32_t intraRefreshMode = 0; 4242 if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) { 4243 err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode); 4244 if (err != OK) { 4245 ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x", 4246 err, intraRefreshMode); 4247 return err; 4248 } 4249 } 4250 4251 OMX_VIDEO_PARAM_AVCTYPE h264type; 4252 InitOMXParams(&h264type); 4253 h264type.nPortIndex = kPortIndexOutput; 4254 4255 err = mOMXNode->getParameter( 4256 OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 4257 4258 if (err != OK) { 4259 return err; 4260 } 4261 4262 h264type.nAllowedPictureTypes = 4263 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 4264 4265 int32_t profile; 4266 if (msg->findInt32("profile", &profile)) { 4267 int32_t level; 4268 if (!msg->findInt32("level", &level)) { 4269 return INVALID_OPERATION; 4270 } 4271 4272 err = verifySupportForProfileAndLevel(profile, level); 4273 4274 if (err != OK) { 4275 return err; 4276 } 4277 4278 h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile); 4279 h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level); 4280 } else { 4281 h264type.eProfile = OMX_VIDEO_AVCProfileBaseline; 4282 #if 0 /* DON'T YET DEFAULT TO HIGHEST PROFILE */ 4283 // Use largest supported profile for AVC recording if profile is not specified. 4284 for (OMX_VIDEO_AVCPROFILETYPE profile : { 4285 OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCProfileMain }) { 4286 if (verifySupportForProfileAndLevel(profile, 0) == OK) { 4287 h264type.eProfile = profile; 4288 break; 4289 } 4290 } 4291 #endif 4292 } 4293 4294 ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]", 4295 asString(h264type.eProfile), asString(h264type.eLevel)); 4296 4297 if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) { 4298 h264type.nSliceHeaderSpacing = 0; 4299 h264type.bUseHadamard = OMX_TRUE; 4300 h264type.nRefFrames = 1; 4301 h264type.nBFrames = 0; 4302 h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames); 4303 if (h264type.nPFrames == 0) { 4304 h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 4305 } 4306 h264type.nRefIdx10ActiveMinus1 = 0; 4307 h264type.nRefIdx11ActiveMinus1 = 0; 4308 h264type.bEntropyCodingCABAC = OMX_FALSE; 4309 h264type.bWeightedPPrediction = OMX_FALSE; 4310 h264type.bconstIpred = OMX_FALSE; 4311 h264type.bDirect8x8Inference = OMX_FALSE; 4312 h264type.bDirectSpatialTemporal = OMX_FALSE; 4313 h264type.nCabacInitIdc = 0; 4314 } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain || 4315 h264type.eProfile == OMX_VIDEO_AVCProfileHigh) { 4316 h264type.nSliceHeaderSpacing = 0; 4317 h264type.bUseHadamard = OMX_TRUE; 4318 h264type.nRefFrames = 2; 4319 h264type.nBFrames = mLatency == 0 ? 1 : std::min(1U, mLatency - 1); 4320 h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames); 4321 h264type.nAllowedPictureTypes = 4322 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB; 4323 h264type.nRefIdx10ActiveMinus1 = 0; 4324 h264type.nRefIdx11ActiveMinus1 = 0; 4325 h264type.bEntropyCodingCABAC = OMX_TRUE; 4326 h264type.bWeightedPPrediction = OMX_TRUE; 4327 h264type.bconstIpred = OMX_TRUE; 4328 h264type.bDirect8x8Inference = OMX_TRUE; 4329 h264type.bDirectSpatialTemporal = OMX_TRUE; 4330 h264type.nCabacInitIdc = 1; 4331 } 4332 4333 if (h264type.nBFrames != 0) { 4334 h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; 4335 } 4336 4337 h264type.bEnableUEP = OMX_FALSE; 4338 h264type.bEnableFMO = OMX_FALSE; 4339 h264type.bEnableASO = OMX_FALSE; 4340 h264type.bEnableRS = OMX_FALSE; 4341 h264type.bFrameMBsOnly = OMX_TRUE; 4342 h264type.bMBAFF = OMX_FALSE; 4343 h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; 4344 4345 err = mOMXNode->setParameter( 4346 OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 4347 4348 if (err != OK) { 4349 return err; 4350 } 4351 4352 // TRICKY: if we are enabling temporal layering as well, some codecs may not support layering 4353 // when B-frames are enabled. Detect this now so we can disable B frames if temporal layering 4354 // is preferred. 4355 AString tsSchema; 4356 int32_t preferBFrames = (int32_t)false; 4357 if (msg->findString("ts-schema", &tsSchema) 4358 && (!msg->findInt32("android._prefer-b-frames", &preferBFrames) || !preferBFrames)) { 4359 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layering; 4360 InitOMXParams(&layering); 4361 layering.nPortIndex = kPortIndexOutput; 4362 if (mOMXNode->getParameter( 4363 (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering, 4364 &layering, sizeof(layering)) == OK 4365 && layering.eSupportedPatterns 4366 && layering.nBLayerCountMax == 0) { 4367 h264type.nBFrames = 0; 4368 h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames); 4369 h264type.nAllowedPictureTypes &= ~OMX_VIDEO_PictureTypeB; 4370 ALOGI("disabling B-frames"); 4371 err = mOMXNode->setParameter( 4372 OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 4373 4374 if (err != OK) { 4375 return err; 4376 } 4377 } 4378 } 4379 4380 return configureBitrate(bitrate, bitrateMode); 4381 } 4382 4383 status_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) { 4384 int32_t bitrate; 4385 float iFrameInterval; 4386 if (!msg->findInt32("bitrate", &bitrate) 4387 || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) { 4388 return INVALID_OPERATION; 4389 } 4390 4391 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 4392 4393 float frameRate; 4394 if (!msg->findFloat("frame-rate", &frameRate)) { 4395 int32_t tmp; 4396 if (!msg->findInt32("frame-rate", &tmp)) { 4397 return INVALID_OPERATION; 4398 } 4399 frameRate = (float)tmp; 4400 } 4401 4402 OMX_VIDEO_PARAM_HEVCTYPE hevcType; 4403 InitOMXParams(&hevcType); 4404 hevcType.nPortIndex = kPortIndexOutput; 4405 4406 status_t err = OK; 4407 err = mOMXNode->getParameter( 4408 (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType)); 4409 if (err != OK) { 4410 return err; 4411 } 4412 4413 int32_t profile; 4414 if (msg->findInt32("profile", &profile)) { 4415 int32_t level; 4416 if (!msg->findInt32("level", &level)) { 4417 return INVALID_OPERATION; 4418 } 4419 4420 err = verifySupportForProfileAndLevel(profile, level); 4421 if (err != OK) { 4422 return err; 4423 } 4424 4425 hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile); 4426 hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level); 4427 } 4428 // TODO: finer control? 4429 hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1; 4430 4431 err = mOMXNode->setParameter( 4432 (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType)); 4433 if (err != OK) { 4434 return err; 4435 } 4436 4437 return configureBitrate(bitrate, bitrateMode); 4438 } 4439 4440 status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat) { 4441 int32_t bitrate; 4442 float iFrameInterval = 0; 4443 size_t tsLayers = 0; 4444 OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern = 4445 OMX_VIDEO_VPXTemporalLayerPatternNone; 4446 static const uint32_t kVp8LayerRateAlloction 4447 [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] 4448 [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = { 4449 {100, 100, 100}, // 1 layer 4450 { 60, 100, 100}, // 2 layers {60%, 40%} 4451 { 40, 60, 100}, // 3 layers {40%, 20%, 40%} 4452 }; 4453 if (!msg->findInt32("bitrate", &bitrate)) { 4454 return INVALID_OPERATION; 4455 } 4456 msg->findAsFloat("i-frame-interval", &iFrameInterval); 4457 4458 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 4459 4460 float frameRate; 4461 if (!msg->findFloat("frame-rate", &frameRate)) { 4462 int32_t tmp; 4463 if (!msg->findInt32("frame-rate", &tmp)) { 4464 return INVALID_OPERATION; 4465 } 4466 frameRate = (float)tmp; 4467 } 4468 4469 AString tsSchema; 4470 OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE tsType = 4471 OMX_VIDEO_AndroidTemporalLayeringPatternNone; 4472 4473 if (msg->findString("ts-schema", &tsSchema)) { 4474 unsigned int numLayers = 0; 4475 unsigned int numBLayers = 0; 4476 int tags; 4477 char dummy; 4478 if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1 4479 && numLayers > 0) { 4480 pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 4481 tsType = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC; 4482 tsLayers = numLayers; 4483 } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c", 4484 &numLayers, &dummy, &numBLayers, &dummy)) 4485 && (tags == 1 || (tags == 3 && dummy == '+')) 4486 && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) { 4487 pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 4488 // VPX does not have a concept of B-frames, so just count all layers 4489 tsType = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid; 4490 tsLayers = numLayers + numBLayers; 4491 } else { 4492 ALOGW("Ignoring unsupported ts-schema [%s]", tsSchema.c_str()); 4493 } 4494 tsLayers = min(tsLayers, (size_t)OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS); 4495 } 4496 4497 OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; 4498 InitOMXParams(&vp8type); 4499 vp8type.nPortIndex = kPortIndexOutput; 4500 status_t err = mOMXNode->getParameter( 4501 (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 4502 &vp8type, sizeof(vp8type)); 4503 4504 if (err == OK) { 4505 if (iFrameInterval > 0) { 4506 vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1; 4507 } 4508 vp8type.eTemporalPattern = pattern; 4509 vp8type.nTemporalLayerCount = tsLayers; 4510 if (tsLayers > 0) { 4511 for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) { 4512 vp8type.nTemporalLayerBitrateRatio[i] = 4513 kVp8LayerRateAlloction[tsLayers - 1][i]; 4514 } 4515 } 4516 if (bitrateMode == OMX_Video_ControlRateConstant) { 4517 vp8type.nMinQuantizer = 2; 4518 vp8type.nMaxQuantizer = 63; 4519 } 4520 4521 err = mOMXNode->setParameter( 4522 (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 4523 &vp8type, sizeof(vp8type)); 4524 if (err != OK) { 4525 ALOGW("Extended VP8 parameters set failed: %d", err); 4526 } else if (tsType == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) { 4527 // advertise even single layer WebRTC layering, as it is defined 4528 outputFormat->setString("ts-schema", AStringPrintf("webrtc.vp8.%u-layer", tsLayers)); 4529 } else if (tsLayers > 0) { 4530 // tsType == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid 4531 outputFormat->setString("ts-schema", AStringPrintf("android.generic.%u", tsLayers)); 4532 } 4533 } 4534 4535 return configureBitrate(bitrate, bitrateMode); 4536 } 4537 4538 status_t ACodec::verifySupportForProfileAndLevel( 4539 int32_t profile, int32_t level) { 4540 OMX_VIDEO_PARAM_PROFILELEVELTYPE params; 4541 InitOMXParams(¶ms); 4542 params.nPortIndex = kPortIndexOutput; 4543 4544 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 4545 params.nProfileIndex = index; 4546 status_t err = mOMXNode->getParameter( 4547 OMX_IndexParamVideoProfileLevelQuerySupported, 4548 ¶ms, sizeof(params)); 4549 4550 if (err != OK) { 4551 return err; 4552 } 4553 4554 int32_t supportedProfile = static_cast<int32_t>(params.eProfile); 4555 int32_t supportedLevel = static_cast<int32_t>(params.eLevel); 4556 4557 if (profile == supportedProfile && level <= supportedLevel) { 4558 return OK; 4559 } 4560 4561 if (index == kMaxIndicesToCheck) { 4562 ALOGW("[%s] stopping checking profiles after %u: %x/%x", 4563 mComponentName.c_str(), index, 4564 params.eProfile, params.eLevel); 4565 } 4566 } 4567 return ERROR_UNSUPPORTED; 4568 } 4569 4570 status_t ACodec::configureBitrate( 4571 int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) { 4572 OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 4573 InitOMXParams(&bitrateType); 4574 bitrateType.nPortIndex = kPortIndexOutput; 4575 4576 status_t err = mOMXNode->getParameter( 4577 OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType)); 4578 4579 if (err != OK) { 4580 return err; 4581 } 4582 4583 bitrateType.eControlRate = bitrateMode; 4584 bitrateType.nTargetBitrate = bitrate; 4585 4586 return mOMXNode->setParameter( 4587 OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType)); 4588 } 4589 4590 void ACodec::configureEncoderLatency(const sp<AMessage> &msg) { 4591 if (!mIsEncoder || !mIsVideo) { 4592 return; 4593 } 4594 4595 int32_t latency = 0, bitrateMode; 4596 if (msg->findInt32("latency", &latency) && latency > 0) { 4597 status_t err = setLatency(latency); 4598 if (err != OK) { 4599 ALOGW("[%s] failed setLatency. Failure is fine since this key is optional", 4600 mComponentName.c_str()); 4601 err = OK; 4602 } else { 4603 mLatency = latency; 4604 } 4605 } else if ((!msg->findInt32("bitrate-mode", &bitrateMode) && 4606 bitrateMode == OMX_Video_ControlRateConstant)) { 4607 // default the latency to be 1 if latency key is not specified or unsupported and bitrateMode 4608 // is CBR. 4609 mLatency = 1; 4610 } 4611 } 4612 4613 status_t ACodec::setupErrorCorrectionParameters() { 4614 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; 4615 InitOMXParams(&errorCorrectionType); 4616 errorCorrectionType.nPortIndex = kPortIndexOutput; 4617 4618 status_t err = mOMXNode->getParameter( 4619 OMX_IndexParamVideoErrorCorrection, 4620 &errorCorrectionType, sizeof(errorCorrectionType)); 4621 4622 if (err != OK) { 4623 return OK; // Optional feature. Ignore this failure 4624 } 4625 4626 errorCorrectionType.bEnableHEC = OMX_FALSE; 4627 errorCorrectionType.bEnableResync = OMX_TRUE; 4628 errorCorrectionType.nResynchMarkerSpacing = 256; 4629 errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; 4630 errorCorrectionType.bEnableRVLC = OMX_FALSE; 4631 4632 return mOMXNode->setParameter( 4633 OMX_IndexParamVideoErrorCorrection, 4634 &errorCorrectionType, sizeof(errorCorrectionType)); 4635 } 4636 4637 status_t ACodec::setVideoFormatOnPort( 4638 OMX_U32 portIndex, 4639 int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat, 4640 float frameRate) { 4641 OMX_PARAM_PORTDEFINITIONTYPE def; 4642 InitOMXParams(&def); 4643 def.nPortIndex = portIndex; 4644 4645 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 4646 4647 status_t err = mOMXNode->getParameter( 4648 OMX_IndexParamPortDefinition, &def, sizeof(def)); 4649 if (err != OK) { 4650 return err; 4651 } 4652 4653 if (portIndex == kPortIndexInput) { 4654 // XXX Need a (much) better heuristic to compute input buffer sizes. 4655 const size_t X = 64 * 1024; 4656 if (def.nBufferSize < X) { 4657 def.nBufferSize = X; 4658 } 4659 } 4660 4661 if (def.eDomain != OMX_PortDomainVideo) { 4662 ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain); 4663 return FAILED_TRANSACTION; 4664 } 4665 4666 video_def->nFrameWidth = width; 4667 video_def->nFrameHeight = height; 4668 4669 if (portIndex == kPortIndexInput) { 4670 video_def->eCompressionFormat = compressionFormat; 4671 video_def->eColorFormat = OMX_COLOR_FormatUnused; 4672 if (frameRate >= 0) { 4673 video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f); 4674 } 4675 } 4676 4677 err = mOMXNode->setParameter( 4678 OMX_IndexParamPortDefinition, &def, sizeof(def)); 4679 4680 return err; 4681 } 4682 4683 size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const { 4684 size_t n = 0; 4685 4686 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 4687 const BufferInfo &info = mBuffers[portIndex].itemAt(i); 4688 4689 if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) { 4690 ++n; 4691 } 4692 } 4693 4694 return n; 4695 } 4696 4697 size_t ACodec::countBuffersOwnedByNativeWindow() const { 4698 size_t n = 0; 4699 4700 for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) { 4701 const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i); 4702 4703 if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 4704 ++n; 4705 } 4706 } 4707 4708 return n; 4709 } 4710 4711 void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() { 4712 if (mNativeWindow == NULL) { 4713 return; 4714 } 4715 4716 while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers 4717 && dequeueBufferFromNativeWindow() != NULL) { 4718 // these buffers will be submitted as regular buffers; account for this 4719 if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) { 4720 --mMetadataBuffersToSubmit; 4721 } 4722 } 4723 } 4724 4725 bool ACodec::allYourBuffersAreBelongToUs( 4726 OMX_U32 portIndex) { 4727 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 4728 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 4729 4730 if (info->mStatus != BufferInfo::OWNED_BY_US 4731 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 4732 ALOGV("[%s] Buffer %u on port %u still has status %d", 4733 mComponentName.c_str(), 4734 info->mBufferID, portIndex, info->mStatus); 4735 return false; 4736 } 4737 } 4738 4739 return true; 4740 } 4741 4742 bool ACodec::allYourBuffersAreBelongToUs() { 4743 return allYourBuffersAreBelongToUs(kPortIndexInput) 4744 && allYourBuffersAreBelongToUs(kPortIndexOutput); 4745 } 4746 4747 void ACodec::deferMessage(const sp<AMessage> &msg) { 4748 mDeferredQueue.push_back(msg); 4749 } 4750 4751 void ACodec::processDeferredMessages() { 4752 List<sp<AMessage> > queue = mDeferredQueue; 4753 mDeferredQueue.clear(); 4754 4755 List<sp<AMessage> >::iterator it = queue.begin(); 4756 while (it != queue.end()) { 4757 onMessageReceived(*it++); 4758 } 4759 } 4760 4761 status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) { 4762 const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output"; 4763 OMX_PARAM_PORTDEFINITIONTYPE def; 4764 InitOMXParams(&def); 4765 def.nPortIndex = portIndex; 4766 4767 status_t err = mOMXNode->getParameter(OMX_IndexParamPortDefinition, &def, sizeof(def)); 4768 if (err != OK) { 4769 return err; 4770 } 4771 4772 if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) { 4773 ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex); 4774 return BAD_VALUE; 4775 } 4776 4777 switch (def.eDomain) { 4778 case OMX_PortDomainVideo: 4779 { 4780 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 4781 switch ((int)videoDef->eCompressionFormat) { 4782 case OMX_VIDEO_CodingUnused: 4783 { 4784 CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput)); 4785 notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW); 4786 4787 notify->setInt32("stride", videoDef->nStride); 4788 notify->setInt32("slice-height", videoDef->nSliceHeight); 4789 notify->setInt32("color-format", videoDef->eColorFormat); 4790 4791 if (mNativeWindow == NULL) { 4792 DescribeColorFormat2Params describeParams; 4793 InitOMXParams(&describeParams); 4794 describeParams.eColorFormat = videoDef->eColorFormat; 4795 describeParams.nFrameWidth = videoDef->nFrameWidth; 4796 describeParams.nFrameHeight = videoDef->nFrameHeight; 4797 describeParams.nStride = videoDef->nStride; 4798 describeParams.nSliceHeight = videoDef->nSliceHeight; 4799 describeParams.bUsingNativeBuffers = OMX_FALSE; 4800 4801 if (DescribeColorFormat(mOMXNode, describeParams)) { 4802 notify->setBuffer( 4803 "image-data", 4804 ABuffer::CreateAsCopy( 4805 &describeParams.sMediaImage, 4806 sizeof(describeParams.sMediaImage))); 4807 4808 MediaImage2 &img = describeParams.sMediaImage; 4809 MediaImage2::PlaneInfo *plane = img.mPlane; 4810 ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }", 4811 mComponentName.c_str(), img.mWidth, img.mHeight, 4812 plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc, 4813 plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc, 4814 plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc); 4815 } 4816 } 4817 4818 int32_t width = (int32_t)videoDef->nFrameWidth; 4819 int32_t height = (int32_t)videoDef->nFrameHeight; 4820 4821 if (portIndex == kPortIndexOutput) { 4822 OMX_CONFIG_RECTTYPE rect; 4823 InitOMXParams(&rect); 4824 rect.nPortIndex = portIndex; 4825 4826 if (mOMXNode->getConfig( 4827 (portIndex == kPortIndexOutput ? 4828 OMX_IndexConfigCommonOutputCrop : 4829 OMX_IndexConfigCommonInputCrop), 4830 &rect, sizeof(rect)) != OK) { 4831 rect.nLeft = 0; 4832 rect.nTop = 0; 4833 rect.nWidth = videoDef->nFrameWidth; 4834 rect.nHeight = videoDef->nFrameHeight; 4835 } 4836 4837 if (rect.nLeft < 0 || 4838 rect.nTop < 0 || 4839 rect.nLeft + rect.nWidth > videoDef->nFrameWidth || 4840 rect.nTop + rect.nHeight > videoDef->nFrameHeight) { 4841 ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)", 4842 rect.nLeft, rect.nTop, 4843 rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight, 4844 videoDef->nFrameWidth, videoDef->nFrameHeight); 4845 return BAD_VALUE; 4846 } 4847 4848 notify->setRect( 4849 "crop", 4850 rect.nLeft, 4851 rect.nTop, 4852 rect.nLeft + rect.nWidth - 1, 4853 rect.nTop + rect.nHeight - 1); 4854 4855 width = rect.nWidth; 4856 height = rect.nHeight; 4857 4858 android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN; 4859 (void)getColorAspectsAndDataSpaceForVideoDecoder( 4860 width, height, mConfigFormat, notify, 4861 mUsingNativeWindow ? &dataSpace : NULL); 4862 if (mUsingNativeWindow) { 4863 notify->setInt32("android._dataspace", dataSpace); 4864 } 4865 (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify); 4866 } else { 4867 (void)getInputColorAspectsForVideoEncoder(notify); 4868 if (mConfigFormat->contains("hdr-static-info")) { 4869 (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify); 4870 } 4871 uint32_t latency = 0; 4872 if (mIsEncoder && getLatency(&latency) == OK && latency > 0) { 4873 notify->setInt32("latency", latency); 4874 } 4875 } 4876 4877 break; 4878 } 4879 4880 case OMX_VIDEO_CodingVP8: 4881 case OMX_VIDEO_CodingVP9: 4882 { 4883 OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; 4884 InitOMXParams(&vp8type); 4885 vp8type.nPortIndex = kPortIndexOutput; 4886 status_t err = mOMXNode->getParameter( 4887 (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 4888 &vp8type, 4889 sizeof(vp8type)); 4890 4891 if (err == OK) { 4892 if (vp8type.eTemporalPattern == OMX_VIDEO_VPXTemporalLayerPatternWebRTC 4893 && vp8type.nTemporalLayerCount > 0 4894 && vp8type.nTemporalLayerCount 4895 <= OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS) { 4896 // advertise as android.generic if we configured for android.generic 4897 AString origSchema; 4898 if (notify->findString("ts-schema", &origSchema) 4899 && origSchema.startsWith("android.generic")) { 4900 notify->setString("ts-schema", AStringPrintf( 4901 "android.generic.%u", vp8type.nTemporalLayerCount)); 4902 } else { 4903 notify->setString("ts-schema", AStringPrintf( 4904 "webrtc.vp8.%u-layer", vp8type.nTemporalLayerCount)); 4905 } 4906 } 4907 } 4908 // Fall through to set up mime. 4909 } 4910 4911 default: 4912 { 4913 if (mIsEncoder ^ (portIndex == kPortIndexOutput)) { 4914 // should be CodingUnused 4915 ALOGE("Raw port video compression format is %s(%d)", 4916 asString(videoDef->eCompressionFormat), 4917 videoDef->eCompressionFormat); 4918 return BAD_VALUE; 4919 } 4920 AString mime; 4921 if (GetMimeTypeForVideoCoding( 4922 videoDef->eCompressionFormat, &mime) != OK) { 4923 notify->setString("mime", "application/octet-stream"); 4924 } else { 4925 notify->setString("mime", mime.c_str()); 4926 } 4927 uint32_t intraRefreshPeriod = 0; 4928 if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK 4929 && intraRefreshPeriod > 0) { 4930 notify->setInt32("intra-refresh-period", intraRefreshPeriod); 4931 } 4932 break; 4933 } 4934 } 4935 notify->setInt32("width", videoDef->nFrameWidth); 4936 notify->setInt32("height", videoDef->nFrameHeight); 4937 ALOGV("[%s] %s format is %s", mComponentName.c_str(), 4938 portIndex == kPortIndexInput ? "input" : "output", 4939 notify->debugString().c_str()); 4940 4941 break; 4942 } 4943 4944 case OMX_PortDomainAudio: 4945 { 4946 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 4947 4948 switch ((int)audioDef->eEncoding) { 4949 case OMX_AUDIO_CodingPCM: 4950 { 4951 OMX_AUDIO_PARAM_PCMMODETYPE params; 4952 InitOMXParams(¶ms); 4953 params.nPortIndex = portIndex; 4954 4955 err = mOMXNode->getParameter( 4956 OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4957 if (err != OK) { 4958 return err; 4959 } 4960 4961 if (params.nChannels <= 0 4962 || (params.nChannels != 1 && !params.bInterleaved) 4963 || params.ePCMMode != OMX_AUDIO_PCMModeLinear) { 4964 ALOGE("unsupported PCM port: %u channels%s, %u-bit", 4965 params.nChannels, 4966 params.bInterleaved ? " interleaved" : "", 4967 params.nBitPerSample); 4968 return FAILED_TRANSACTION; 4969 } 4970 4971 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW); 4972 notify->setInt32("channel-count", params.nChannels); 4973 notify->setInt32("sample-rate", params.nSamplingRate); 4974 4975 AudioEncoding encoding = kAudioEncodingPcm16bit; 4976 if (params.eNumData == OMX_NumericalDataUnsigned 4977 && params.nBitPerSample == 8u) { 4978 encoding = kAudioEncodingPcm8bit; 4979 } else if (params.eNumData == OMX_NumericalDataFloat 4980 && params.nBitPerSample == 32u) { 4981 encoding = kAudioEncodingPcmFloat; 4982 } else if (params.nBitPerSample != 16u 4983 || params.eNumData != OMX_NumericalDataSigned) { 4984 ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ", 4985 asString(params.eNumData), params.eNumData, 4986 asString(params.ePCMMode), params.ePCMMode); 4987 return FAILED_TRANSACTION; 4988 } 4989 notify->setInt32("pcm-encoding", encoding); 4990 4991 if (mChannelMaskPresent) { 4992 notify->setInt32("channel-mask", mChannelMask); 4993 } 4994 break; 4995 } 4996 4997 case OMX_AUDIO_CodingAAC: 4998 { 4999 OMX_AUDIO_PARAM_AACPROFILETYPE params; 5000 InitOMXParams(¶ms); 5001 params.nPortIndex = portIndex; 5002 5003 err = mOMXNode->getParameter( 5004 OMX_IndexParamAudioAac, ¶ms, sizeof(params)); 5005 if (err != OK) { 5006 return err; 5007 } 5008 5009 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 5010 notify->setInt32("channel-count", params.nChannels); 5011 notify->setInt32("sample-rate", params.nSampleRate); 5012 break; 5013 } 5014 5015 case OMX_AUDIO_CodingAMR: 5016 { 5017 OMX_AUDIO_PARAM_AMRTYPE params; 5018 InitOMXParams(¶ms); 5019 params.nPortIndex = portIndex; 5020 5021 err = mOMXNode->getParameter( 5022 OMX_IndexParamAudioAmr, ¶ms, sizeof(params)); 5023 if (err != OK) { 5024 return err; 5025 } 5026 5027 notify->setInt32("channel-count", 1); 5028 if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) { 5029 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB); 5030 notify->setInt32("sample-rate", 16000); 5031 } else { 5032 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB); 5033 notify->setInt32("sample-rate", 8000); 5034 } 5035 break; 5036 } 5037 5038 case OMX_AUDIO_CodingFLAC: 5039 { 5040 OMX_AUDIO_PARAM_FLACTYPE params; 5041 InitOMXParams(¶ms); 5042 params.nPortIndex = portIndex; 5043 5044 err = mOMXNode->getParameter( 5045 OMX_IndexParamAudioFlac, ¶ms, sizeof(params)); 5046 if (err != OK) { 5047 return err; 5048 } 5049 5050 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC); 5051 notify->setInt32("channel-count", params.nChannels); 5052 notify->setInt32("sample-rate", params.nSampleRate); 5053 break; 5054 } 5055 5056 case OMX_AUDIO_CodingMP3: 5057 { 5058 OMX_AUDIO_PARAM_MP3TYPE params; 5059 InitOMXParams(¶ms); 5060 params.nPortIndex = portIndex; 5061 5062 err = mOMXNode->getParameter( 5063 OMX_IndexParamAudioMp3, ¶ms, sizeof(params)); 5064 if (err != OK) { 5065 return err; 5066 } 5067 5068 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG); 5069 notify->setInt32("channel-count", params.nChannels); 5070 notify->setInt32("sample-rate", params.nSampleRate); 5071 break; 5072 } 5073 5074 case OMX_AUDIO_CodingVORBIS: 5075 { 5076 OMX_AUDIO_PARAM_VORBISTYPE params; 5077 InitOMXParams(¶ms); 5078 params.nPortIndex = portIndex; 5079 5080 err = mOMXNode->getParameter( 5081 OMX_IndexParamAudioVorbis, ¶ms, sizeof(params)); 5082 if (err != OK) { 5083 return err; 5084 } 5085 5086 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS); 5087 notify->setInt32("channel-count", params.nChannels); 5088 notify->setInt32("sample-rate", params.nSampleRate); 5089 break; 5090 } 5091 5092 case OMX_AUDIO_CodingAndroidAC3: 5093 { 5094 OMX_AUDIO_PARAM_ANDROID_AC3TYPE params; 5095 InitOMXParams(¶ms); 5096 params.nPortIndex = portIndex; 5097 5098 err = mOMXNode->getParameter( 5099 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 5100 ¶ms, sizeof(params)); 5101 if (err != OK) { 5102 return err; 5103 } 5104 5105 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3); 5106 notify->setInt32("channel-count", params.nChannels); 5107 notify->setInt32("sample-rate", params.nSampleRate); 5108 break; 5109 } 5110 5111 case OMX_AUDIO_CodingAndroidEAC3: 5112 { 5113 OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params; 5114 InitOMXParams(¶ms); 5115 params.nPortIndex = portIndex; 5116 5117 err = mOMXNode->getParameter( 5118 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, 5119 ¶ms, sizeof(params)); 5120 if (err != OK) { 5121 return err; 5122 } 5123 5124 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3); 5125 notify->setInt32("channel-count", params.nChannels); 5126 notify->setInt32("sample-rate", params.nSampleRate); 5127 break; 5128 } 5129 5130 case OMX_AUDIO_CodingAndroidOPUS: 5131 { 5132 OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params; 5133 InitOMXParams(¶ms); 5134 params.nPortIndex = portIndex; 5135 5136 err = mOMXNode->getParameter( 5137 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, 5138 ¶ms, sizeof(params)); 5139 if (err != OK) { 5140 return err; 5141 } 5142 5143 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS); 5144 notify->setInt32("channel-count", params.nChannels); 5145 notify->setInt32("sample-rate", params.nSampleRate); 5146 break; 5147 } 5148 5149 case OMX_AUDIO_CodingG711: 5150 { 5151 OMX_AUDIO_PARAM_PCMMODETYPE params; 5152 InitOMXParams(¶ms); 5153 params.nPortIndex = portIndex; 5154 5155 err = mOMXNode->getParameter( 5156 (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 5157 if (err != OK) { 5158 return err; 5159 } 5160 5161 const char *mime = NULL; 5162 if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) { 5163 mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW; 5164 } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) { 5165 mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW; 5166 } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear 5167 mime = MEDIA_MIMETYPE_AUDIO_RAW; 5168 } 5169 notify->setString("mime", mime); 5170 notify->setInt32("channel-count", params.nChannels); 5171 notify->setInt32("sample-rate", params.nSamplingRate); 5172 notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit); 5173 break; 5174 } 5175 5176 case OMX_AUDIO_CodingGSMFR: 5177 { 5178 OMX_AUDIO_PARAM_PCMMODETYPE params; 5179 InitOMXParams(¶ms); 5180 params.nPortIndex = portIndex; 5181 5182 err = mOMXNode->getParameter( 5183 OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 5184 if (err != OK) { 5185 return err; 5186 } 5187 5188 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM); 5189 notify->setInt32("channel-count", params.nChannels); 5190 notify->setInt32("sample-rate", params.nSamplingRate); 5191 break; 5192 } 5193 5194 default: 5195 ALOGE("Unsupported audio coding: %s(%d)\n", 5196 asString(audioDef->eEncoding), audioDef->eEncoding); 5197 return BAD_TYPE; 5198 } 5199 break; 5200 } 5201 5202 default: 5203 ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain); 5204 return BAD_TYPE; 5205 } 5206 5207 return getVendorParameters(portIndex, notify); 5208 } 5209 5210 void ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) { 5211 // aspects are normally communicated in ColorAspects 5212 int32_t range, standard, transfer; 5213 convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer); 5214 5215 // if some aspects are unspecified, use dataspace fields 5216 if (range != 0) { 5217 range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT; 5218 } 5219 if (standard != 0) { 5220 standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT; 5221 } 5222 if (transfer != 0) { 5223 transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT; 5224 } 5225 5226 mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event 5227 if (range != 0) { 5228 mOutputFormat->setInt32("color-range", range); 5229 } 5230 if (standard != 0) { 5231 mOutputFormat->setInt32("color-standard", standard); 5232 } 5233 if (transfer != 0) { 5234 mOutputFormat->setInt32("color-transfer", transfer); 5235 } 5236 5237 ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) " 5238 "(R:%d(%s), S:%d(%s), T:%d(%s))", 5239 dataSpace, 5240 aspects.mRange, asString(aspects.mRange), 5241 aspects.mPrimaries, asString(aspects.mPrimaries), 5242 aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs), 5243 aspects.mTransfer, asString(aspects.mTransfer), 5244 range, asString((ColorRange)range), 5245 standard, asString((ColorStandard)standard), 5246 transfer, asString((ColorTransfer)transfer)); 5247 } 5248 5249 void ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) { 5250 // store new output format, at the same time mark that this is no longer the first frame 5251 mOutputFormat = mBaseOutputFormat->dup(); 5252 5253 if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) { 5254 ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str()); 5255 return; 5256 } 5257 5258 if (expectedFormat != NULL) { 5259 sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat); 5260 sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat); 5261 if (changes->countEntries() != 0 || to->countEntries() != 0) { 5262 ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s", 5263 mComponentName.c_str(), 5264 changes->debugString(4).c_str(), to->debugString(4).c_str()); 5265 } 5266 } 5267 5268 if (!mIsVideo && !mIsEncoder) { 5269 AudioEncoding pcmEncoding = kAudioEncodingPcm16bit; 5270 (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding); 5271 AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit; 5272 (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding); 5273 5274 mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding); 5275 if (mConverter[kPortIndexOutput] != NULL) { 5276 mOutputFormat->setInt32("pcm-encoding", pcmEncoding); 5277 } 5278 } 5279 5280 if (mTunneled) { 5281 sendFormatChange(); 5282 } 5283 } 5284 5285 void ACodec::sendFormatChange() { 5286 AString mime; 5287 CHECK(mOutputFormat->findString("mime", &mime)); 5288 5289 if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) { 5290 int32_t channelCount, sampleRate; 5291 CHECK(mOutputFormat->findInt32("channel-count", &channelCount)); 5292 CHECK(mOutputFormat->findInt32("sample-rate", &sampleRate)); 5293 if (mSampleRate != 0 && sampleRate != 0) { 5294 mEncoderDelay = mEncoderDelay * sampleRate / mSampleRate; 5295 mEncoderPadding = mEncoderPadding * sampleRate / mSampleRate; 5296 mSampleRate = sampleRate; 5297 } 5298 if (mSkipCutBuffer != NULL) { 5299 size_t prevbufsize = mSkipCutBuffer->size(); 5300 if (prevbufsize != 0) { 5301 ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize); 5302 } 5303 } 5304 mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount); 5305 } 5306 5307 // mLastOutputFormat is not used when tunneled; doing this just to stay consistent 5308 mLastOutputFormat = mOutputFormat; 5309 } 5310 5311 void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) { 5312 ALOGE("signalError(omxError %#x, internalError %d)", error, internalError); 5313 5314 if (internalError == UNKNOWN_ERROR) { // find better error code 5315 const status_t omxStatus = statusFromOMXError(error); 5316 if (omxStatus != 0) { 5317 internalError = omxStatus; 5318 } else { 5319 ALOGW("Invalid OMX error %#x", error); 5320 } 5321 } 5322 5323 mFatalError = true; 5324 mCallback->onError(internalError, ACTION_CODE_FATAL); 5325 } 5326 5327 status_t ACodec::requestIDRFrame() { 5328 if (!mIsEncoder) { 5329 return ERROR_UNSUPPORTED; 5330 } 5331 5332 OMX_CONFIG_INTRAREFRESHVOPTYPE params; 5333 InitOMXParams(¶ms); 5334 5335 params.nPortIndex = kPortIndexOutput; 5336 params.IntraRefreshVOP = OMX_TRUE; 5337 5338 return mOMXNode->setConfig( 5339 OMX_IndexConfigVideoIntraVOPRefresh, 5340 ¶ms, 5341 sizeof(params)); 5342 } 5343 5344 //////////////////////////////////////////////////////////////////////////////// 5345 5346 ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState) 5347 : AState(parentState), 5348 mCodec(codec) { 5349 } 5350 5351 ACodec::BaseState::PortMode ACodec::BaseState::getPortMode( 5352 OMX_U32 /* portIndex */) { 5353 return KEEP_BUFFERS; 5354 } 5355 5356 void ACodec::BaseState::stateExited() { 5357 ++mCodec->mStateGeneration; 5358 } 5359 5360 bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { 5361 switch (msg->what()) { 5362 case kWhatInputBufferFilled: 5363 { 5364 onInputBufferFilled(msg); 5365 break; 5366 } 5367 5368 case kWhatOutputBufferDrained: 5369 { 5370 onOutputBufferDrained(msg); 5371 break; 5372 } 5373 5374 case ACodec::kWhatOMXMessageList: 5375 { 5376 return checkOMXMessage(msg) ? onOMXMessageList(msg) : true; 5377 } 5378 5379 case ACodec::kWhatOMXMessageItem: 5380 { 5381 // no need to check as we already did it for kWhatOMXMessageList 5382 return onOMXMessage(msg); 5383 } 5384 5385 case ACodec::kWhatOMXMessage: 5386 { 5387 return checkOMXMessage(msg) ? onOMXMessage(msg) : true; 5388 } 5389 5390 case ACodec::kWhatSetSurface: 5391 { 5392 sp<AReplyToken> replyID; 5393 CHECK(msg->senderAwaitsResponse(&replyID)); 5394 5395 sp<RefBase> obj; 5396 CHECK(msg->findObject("surface", &obj)); 5397 5398 status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get())); 5399 5400 sp<AMessage> response = new AMessage; 5401 response->setInt32("err", err); 5402 response->postReply(replyID); 5403 break; 5404 } 5405 5406 case ACodec::kWhatCreateInputSurface: 5407 case ACodec::kWhatSetInputSurface: 5408 case ACodec::kWhatSignalEndOfInputStream: 5409 { 5410 // This may result in an app illegal state exception. 5411 ALOGE("Message 0x%x was not handled", msg->what()); 5412 mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION); 5413 return true; 5414 } 5415 5416 case ACodec::kWhatOMXDied: 5417 { 5418 // This will result in kFlagSawMediaServerDie handling in MediaCodec. 5419 ALOGE("OMX/mediaserver died, signalling error!"); 5420 mCodec->mGraphicBufferSource.clear(); 5421 mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT); 5422 break; 5423 } 5424 5425 case ACodec::kWhatReleaseCodecInstance: 5426 { 5427 ALOGI("[%s] forcing the release of codec", 5428 mCodec->mComponentName.c_str()); 5429 status_t err = mCodec->mOMXNode->freeNode(); 5430 ALOGE_IF("[%s] failed to release codec instance: err=%d", 5431 mCodec->mComponentName.c_str(), err); 5432 mCodec->mCallback->onReleaseCompleted(); 5433 5434 mCodec->changeState(mCodec->mUninitializedState); 5435 break; 5436 } 5437 5438 case ACodec::kWhatForceStateTransition: 5439 { 5440 ALOGV("Already transitioned --- ignore"); 5441 break; 5442 } 5443 5444 default: 5445 return false; 5446 } 5447 5448 return true; 5449 } 5450 5451 bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) { 5452 // there is a possibility that this is an outstanding message for a 5453 // codec that we have already destroyed 5454 if (mCodec->mOMXNode == NULL) { 5455 ALOGI("ignoring message as already freed component: %s", 5456 msg->debugString().c_str()); 5457 return false; 5458 } 5459 5460 int32_t generation; 5461 CHECK(msg->findInt32("generation", (int32_t*)&generation)); 5462 if (generation != mCodec->mNodeGeneration) { 5463 ALOGW("Unexpected message for component: %s, gen %u, cur %u", 5464 msg->debugString().c_str(), generation, mCodec->mNodeGeneration); 5465 return false; 5466 } 5467 return true; 5468 } 5469 5470 bool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) { 5471 sp<RefBase> obj; 5472 CHECK(msg->findObject("messages", &obj)); 5473 sp<MessageList> msgList = static_cast<MessageList *>(obj.get()); 5474 5475 bool receivedRenderedEvents = false; 5476 for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin(); 5477 it != msgList->getList().cend(); ++it) { 5478 (*it)->setWhat(ACodec::kWhatOMXMessageItem); 5479 mCodec->handleMessage(*it); 5480 int32_t type; 5481 CHECK((*it)->findInt32("type", &type)); 5482 if (type == omx_message::FRAME_RENDERED) { 5483 receivedRenderedEvents = true; 5484 } 5485 } 5486 5487 if (receivedRenderedEvents) { 5488 // NOTE: all buffers are rendered in this case 5489 mCodec->notifyOfRenderedFrames(); 5490 } 5491 return true; 5492 } 5493 5494 bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { 5495 int32_t type; 5496 CHECK(msg->findInt32("type", &type)); 5497 5498 switch (type) { 5499 case omx_message::EVENT: 5500 { 5501 int32_t event, data1, data2; 5502 CHECK(msg->findInt32("event", &event)); 5503 CHECK(msg->findInt32("data1", &data1)); 5504 CHECK(msg->findInt32("data2", &data2)); 5505 5506 if (event == OMX_EventCmdComplete 5507 && data1 == OMX_CommandFlush 5508 && data2 == (int32_t)OMX_ALL) { 5509 // Use of this notification is not consistent across 5510 // implementations. We'll drop this notification and rely 5511 // on flush-complete notifications on the individual port 5512 // indices instead. 5513 5514 return true; 5515 } 5516 5517 return onOMXEvent( 5518 static_cast<OMX_EVENTTYPE>(event), 5519 static_cast<OMX_U32>(data1), 5520 static_cast<OMX_U32>(data2)); 5521 } 5522 5523 case omx_message::EMPTY_BUFFER_DONE: 5524 { 5525 IOMX::buffer_id bufferID; 5526 int32_t fenceFd; 5527 5528 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 5529 CHECK(msg->findInt32("fence_fd", &fenceFd)); 5530 5531 return onOMXEmptyBufferDone(bufferID, fenceFd); 5532 } 5533 5534 case omx_message::FILL_BUFFER_DONE: 5535 { 5536 IOMX::buffer_id bufferID; 5537 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 5538 5539 int32_t rangeOffset, rangeLength, flags, fenceFd; 5540 int64_t timeUs; 5541 5542 CHECK(msg->findInt32("range_offset", &rangeOffset)); 5543 CHECK(msg->findInt32("range_length", &rangeLength)); 5544 CHECK(msg->findInt32("flags", &flags)); 5545 CHECK(msg->findInt64("timestamp", &timeUs)); 5546 CHECK(msg->findInt32("fence_fd", &fenceFd)); 5547 5548 return onOMXFillBufferDone( 5549 bufferID, 5550 (size_t)rangeOffset, (size_t)rangeLength, 5551 (OMX_U32)flags, 5552 timeUs, 5553 fenceFd); 5554 } 5555 5556 case omx_message::FRAME_RENDERED: 5557 { 5558 int64_t mediaTimeUs, systemNano; 5559 5560 CHECK(msg->findInt64("media_time_us", &mediaTimeUs)); 5561 CHECK(msg->findInt64("system_nano", &systemNano)); 5562 5563 return onOMXFrameRendered( 5564 mediaTimeUs, systemNano); 5565 } 5566 5567 default: 5568 ALOGE("Unexpected message type: %d", type); 5569 return false; 5570 } 5571 } 5572 5573 bool ACodec::BaseState::onOMXFrameRendered( 5574 int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) { 5575 // ignore outside of Executing and PortSettingsChanged states 5576 return true; 5577 } 5578 5579 bool ACodec::BaseState::onOMXEvent( 5580 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5581 if (event == OMX_EventDataSpaceChanged) { 5582 ColorAspects aspects = ColorUtils::unpackToColorAspects(data2); 5583 5584 mCodec->onDataSpaceChanged((android_dataspace)data1, aspects); 5585 return true; 5586 } 5587 5588 if (event != OMX_EventError) { 5589 ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)", 5590 mCodec->mComponentName.c_str(), event, data1, data2); 5591 5592 return false; 5593 } 5594 5595 ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1); 5596 5597 // verify OMX component sends back an error we expect. 5598 OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1; 5599 if (!isOMXError(omxError)) { 5600 ALOGW("Invalid OMX error %#x", omxError); 5601 omxError = OMX_ErrorUndefined; 5602 } 5603 mCodec->signalError(omxError); 5604 5605 return true; 5606 } 5607 5608 bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) { 5609 ALOGV("[%s] onOMXEmptyBufferDone %u", 5610 mCodec->mComponentName.c_str(), bufferID); 5611 5612 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 5613 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5614 if (status != BufferInfo::OWNED_BY_COMPONENT) { 5615 ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5616 mCodec->dumpBuffers(kPortIndexInput); 5617 if (fenceFd >= 0) { 5618 ::close(fenceFd); 5619 } 5620 return false; 5621 } 5622 info->mStatus = BufferInfo::OWNED_BY_US; 5623 5624 // input buffers cannot take fences, so wait for any fence now 5625 (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone"); 5626 fenceFd = -1; 5627 5628 // still save fence for completeness 5629 info->setWriteFence(fenceFd, "onOMXEmptyBufferDone"); 5630 5631 // We're in "store-metadata-in-buffers" mode, the underlying 5632 // OMX component had access to data that's implicitly refcounted 5633 // by this "MediaBuffer" object. Now that the OMX component has 5634 // told us that it's done with the input buffer, we can decrement 5635 // the mediaBuffer's reference count. 5636 info->mData->setMediaBufferBase(NULL); 5637 5638 PortMode mode = getPortMode(kPortIndexInput); 5639 5640 switch (mode) { 5641 case KEEP_BUFFERS: 5642 break; 5643 5644 case RESUBMIT_BUFFERS: 5645 postFillThisBuffer(info); 5646 break; 5647 5648 case FREE_BUFFERS: 5649 default: 5650 ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers"); 5651 return false; 5652 } 5653 5654 return true; 5655 } 5656 5657 void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) { 5658 if (mCodec->mPortEOS[kPortIndexInput]) { 5659 return; 5660 } 5661 5662 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 5663 5664 info->mData->setFormat(mCodec->mInputFormat); 5665 mCodec->mBufferChannel->fillThisBuffer(info->mBufferID); 5666 info->mData.clear(); 5667 info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 5668 } 5669 5670 void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { 5671 IOMX::buffer_id bufferID; 5672 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 5673 sp<MediaCodecBuffer> buffer; 5674 int32_t err = OK; 5675 bool eos = false; 5676 PortMode mode = getPortMode(kPortIndexInput); 5677 int32_t discarded = 0; 5678 if (msg->findInt32("discarded", &discarded) && discarded) { 5679 // these are unfilled buffers returned by client 5680 // buffers are returned on MediaCodec.flush 5681 mode = KEEP_BUFFERS; 5682 } 5683 sp<RefBase> obj; 5684 CHECK(msg->findObject("buffer", &obj)); 5685 buffer = static_cast<MediaCodecBuffer *>(obj.get()); 5686 5687 int32_t tmp; 5688 if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) { 5689 eos = true; 5690 err = ERROR_END_OF_STREAM; 5691 } 5692 5693 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 5694 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5695 if (status != BufferInfo::OWNED_BY_UPSTREAM) { 5696 ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID); 5697 mCodec->dumpBuffers(kPortIndexInput); 5698 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5699 return; 5700 } 5701 5702 info->mStatus = BufferInfo::OWNED_BY_US; 5703 info->mData = buffer; 5704 5705 switch (mode) { 5706 case KEEP_BUFFERS: 5707 { 5708 if (eos) { 5709 if (!mCodec->mPortEOS[kPortIndexInput]) { 5710 mCodec->mPortEOS[kPortIndexInput] = true; 5711 mCodec->mInputEOSResult = err; 5712 } 5713 } 5714 break; 5715 } 5716 5717 case RESUBMIT_BUFFERS: 5718 { 5719 if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) { 5720 // Do not send empty input buffer w/o EOS to the component. 5721 if (buffer->size() == 0 && !eos) { 5722 postFillThisBuffer(info); 5723 break; 5724 } 5725 5726 int64_t timeUs; 5727 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 5728 5729 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 5730 5731 int32_t isCSD = 0; 5732 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) { 5733 if (mCodec->mIsLegacyVP9Decoder) { 5734 ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data", 5735 mCodec->mComponentName.c_str(), bufferID); 5736 postFillThisBuffer(info); 5737 break; 5738 } 5739 flags |= OMX_BUFFERFLAG_CODECCONFIG; 5740 } 5741 5742 if (eos) { 5743 flags |= OMX_BUFFERFLAG_EOS; 5744 } 5745 5746 size_t size = buffer->size(); 5747 size_t offset = buffer->offset(); 5748 if (buffer->base() != info->mCodecData->base()) { 5749 ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)", 5750 mCodec->mComponentName.c_str(), 5751 bufferID, 5752 buffer->base(), info->mCodecData->base()); 5753 5754 sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput]; 5755 if (converter == NULL || isCSD) { 5756 converter = getCopyConverter(); 5757 } 5758 status_t err = converter->convert(buffer, info->mCodecData); 5759 if (err != OK) { 5760 mCodec->signalError(OMX_ErrorUndefined, err); 5761 return; 5762 } 5763 size = info->mCodecData->size(); 5764 } else { 5765 info->mCodecData->setRange(offset, size); 5766 } 5767 5768 if (flags & OMX_BUFFERFLAG_CODECCONFIG) { 5769 ALOGV("[%s] calling emptyBuffer %u w/ codec specific data", 5770 mCodec->mComponentName.c_str(), bufferID); 5771 } else if (flags & OMX_BUFFERFLAG_EOS) { 5772 ALOGV("[%s] calling emptyBuffer %u w/ EOS", 5773 mCodec->mComponentName.c_str(), bufferID); 5774 } else { 5775 #if TRACK_BUFFER_TIMING 5776 ALOGI("[%s] calling emptyBuffer %u w/ time %lld us", 5777 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 5778 #else 5779 ALOGV("[%s] calling emptyBuffer %u w/ time %lld us", 5780 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 5781 #endif 5782 } 5783 5784 #if TRACK_BUFFER_TIMING 5785 ACodec::BufferStats stats; 5786 stats.mEmptyBufferTimeUs = ALooper::GetNowUs(); 5787 stats.mFillBufferDoneTimeUs = -1ll; 5788 mCodec->mBufferStats.add(timeUs, stats); 5789 #endif 5790 5791 if (mCodec->storingMetadataInDecodedBuffers()) { 5792 // try to submit an output buffer for each input buffer 5793 PortMode outputMode = getPortMode(kPortIndexOutput); 5794 5795 ALOGV("MetadataBuffersToSubmit=%u portMode=%s", 5796 mCodec->mMetadataBuffersToSubmit, 5797 (outputMode == FREE_BUFFERS ? "FREE" : 5798 outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT")); 5799 if (outputMode == RESUBMIT_BUFFERS) { 5800 mCodec->submitOutputMetadataBuffer(); 5801 } 5802 } 5803 info->checkReadFence("onInputBufferFilled"); 5804 5805 status_t err2 = OK; 5806 switch (mCodec->mPortMode[kPortIndexInput]) { 5807 case IOMX::kPortModePresetByteBuffer: 5808 case IOMX::kPortModePresetANWBuffer: 5809 case IOMX::kPortModePresetSecureBuffer: 5810 { 5811 err2 = mCodec->mOMXNode->emptyBuffer( 5812 bufferID, info->mCodecData, flags, timeUs, info->mFenceFd); 5813 } 5814 break; 5815 #ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 5816 case IOMX::kPortModeDynamicNativeHandle: 5817 if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) { 5818 VideoNativeHandleMetadata *vnhmd = 5819 (VideoNativeHandleMetadata*)info->mCodecData->base(); 5820 sp<NativeHandle> handle = NativeHandle::create( 5821 vnhmd->pHandle, false /* ownsHandle */); 5822 err2 = mCodec->mOMXNode->emptyBuffer( 5823 bufferID, handle, flags, timeUs, info->mFenceFd); 5824 } 5825 break; 5826 case IOMX::kPortModeDynamicANWBuffer: 5827 if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) { 5828 VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base(); 5829 sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(vnmd->pBuffer); 5830 err2 = mCodec->mOMXNode->emptyBuffer( 5831 bufferID, graphicBuffer, flags, timeUs, info->mFenceFd); 5832 } 5833 break; 5834 #endif 5835 default: 5836 ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode", 5837 asString(mCodec->mPortMode[kPortIndexInput]), 5838 info->mCodecData->size(), 5839 sizeof(buffer_handle_t) * 8); 5840 err2 = ERROR_UNSUPPORTED; 5841 break; 5842 } 5843 5844 info->mFenceFd = -1; 5845 if (err2 != OK) { 5846 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 5847 return; 5848 } 5849 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5850 // Hold the reference while component is using the buffer. 5851 info->mData = buffer; 5852 5853 if (!eos && err == OK) { 5854 getMoreInputDataIfPossible(); 5855 } else { 5856 ALOGV("[%s] Signalled EOS (%d) on the input port", 5857 mCodec->mComponentName.c_str(), err); 5858 5859 mCodec->mPortEOS[kPortIndexInput] = true; 5860 mCodec->mInputEOSResult = err; 5861 } 5862 } else if (!mCodec->mPortEOS[kPortIndexInput]) { 5863 if (err != OK && err != ERROR_END_OF_STREAM) { 5864 ALOGV("[%s] Signalling EOS on the input port due to error %d", 5865 mCodec->mComponentName.c_str(), err); 5866 } else { 5867 ALOGV("[%s] Signalling EOS on the input port", 5868 mCodec->mComponentName.c_str()); 5869 } 5870 5871 ALOGV("[%s] calling emptyBuffer %u signalling EOS", 5872 mCodec->mComponentName.c_str(), bufferID); 5873 5874 info->checkReadFence("onInputBufferFilled"); 5875 status_t err2 = mCodec->mOMXNode->emptyBuffer( 5876 bufferID, OMXBuffer::sPreset, OMX_BUFFERFLAG_EOS, 0, info->mFenceFd); 5877 info->mFenceFd = -1; 5878 if (err2 != OK) { 5879 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 5880 return; 5881 } 5882 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5883 5884 mCodec->mPortEOS[kPortIndexInput] = true; 5885 mCodec->mInputEOSResult = err; 5886 } 5887 break; 5888 } 5889 5890 case FREE_BUFFERS: 5891 break; 5892 5893 default: 5894 ALOGE("invalid port mode: %d", mode); 5895 break; 5896 } 5897 } 5898 5899 void ACodec::BaseState::getMoreInputDataIfPossible() { 5900 if (mCodec->mPortEOS[kPortIndexInput]) { 5901 return; 5902 } 5903 5904 BufferInfo *eligible = NULL; 5905 5906 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 5907 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 5908 5909 #if 0 5910 if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 5911 // There's already a "read" pending. 5912 return; 5913 } 5914 #endif 5915 5916 if (info->mStatus == BufferInfo::OWNED_BY_US) { 5917 eligible = info; 5918 } 5919 } 5920 5921 if (eligible == NULL) { 5922 return; 5923 } 5924 5925 postFillThisBuffer(eligible); 5926 } 5927 5928 bool ACodec::BaseState::onOMXFillBufferDone( 5929 IOMX::buffer_id bufferID, 5930 size_t rangeOffset, size_t rangeLength, 5931 OMX_U32 flags, 5932 int64_t timeUs, 5933 int fenceFd) { 5934 ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x", 5935 mCodec->mComponentName.c_str(), bufferID, timeUs, flags); 5936 5937 ssize_t index; 5938 status_t err= OK; 5939 5940 #if TRACK_BUFFER_TIMING 5941 index = mCodec->mBufferStats.indexOfKey(timeUs); 5942 if (index >= 0) { 5943 ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index); 5944 stats->mFillBufferDoneTimeUs = ALooper::GetNowUs(); 5945 5946 ALOGI("frame PTS %lld: %lld", 5947 timeUs, 5948 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs); 5949 5950 mCodec->mBufferStats.removeItemsAt(index); 5951 stats = NULL; 5952 } 5953 #endif 5954 5955 BufferInfo *info = 5956 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 5957 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5958 if (status != BufferInfo::OWNED_BY_COMPONENT) { 5959 ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5960 mCodec->dumpBuffers(kPortIndexOutput); 5961 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5962 if (fenceFd >= 0) { 5963 ::close(fenceFd); 5964 } 5965 return true; 5966 } 5967 5968 info->mDequeuedAt = ++mCodec->mDequeueCounter; 5969 info->mStatus = BufferInfo::OWNED_BY_US; 5970 5971 if (info->mRenderInfo != NULL) { 5972 // The fence for an emptied buffer must have signaled, but there still could be queued 5973 // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these, 5974 // as we will soon requeue this buffer to the surface. While in theory we could still keep 5975 // track of buffers that are requeued to the surface, it is better to add support to the 5976 // buffer-queue to notify us of released buffers and their fences (in the future). 5977 mCodec->notifyOfRenderedFrames(true /* dropIncomplete */); 5978 } 5979 5980 // byte buffers cannot take fences, so wait for any fence now 5981 if (mCodec->mNativeWindow == NULL) { 5982 (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone"); 5983 fenceFd = -1; 5984 } 5985 info->setReadFence(fenceFd, "onOMXFillBufferDone"); 5986 5987 PortMode mode = getPortMode(kPortIndexOutput); 5988 5989 switch (mode) { 5990 case KEEP_BUFFERS: 5991 break; 5992 5993 case RESUBMIT_BUFFERS: 5994 { 5995 if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS) 5996 || mCodec->mPortEOS[kPortIndexOutput])) { 5997 ALOGV("[%s] calling fillBuffer %u", 5998 mCodec->mComponentName.c_str(), info->mBufferID); 5999 6000 err = mCodec->fillBuffer(info); 6001 if (err != OK) { 6002 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6003 return true; 6004 } 6005 break; 6006 } 6007 6008 sp<MediaCodecBuffer> buffer = info->mData; 6009 6010 if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) { 6011 // pretend that output format has changed on the first frame (we used to do this) 6012 if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) { 6013 mCodec->onOutputFormatChanged(mCodec->mOutputFormat); 6014 } 6015 mCodec->sendFormatChange(); 6016 } 6017 buffer->setFormat(mCodec->mOutputFormat); 6018 6019 if (mCodec->usingSecureBufferOnEncoderOutput()) { 6020 native_handle_t *handle = NULL; 6021 sp<SecureBuffer> secureBuffer = static_cast<SecureBuffer *>(buffer.get()); 6022 if (secureBuffer != NULL) { 6023 #ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 6024 // handle is only valid on 32-bit/mediaserver process 6025 handle = NULL; 6026 #else 6027 handle = (native_handle_t *)secureBuffer->getDestinationPointer(); 6028 #endif 6029 } 6030 buffer->meta()->setPointer("handle", handle); 6031 buffer->meta()->setInt32("rangeOffset", rangeOffset); 6032 buffer->meta()->setInt32("rangeLength", rangeLength); 6033 } else if (buffer->base() == info->mCodecData->base()) { 6034 buffer->setRange(rangeOffset, rangeLength); 6035 } else { 6036 info->mCodecData->setRange(rangeOffset, rangeLength); 6037 // in this case we know that mConverter is not null 6038 status_t err = mCodec->mConverter[kPortIndexOutput]->convert( 6039 info->mCodecData, buffer); 6040 if (err != OK) { 6041 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6042 return true; 6043 } 6044 } 6045 #if 0 6046 if (mCodec->mNativeWindow == NULL) { 6047 if (IsIDR(info->mData)) { 6048 ALOGI("IDR frame"); 6049 } 6050 } 6051 #endif 6052 6053 if (mCodec->mSkipCutBuffer != NULL) { 6054 mCodec->mSkipCutBuffer->submit(buffer); 6055 } 6056 buffer->meta()->setInt64("timeUs", timeUs); 6057 6058 info->mData.clear(); 6059 6060 mCodec->mBufferChannel->drainThisBuffer(info->mBufferID, flags); 6061 6062 info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 6063 6064 if (flags & OMX_BUFFERFLAG_EOS) { 6065 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str()); 6066 6067 mCodec->mCallback->onEos(mCodec->mInputEOSResult); 6068 mCodec->mPortEOS[kPortIndexOutput] = true; 6069 } 6070 break; 6071 } 6072 6073 case FREE_BUFFERS: 6074 err = mCodec->freeBuffer(kPortIndexOutput, index); 6075 if (err != OK) { 6076 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6077 return true; 6078 } 6079 break; 6080 6081 default: 6082 ALOGE("Invalid port mode: %d", mode); 6083 return false; 6084 } 6085 6086 return true; 6087 } 6088 6089 void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 6090 IOMX::buffer_id bufferID; 6091 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 6092 sp<RefBase> obj; 6093 CHECK(msg->findObject("buffer", &obj)); 6094 sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get()); 6095 int32_t discarded = 0; 6096 msg->findInt32("discarded", &discarded); 6097 6098 ssize_t index; 6099 BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 6100 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 6101 if (status != BufferInfo::OWNED_BY_DOWNSTREAM) { 6102 ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 6103 mCodec->dumpBuffers(kPortIndexOutput); 6104 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6105 return; 6106 } 6107 info->mData = buffer; 6108 int32_t render; 6109 if (mCodec->mNativeWindow != NULL 6110 && msg->findInt32("render", &render) && render != 0 6111 && !discarded && buffer->size() != 0) { 6112 ATRACE_NAME("render"); 6113 // The client wants this buffer to be rendered. 6114 6115 android_native_rect_t crop; 6116 if (buffer->format()->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) { 6117 // NOTE: native window uses extended right-bottom coordinate 6118 ++crop.right; 6119 ++crop.bottom; 6120 if (memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) { 6121 mCodec->mLastNativeWindowCrop = crop; 6122 status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop); 6123 ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err); 6124 } 6125 } 6126 6127 int32_t dataSpace; 6128 if (buffer->format()->findInt32("android._dataspace", &dataSpace) 6129 && dataSpace != mCodec->mLastNativeWindowDataSpace) { 6130 status_t err = native_window_set_buffers_data_space( 6131 mCodec->mNativeWindow.get(), (android_dataspace)dataSpace); 6132 mCodec->mLastNativeWindowDataSpace = dataSpace; 6133 ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err); 6134 } 6135 6136 // save buffers sent to the surface so we can get render time when they return 6137 int64_t mediaTimeUs = -1; 6138 buffer->meta()->findInt64("timeUs", &mediaTimeUs); 6139 if (mediaTimeUs >= 0) { 6140 mCodec->mRenderTracker.onFrameQueued( 6141 mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd))); 6142 } 6143 6144 int64_t timestampNs = 0; 6145 if (!msg->findInt64("timestampNs", ×tampNs)) { 6146 // use media timestamp if client did not request a specific render timestamp 6147 if (buffer->meta()->findInt64("timeUs", ×tampNs)) { 6148 ALOGV("using buffer PTS of %lld", (long long)timestampNs); 6149 timestampNs *= 1000; 6150 } 6151 } 6152 6153 status_t err; 6154 err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs); 6155 ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err); 6156 6157 info->checkReadFence("onOutputBufferDrained before queueBuffer"); 6158 err = mCodec->mNativeWindow->queueBuffer( 6159 mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd); 6160 info->mFenceFd = -1; 6161 if (err == OK) { 6162 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 6163 } else { 6164 ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err); 6165 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6166 info->mStatus = BufferInfo::OWNED_BY_US; 6167 // keeping read fence as write fence to avoid clobbering 6168 info->mIsReadFence = false; 6169 } 6170 } else { 6171 if (mCodec->mNativeWindow != NULL && (discarded || buffer->size() != 0)) { 6172 // move read fence into write fence to avoid clobbering 6173 info->mIsReadFence = false; 6174 ATRACE_NAME("frame-drop"); 6175 } 6176 info->mStatus = BufferInfo::OWNED_BY_US; 6177 } 6178 6179 PortMode mode = getPortMode(kPortIndexOutput); 6180 6181 switch (mode) { 6182 case KEEP_BUFFERS: 6183 { 6184 // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 6185 6186 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6187 // We cannot resubmit the buffer we just rendered, dequeue 6188 // the spare instead. 6189 6190 info = mCodec->dequeueBufferFromNativeWindow(); 6191 } 6192 break; 6193 } 6194 6195 case RESUBMIT_BUFFERS: 6196 { 6197 if (!mCodec->mPortEOS[kPortIndexOutput]) { 6198 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6199 // We cannot resubmit the buffer we just rendered, dequeue 6200 // the spare instead. 6201 6202 info = mCodec->dequeueBufferFromNativeWindow(); 6203 } 6204 6205 if (info != NULL) { 6206 ALOGV("[%s] calling fillBuffer %u", 6207 mCodec->mComponentName.c_str(), info->mBufferID); 6208 info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS"); 6209 status_t err = mCodec->fillBuffer(info); 6210 if (err != OK) { 6211 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6212 } 6213 } 6214 } 6215 break; 6216 } 6217 6218 case FREE_BUFFERS: 6219 { 6220 status_t err = mCodec->freeBuffer(kPortIndexOutput, index); 6221 if (err != OK) { 6222 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6223 } 6224 break; 6225 } 6226 6227 default: 6228 ALOGE("Invalid port mode: %d", mode); 6229 return; 6230 } 6231 } 6232 6233 //////////////////////////////////////////////////////////////////////////////// 6234 6235 ACodec::UninitializedState::UninitializedState(ACodec *codec) 6236 : BaseState(codec) { 6237 } 6238 6239 void ACodec::UninitializedState::stateEntered() { 6240 ALOGV("Now uninitialized"); 6241 6242 if (mDeathNotifier != NULL) { 6243 if (mCodec->mOMXNode != NULL) { 6244 if (mCodec->getTrebleFlag()) { 6245 auto tOmxNode = mCodec->mOMXNode->getHalInterface(); 6246 tOmxNode->unlinkToDeath(mDeathNotifier); 6247 } else { 6248 sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode); 6249 binder->unlinkToDeath(mDeathNotifier); 6250 } 6251 } 6252 mDeathNotifier.clear(); 6253 } 6254 6255 mCodec->mUsingNativeWindow = false; 6256 mCodec->mNativeWindow.clear(); 6257 mCodec->mNativeWindowUsageBits = 0; 6258 mCodec->mOMX.clear(); 6259 mCodec->mOMXNode.clear(); 6260 mCodec->mFlags = 0; 6261 mCodec->mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer; 6262 mCodec->mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer; 6263 mCodec->mConverter[0].clear(); 6264 mCodec->mConverter[1].clear(); 6265 mCodec->mComponentName.clear(); 6266 } 6267 6268 bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 6269 bool handled = false; 6270 6271 switch (msg->what()) { 6272 case ACodec::kWhatSetup: 6273 { 6274 onSetup(msg); 6275 6276 handled = true; 6277 break; 6278 } 6279 6280 case ACodec::kWhatAllocateComponent: 6281 { 6282 onAllocateComponent(msg); 6283 handled = true; 6284 break; 6285 } 6286 6287 case ACodec::kWhatShutdown: 6288 { 6289 int32_t keepComponentAllocated; 6290 CHECK(msg->findInt32( 6291 "keepComponentAllocated", &keepComponentAllocated)); 6292 ALOGW_IF(keepComponentAllocated, 6293 "cannot keep component allocated on shutdown in Uninitialized state"); 6294 if (keepComponentAllocated) { 6295 mCodec->mCallback->onStopCompleted(); 6296 } else { 6297 mCodec->mCallback->onReleaseCompleted(); 6298 } 6299 handled = true; 6300 break; 6301 } 6302 6303 case ACodec::kWhatFlush: 6304 { 6305 mCodec->mCallback->onFlushCompleted(); 6306 handled = true; 6307 break; 6308 } 6309 6310 case ACodec::kWhatReleaseCodecInstance: 6311 { 6312 // nothing to do, as we have already signaled shutdown 6313 handled = true; 6314 break; 6315 } 6316 6317 default: 6318 return BaseState::onMessageReceived(msg); 6319 } 6320 6321 return handled; 6322 } 6323 6324 void ACodec::UninitializedState::onSetup( 6325 const sp<AMessage> &msg) { 6326 if (onAllocateComponent(msg) 6327 && mCodec->mLoadedState->onConfigureComponent(msg)) { 6328 mCodec->mLoadedState->onStart(); 6329 } 6330 } 6331 6332 bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { 6333 ALOGV("onAllocateComponent"); 6334 6335 CHECK(mCodec->mOMXNode == NULL); 6336 6337 OMXClient client; 6338 bool trebleFlag; 6339 if (client.connect(&trebleFlag) != OK) { 6340 mCodec->signalError(OMX_ErrorUndefined, NO_INIT); 6341 return false; 6342 } 6343 mCodec->setTrebleFlag(trebleFlag); 6344 6345 sp<IOMX> omx = client.interface(); 6346 6347 sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec); 6348 6349 Vector<AString> matchingCodecs; 6350 6351 AString mime; 6352 6353 AString componentName; 6354 int32_t encoder = false; 6355 if (msg->findString("componentName", &componentName)) { 6356 sp<IMediaCodecList> list = MediaCodecList::getInstance(); 6357 if (list != NULL && list->findCodecByName(componentName.c_str()) >= 0) { 6358 matchingCodecs.add(componentName); 6359 } 6360 } else { 6361 CHECK(msg->findString("mime", &mime)); 6362 6363 if (!msg->findInt32("encoder", &encoder)) { 6364 encoder = false; 6365 } 6366 6367 MediaCodecList::findMatchingCodecs( 6368 mime.c_str(), 6369 encoder, // createEncoder 6370 0, // flags 6371 &matchingCodecs); 6372 } 6373 6374 sp<CodecObserver> observer = new CodecObserver; 6375 sp<IOMXNode> omxNode; 6376 6377 status_t err = NAME_NOT_FOUND; 6378 for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); 6379 ++matchIndex) { 6380 componentName = matchingCodecs[matchIndex]; 6381 6382 pid_t tid = gettid(); 6383 int prevPriority = androidGetThreadPriority(tid); 6384 androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); 6385 err = omx->allocateNode(componentName.c_str(), observer, &omxNode); 6386 androidSetThreadPriority(tid, prevPriority); 6387 6388 if (err == OK) { 6389 break; 6390 } else { 6391 ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str()); 6392 } 6393 6394 omxNode = NULL; 6395 } 6396 6397 if (omxNode == NULL) { 6398 if (!mime.empty()) { 6399 ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.", 6400 encoder ? "en" : "de", mime.c_str(), err); 6401 } else { 6402 ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err); 6403 } 6404 6405 mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err)); 6406 return false; 6407 } 6408 6409 mDeathNotifier = new DeathNotifier(notify); 6410 if (mCodec->getTrebleFlag()) { 6411 auto tOmxNode = omxNode->getHalInterface(); 6412 if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) { 6413 mDeathNotifier.clear(); 6414 } 6415 } else { 6416 if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) { 6417 // This was a local binder, if it dies so do we, we won't care 6418 // about any notifications in the afterlife. 6419 mDeathNotifier.clear(); 6420 } 6421 } 6422 6423 notify = new AMessage(kWhatOMXMessageList, mCodec); 6424 notify->setInt32("generation", ++mCodec->mNodeGeneration); 6425 observer->setNotificationMessage(notify); 6426 6427 mCodec->mComponentName = componentName; 6428 mCodec->mRenderTracker.setComponentName(componentName); 6429 mCodec->mFlags = 0; 6430 6431 if (componentName.endsWith(".secure")) { 6432 mCodec->mFlags |= kFlagIsSecure; 6433 mCodec->mFlags |= kFlagIsGrallocUsageProtected; 6434 mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 6435 } 6436 6437 mCodec->mOMX = omx; 6438 mCodec->mOMXNode = omxNode; 6439 mCodec->mCallback->onComponentAllocated(mCodec->mComponentName.c_str()); 6440 mCodec->changeState(mCodec->mLoadedState); 6441 6442 return true; 6443 } 6444 6445 //////////////////////////////////////////////////////////////////////////////// 6446 6447 ACodec::LoadedState::LoadedState(ACodec *codec) 6448 : BaseState(codec) { 6449 } 6450 6451 void ACodec::LoadedState::stateEntered() { 6452 ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 6453 6454 mCodec->mPortEOS[kPortIndexInput] = 6455 mCodec->mPortEOS[kPortIndexOutput] = false; 6456 6457 mCodec->mInputEOSResult = OK; 6458 6459 mCodec->mDequeueCounter = 0; 6460 mCodec->mMetadataBuffersToSubmit = 0; 6461 mCodec->mRepeatFrameDelayUs = -1ll; 6462 mCodec->mInputFormat.clear(); 6463 mCodec->mOutputFormat.clear(); 6464 mCodec->mBaseOutputFormat.clear(); 6465 mCodec->mGraphicBufferSource.clear(); 6466 6467 if (mCodec->mShutdownInProgress) { 6468 bool keepComponentAllocated = mCodec->mKeepComponentAllocated; 6469 6470 mCodec->mShutdownInProgress = false; 6471 mCodec->mKeepComponentAllocated = false; 6472 6473 onShutdown(keepComponentAllocated); 6474 } 6475 mCodec->mExplicitShutdown = false; 6476 6477 mCodec->processDeferredMessages(); 6478 } 6479 6480 void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) { 6481 if (!keepComponentAllocated) { 6482 (void)mCodec->mOMXNode->freeNode(); 6483 6484 mCodec->changeState(mCodec->mUninitializedState); 6485 } 6486 6487 if (mCodec->mExplicitShutdown) { 6488 if (keepComponentAllocated) { 6489 mCodec->mCallback->onStopCompleted(); 6490 } else { 6491 mCodec->mCallback->onReleaseCompleted(); 6492 } 6493 mCodec->mExplicitShutdown = false; 6494 } 6495 } 6496 6497 bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) { 6498 bool handled = false; 6499 6500 switch (msg->what()) { 6501 case ACodec::kWhatConfigureComponent: 6502 { 6503 onConfigureComponent(msg); 6504 handled = true; 6505 break; 6506 } 6507 6508 case ACodec::kWhatCreateInputSurface: 6509 { 6510 onCreateInputSurface(msg); 6511 handled = true; 6512 break; 6513 } 6514 6515 case ACodec::kWhatSetInputSurface: 6516 { 6517 onSetInputSurface(msg); 6518 handled = true; 6519 break; 6520 } 6521 6522 case ACodec::kWhatStart: 6523 { 6524 onStart(); 6525 handled = true; 6526 break; 6527 } 6528 6529 case ACodec::kWhatShutdown: 6530 { 6531 int32_t keepComponentAllocated; 6532 CHECK(msg->findInt32( 6533 "keepComponentAllocated", &keepComponentAllocated)); 6534 6535 mCodec->mExplicitShutdown = true; 6536 onShutdown(keepComponentAllocated); 6537 6538 handled = true; 6539 break; 6540 } 6541 6542 case ACodec::kWhatFlush: 6543 { 6544 mCodec->mCallback->onFlushCompleted(); 6545 handled = true; 6546 break; 6547 } 6548 6549 default: 6550 return BaseState::onMessageReceived(msg); 6551 } 6552 6553 return handled; 6554 } 6555 6556 bool ACodec::LoadedState::onConfigureComponent( 6557 const sp<AMessage> &msg) { 6558 ALOGV("onConfigureComponent"); 6559 6560 CHECK(mCodec->mOMXNode != NULL); 6561 6562 status_t err = OK; 6563 AString mime; 6564 if (!msg->findString("mime", &mime)) { 6565 err = BAD_VALUE; 6566 } else { 6567 err = mCodec->configureCodec(mime.c_str(), msg); 6568 } 6569 if (err != OK) { 6570 ALOGE("[%s] configureCodec returning error %d", 6571 mCodec->mComponentName.c_str(), err); 6572 6573 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6574 return false; 6575 } 6576 6577 mCodec->mCallback->onComponentConfigured(mCodec->mInputFormat, mCodec->mOutputFormat); 6578 6579 return true; 6580 } 6581 6582 status_t ACodec::LoadedState::setupInputSurface() { 6583 if (mCodec->mGraphicBufferSource == NULL) { 6584 return BAD_VALUE; 6585 } 6586 6587 android_dataspace dataSpace; 6588 status_t err = 6589 mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace); 6590 if (err != OK) { 6591 ALOGE("Failed to get default data space"); 6592 return err; 6593 } 6594 6595 err = statusFromBinderStatus( 6596 mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace)); 6597 if (err != OK) { 6598 ALOGE("[%s] Unable to configure for node (err %d)", 6599 mCodec->mComponentName.c_str(), err); 6600 return err; 6601 } 6602 6603 if (mCodec->mRepeatFrameDelayUs > 0ll) { 6604 err = statusFromBinderStatus( 6605 mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs( 6606 mCodec->mRepeatFrameDelayUs)); 6607 6608 if (err != OK) { 6609 ALOGE("[%s] Unable to configure option to repeat previous " 6610 "frames (err %d)", 6611 mCodec->mComponentName.c_str(), err); 6612 return err; 6613 } 6614 } 6615 6616 if (mCodec->mMaxPtsGapUs > 0ll) { 6617 OMX_PARAM_U32TYPE maxPtsGapParams; 6618 InitOMXParams(&maxPtsGapParams); 6619 maxPtsGapParams.nPortIndex = kPortIndexInput; 6620 maxPtsGapParams.nU32 = (uint32_t) mCodec->mMaxPtsGapUs; 6621 6622 err = mCodec->mOMXNode->setParameter( 6623 (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl, 6624 &maxPtsGapParams, sizeof(maxPtsGapParams)); 6625 6626 if (err != OK) { 6627 ALOGE("[%s] Unable to configure max timestamp gap (err %d)", 6628 mCodec->mComponentName.c_str(), err); 6629 return err; 6630 } 6631 } 6632 6633 if (mCodec->mMaxFps > 0) { 6634 err = statusFromBinderStatus( 6635 mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps)); 6636 6637 if (err != OK) { 6638 ALOGE("[%s] Unable to configure max fps (err %d)", 6639 mCodec->mComponentName.c_str(), err); 6640 return err; 6641 } 6642 } 6643 6644 if (mCodec->mCaptureFps > 0. && mCodec->mFps > 0.) { 6645 err = statusFromBinderStatus( 6646 mCodec->mGraphicBufferSource->setTimeLapseConfig( 6647 mCodec->mFps, mCodec->mCaptureFps)); 6648 6649 if (err != OK) { 6650 ALOGE("[%s] Unable to configure time lapse (err %d)", 6651 mCodec->mComponentName.c_str(), err); 6652 return err; 6653 } 6654 } 6655 6656 if (mCodec->mCreateInputBuffersSuspended) { 6657 err = statusFromBinderStatus( 6658 mCodec->mGraphicBufferSource->setSuspend(true, -1)); 6659 6660 if (err != OK) { 6661 ALOGE("[%s] Unable to configure option to suspend (err %d)", 6662 mCodec->mComponentName.c_str(), err); 6663 return err; 6664 } 6665 } 6666 6667 uint32_t usageBits; 6668 if (mCodec->mOMXNode->getParameter( 6669 (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, 6670 &usageBits, sizeof(usageBits)) == OK) { 6671 mCodec->mInputFormat->setInt32( 6672 "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN)); 6673 } 6674 6675 sp<ABuffer> colorAspectsBuffer; 6676 if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) { 6677 if (colorAspectsBuffer->size() != sizeof(ColorAspects)) { 6678 return INVALID_OPERATION; 6679 } 6680 6681 err = statusFromBinderStatus( 6682 mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32( 6683 *(ColorAspects *)colorAspectsBuffer->base()))); 6684 6685 if (err != OK) { 6686 ALOGE("[%s] Unable to configure color aspects (err %d)", 6687 mCodec->mComponentName.c_str(), err); 6688 return err; 6689 } 6690 } 6691 return OK; 6692 } 6693 6694 void ACodec::LoadedState::onCreateInputSurface( 6695 const sp<AMessage> & /* msg */) { 6696 ALOGV("onCreateInputSurface"); 6697 6698 sp<IGraphicBufferProducer> bufferProducer; 6699 status_t err = mCodec->mOMX->createInputSurface( 6700 &bufferProducer, &mCodec->mGraphicBufferSource); 6701 6702 if (err == OK) { 6703 err = setupInputSurface(); 6704 } 6705 6706 if (err == OK) { 6707 mCodec->mCallback->onInputSurfaceCreated( 6708 mCodec->mInputFormat, 6709 mCodec->mOutputFormat, 6710 new BufferProducerWrapper(bufferProducer)); 6711 } else { 6712 // Can't use mCodec->signalError() here -- MediaCodec won't forward 6713 // the error through because it's in the "configured" state. We 6714 // send a kWhatInputSurfaceCreated with an error value instead. 6715 ALOGE("[%s] onCreateInputSurface returning error %d", 6716 mCodec->mComponentName.c_str(), err); 6717 mCodec->mCallback->onInputSurfaceCreationFailed(err); 6718 } 6719 } 6720 6721 void ACodec::LoadedState::onSetInputSurface(const sp<AMessage> &msg) { 6722 ALOGV("onSetInputSurface"); 6723 6724 sp<RefBase> obj; 6725 CHECK(msg->findObject("input-surface", &obj)); 6726 sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get()); 6727 mCodec->mGraphicBufferSource = surface->getBufferSource(); 6728 6729 status_t err = setupInputSurface(); 6730 6731 if (err == OK) { 6732 mCodec->mCallback->onInputSurfaceAccepted( 6733 mCodec->mInputFormat, mCodec->mOutputFormat); 6734 } else { 6735 // Can't use mCodec->signalError() here -- MediaCodec won't forward 6736 // the error through because it's in the "configured" state. We 6737 // send a kWhatInputSurfaceAccepted with an error value instead. 6738 ALOGE("[%s] onSetInputSurface returning error %d", 6739 mCodec->mComponentName.c_str(), err); 6740 mCodec->mCallback->onInputSurfaceDeclined(err); 6741 } 6742 } 6743 6744 void ACodec::LoadedState::onStart() { 6745 ALOGV("onStart"); 6746 6747 status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle); 6748 if (err != OK) { 6749 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6750 } else { 6751 mCodec->changeState(mCodec->mLoadedToIdleState); 6752 } 6753 } 6754 6755 //////////////////////////////////////////////////////////////////////////////// 6756 6757 ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 6758 : BaseState(codec) { 6759 } 6760 6761 void ACodec::LoadedToIdleState::stateEntered() { 6762 ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 6763 6764 status_t err; 6765 if ((err = allocateBuffers()) != OK) { 6766 ALOGE("Failed to allocate buffers after transitioning to IDLE state " 6767 "(error 0x%08x)", 6768 err); 6769 6770 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6771 6772 mCodec->mOMXNode->sendCommand( 6773 OMX_CommandStateSet, OMX_StateLoaded); 6774 if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) { 6775 mCodec->freeBuffersOnPort(kPortIndexInput); 6776 } 6777 if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) { 6778 mCodec->freeBuffersOnPort(kPortIndexOutput); 6779 } 6780 6781 mCodec->changeState(mCodec->mLoadedState); 6782 } 6783 } 6784 6785 status_t ACodec::LoadedToIdleState::allocateBuffers() { 6786 status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 6787 if (err != OK) { 6788 return err; 6789 } 6790 6791 err = mCodec->allocateBuffersOnPort(kPortIndexOutput); 6792 if (err != OK) { 6793 return err; 6794 } 6795 6796 mCodec->mCallback->onStartCompleted(); 6797 6798 return OK; 6799 } 6800 6801 bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 6802 switch (msg->what()) { 6803 case kWhatSetParameters: 6804 case kWhatShutdown: 6805 { 6806 mCodec->deferMessage(msg); 6807 return true; 6808 } 6809 6810 case kWhatSignalEndOfInputStream: 6811 { 6812 mCodec->onSignalEndOfInputStream(); 6813 return true; 6814 } 6815 6816 case kWhatResume: 6817 { 6818 // We'll be active soon enough. 6819 return true; 6820 } 6821 6822 case kWhatFlush: 6823 { 6824 // We haven't even started yet, so we're flushed alright... 6825 mCodec->mCallback->onFlushCompleted(); 6826 return true; 6827 } 6828 6829 default: 6830 return BaseState::onMessageReceived(msg); 6831 } 6832 } 6833 6834 bool ACodec::LoadedToIdleState::onOMXEvent( 6835 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6836 switch (event) { 6837 case OMX_EventCmdComplete: 6838 { 6839 status_t err = OK; 6840 if (data1 != (OMX_U32)OMX_CommandStateSet 6841 || data2 != (OMX_U32)OMX_StateIdle) { 6842 ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)", 6843 asString((OMX_COMMANDTYPE)data1), data1, 6844 asString((OMX_STATETYPE)data2), data2); 6845 err = FAILED_TRANSACTION; 6846 } 6847 6848 if (err == OK) { 6849 err = mCodec->mOMXNode->sendCommand( 6850 OMX_CommandStateSet, OMX_StateExecuting); 6851 } 6852 6853 if (err != OK) { 6854 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6855 } else { 6856 mCodec->changeState(mCodec->mIdleToExecutingState); 6857 } 6858 6859 return true; 6860 } 6861 6862 default: 6863 return BaseState::onOMXEvent(event, data1, data2); 6864 } 6865 } 6866 6867 //////////////////////////////////////////////////////////////////////////////// 6868 6869 ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 6870 : BaseState(codec) { 6871 } 6872 6873 void ACodec::IdleToExecutingState::stateEntered() { 6874 ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 6875 } 6876 6877 bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 6878 switch (msg->what()) { 6879 case kWhatSetParameters: 6880 case kWhatShutdown: 6881 { 6882 mCodec->deferMessage(msg); 6883 return true; 6884 } 6885 6886 case kWhatResume: 6887 { 6888 // We'll be active soon enough. 6889 return true; 6890 } 6891 6892 case kWhatFlush: 6893 { 6894 // We haven't even started yet, so we're flushed alright... 6895 mCodec->mCallback->onFlushCompleted(); 6896 return true; 6897 } 6898 6899 case kWhatSignalEndOfInputStream: 6900 { 6901 mCodec->onSignalEndOfInputStream(); 6902 return true; 6903 } 6904 6905 default: 6906 return BaseState::onMessageReceived(msg); 6907 } 6908 } 6909 6910 bool ACodec::IdleToExecutingState::onOMXEvent( 6911 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6912 switch (event) { 6913 case OMX_EventCmdComplete: 6914 { 6915 if (data1 != (OMX_U32)OMX_CommandStateSet 6916 || data2 != (OMX_U32)OMX_StateExecuting) { 6917 ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)", 6918 asString((OMX_COMMANDTYPE)data1), data1, 6919 asString((OMX_STATETYPE)data2), data2); 6920 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6921 return true; 6922 } 6923 6924 mCodec->mExecutingState->resume(); 6925 mCodec->changeState(mCodec->mExecutingState); 6926 6927 return true; 6928 } 6929 6930 default: 6931 return BaseState::onOMXEvent(event, data1, data2); 6932 } 6933 } 6934 6935 //////////////////////////////////////////////////////////////////////////////// 6936 6937 ACodec::ExecutingState::ExecutingState(ACodec *codec) 6938 : BaseState(codec), 6939 mActive(false) { 6940 } 6941 6942 ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 6943 OMX_U32 /* portIndex */) { 6944 return RESUBMIT_BUFFERS; 6945 } 6946 6947 void ACodec::ExecutingState::submitOutputMetaBuffers() { 6948 // submit as many buffers as there are input buffers with the codec 6949 // in case we are in port reconfiguring 6950 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 6951 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 6952 6953 if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) { 6954 if (mCodec->submitOutputMetadataBuffer() != OK) 6955 break; 6956 } 6957 } 6958 6959 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 6960 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 6961 } 6962 6963 void ACodec::ExecutingState::submitRegularOutputBuffers() { 6964 bool failed = false; 6965 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 6966 BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 6967 6968 if (mCodec->mNativeWindow != NULL) { 6969 if (info->mStatus != BufferInfo::OWNED_BY_US 6970 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6971 ALOGE("buffers should be owned by us or the surface"); 6972 failed = true; 6973 break; 6974 } 6975 6976 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6977 continue; 6978 } 6979 } else { 6980 if (info->mStatus != BufferInfo::OWNED_BY_US) { 6981 ALOGE("buffers should be owned by us"); 6982 failed = true; 6983 break; 6984 } 6985 } 6986 6987 ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID); 6988 6989 info->checkWriteFence("submitRegularOutputBuffers"); 6990 status_t err = mCodec->fillBuffer(info); 6991 if (err != OK) { 6992 failed = true; 6993 break; 6994 } 6995 } 6996 6997 if (failed) { 6998 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6999 } 7000 } 7001 7002 void ACodec::ExecutingState::submitOutputBuffers() { 7003 submitRegularOutputBuffers(); 7004 if (mCodec->storingMetadataInDecodedBuffers()) { 7005 submitOutputMetaBuffers(); 7006 } 7007 } 7008 7009 void ACodec::ExecutingState::resume() { 7010 if (mActive) { 7011 ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str()); 7012 return; 7013 } 7014 7015 submitOutputBuffers(); 7016 7017 // Post all available input buffers 7018 if (mCodec->mBuffers[kPortIndexInput].size() == 0u) { 7019 ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str()); 7020 } 7021 7022 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) { 7023 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 7024 if (info->mStatus == BufferInfo::OWNED_BY_US) { 7025 postFillThisBuffer(info); 7026 } 7027 } 7028 7029 mActive = true; 7030 } 7031 7032 void ACodec::ExecutingState::stateEntered() { 7033 ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 7034 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 7035 mCodec->processDeferredMessages(); 7036 } 7037 7038 bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 7039 bool handled = false; 7040 7041 switch (msg->what()) { 7042 case kWhatShutdown: 7043 { 7044 int32_t keepComponentAllocated; 7045 CHECK(msg->findInt32( 7046 "keepComponentAllocated", &keepComponentAllocated)); 7047 7048 mCodec->mShutdownInProgress = true; 7049 mCodec->mExplicitShutdown = true; 7050 mCodec->mKeepComponentAllocated = keepComponentAllocated; 7051 7052 mActive = false; 7053 7054 status_t err = mCodec->mOMXNode->sendCommand( 7055 OMX_CommandStateSet, OMX_StateIdle); 7056 if (err != OK) { 7057 if (keepComponentAllocated) { 7058 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7059 } 7060 // TODO: do some recovery here. 7061 } else { 7062 mCodec->changeState(mCodec->mExecutingToIdleState); 7063 } 7064 7065 handled = true; 7066 break; 7067 } 7068 7069 case kWhatFlush: 7070 { 7071 ALOGV("[%s] ExecutingState flushing now " 7072 "(codec owns %zu/%zu input, %zu/%zu output).", 7073 mCodec->mComponentName.c_str(), 7074 mCodec->countBuffersOwnedByComponent(kPortIndexInput), 7075 mCodec->mBuffers[kPortIndexInput].size(), 7076 mCodec->countBuffersOwnedByComponent(kPortIndexOutput), 7077 mCodec->mBuffers[kPortIndexOutput].size()); 7078 7079 mActive = false; 7080 7081 status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL); 7082 if (err != OK) { 7083 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7084 } else { 7085 mCodec->changeState(mCodec->mFlushingState); 7086 } 7087 7088 handled = true; 7089 break; 7090 } 7091 7092 case kWhatResume: 7093 { 7094 resume(); 7095 7096 handled = true; 7097 break; 7098 } 7099 7100 case kWhatRequestIDRFrame: 7101 { 7102 status_t err = mCodec->requestIDRFrame(); 7103 if (err != OK) { 7104 ALOGW("Requesting an IDR frame failed."); 7105 } 7106 7107 handled = true; 7108 break; 7109 } 7110 7111 case kWhatSetParameters: 7112 { 7113 sp<AMessage> params; 7114 CHECK(msg->findMessage("params", ¶ms)); 7115 7116 status_t err = mCodec->setParameters(params); 7117 7118 sp<AMessage> reply; 7119 if (msg->findMessage("reply", &reply)) { 7120 reply->setInt32("err", err); 7121 reply->post(); 7122 } 7123 7124 handled = true; 7125 break; 7126 } 7127 7128 case ACodec::kWhatSignalEndOfInputStream: 7129 { 7130 mCodec->onSignalEndOfInputStream(); 7131 handled = true; 7132 break; 7133 } 7134 7135 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 7136 case kWhatSubmitOutputMetadataBufferIfEOS: 7137 { 7138 if (mCodec->mPortEOS[kPortIndexInput] && 7139 !mCodec->mPortEOS[kPortIndexOutput]) { 7140 status_t err = mCodec->submitOutputMetadataBuffer(); 7141 if (err == OK) { 7142 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 7143 } 7144 } 7145 return true; 7146 } 7147 7148 default: 7149 handled = BaseState::onMessageReceived(msg); 7150 break; 7151 } 7152 7153 return handled; 7154 } 7155 7156 status_t ACodec::setParameters(const sp<AMessage> ¶ms) { 7157 int32_t videoBitrate; 7158 if (params->findInt32("video-bitrate", &videoBitrate)) { 7159 OMX_VIDEO_CONFIG_BITRATETYPE configParams; 7160 InitOMXParams(&configParams); 7161 configParams.nPortIndex = kPortIndexOutput; 7162 configParams.nEncodeBitrate = videoBitrate; 7163 7164 status_t err = mOMXNode->setConfig( 7165 OMX_IndexConfigVideoBitrate, 7166 &configParams, 7167 sizeof(configParams)); 7168 7169 if (err != OK) { 7170 ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d", 7171 videoBitrate, err); 7172 7173 return err; 7174 } 7175 } 7176 7177 int64_t timeOffsetUs; 7178 if (params->findInt64("time-offset-us", &timeOffsetUs)) { 7179 if (mGraphicBufferSource == NULL) { 7180 ALOGE("[%s] Invalid to set input buffer time offset without surface", 7181 mComponentName.c_str()); 7182 return INVALID_OPERATION; 7183 } 7184 7185 status_t err = statusFromBinderStatus( 7186 mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs)); 7187 7188 if (err != OK) { 7189 ALOGE("[%s] Unable to set input buffer time offset (err %d)", 7190 mComponentName.c_str(), 7191 err); 7192 return err; 7193 } 7194 } 7195 7196 int64_t skipFramesBeforeUs; 7197 if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) { 7198 if (mGraphicBufferSource == NULL) { 7199 ALOGE("[%s] Invalid to set start time without surface", 7200 mComponentName.c_str()); 7201 return INVALID_OPERATION; 7202 } 7203 7204 status_t err = statusFromBinderStatus( 7205 mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs)); 7206 7207 if (err != OK) { 7208 ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err); 7209 return err; 7210 } 7211 } 7212 7213 int32_t dropInputFrames; 7214 if (params->findInt32("drop-input-frames", &dropInputFrames)) { 7215 if (mGraphicBufferSource == NULL) { 7216 ALOGE("[%s] Invalid to set suspend without surface", 7217 mComponentName.c_str()); 7218 return INVALID_OPERATION; 7219 } 7220 7221 int64_t suspendStartTimeUs = -1; 7222 (void) params->findInt64("drop-start-time-us", &suspendStartTimeUs); 7223 status_t err = statusFromBinderStatus( 7224 mGraphicBufferSource->setSuspend(dropInputFrames != 0, suspendStartTimeUs)); 7225 7226 if (err != OK) { 7227 ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err); 7228 return err; 7229 } 7230 } 7231 7232 int64_t stopTimeUs; 7233 if (params->findInt64("stop-time-us", &stopTimeUs)) { 7234 if (mGraphicBufferSource == NULL) { 7235 ALOGE("[%s] Invalid to set stop time without surface", 7236 mComponentName.c_str()); 7237 return INVALID_OPERATION; 7238 } 7239 status_t err = statusFromBinderStatus( 7240 mGraphicBufferSource->setStopTimeUs(stopTimeUs)); 7241 7242 if (err != OK) { 7243 ALOGE("Failed to set parameter 'stop-time-us' (err %d)", err); 7244 return err; 7245 } 7246 } 7247 7248 int32_t dummy; 7249 if (params->findInt32("request-sync", &dummy)) { 7250 status_t err = requestIDRFrame(); 7251 7252 if (err != OK) { 7253 ALOGE("Requesting a sync frame failed w/ err %d", err); 7254 return err; 7255 } 7256 } 7257 7258 float rate; 7259 if (params->findFloat("operating-rate", &rate) && rate > 0) { 7260 status_t err = setOperatingRate(rate, mIsVideo); 7261 if (err != OK) { 7262 ALOGE("Failed to set parameter 'operating-rate' (err %d)", err); 7263 return err; 7264 } 7265 } 7266 7267 int32_t intraRefreshPeriod = 0; 7268 if (params->findInt32("intra-refresh-period", &intraRefreshPeriod) 7269 && intraRefreshPeriod > 0) { 7270 status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false); 7271 if (err != OK) { 7272 ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional", 7273 mComponentName.c_str()); 7274 err = OK; 7275 } 7276 } 7277 7278 int32_t latency = 0; 7279 if (params->findInt32("latency", &latency) && latency > 0) { 7280 status_t err = setLatency(latency); 7281 if (err != OK) { 7282 ALOGI("[%s] failed setLatency. Failure is fine since this key is optional", 7283 mComponentName.c_str()); 7284 err = OK; 7285 } 7286 } 7287 7288 status_t err = configureTemporalLayers(params, false /* inConfigure */, mOutputFormat); 7289 if (err != OK) { 7290 err = OK; // ignore failure 7291 } 7292 7293 return setVendorParameters(params); 7294 } 7295 7296 // Removes trailing tags matching |tag| from |key| (e.g. a settings name). |minLength| specifies 7297 // the minimum number of characters to keep in |key| (even if it has trailing tags). 7298 // (Used to remove trailing 'value' tags in settings names, e.g. to normalize 7299 // 'vendor.settingsX.value' to 'vendor.settingsX') 7300 static void removeTrailingTags(char *key, size_t minLength, const char *tag) { 7301 size_t length = strlen(key); 7302 size_t tagLength = strlen(tag); 7303 while (length > minLength + tagLength 7304 && !strcmp(key + length - tagLength, tag) 7305 && key[length - tagLength - 1] == '.') { 7306 length -= tagLength + 1; 7307 key[length] = '\0'; 7308 } 7309 } 7310 7311 /** 7312 * Struct encompassing a vendor extension config structure and a potential error status (in case 7313 * the structure is null). Used to iterate through vendor extensions. 7314 */ 7315 struct VendorExtension { 7316 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config; // structure does not own config 7317 status_t status; 7318 7319 // create based on an error status 7320 VendorExtension(status_t s_ = NO_INIT) : config(nullptr), status(s_) { } 7321 7322 // create based on a successfully retrieved config structure 7323 VendorExtension(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *c_) : config(c_), status(OK) { } 7324 }; 7325 7326 // class VendorExtensions; 7327 /** 7328 * Forward iterator to enumerate vendor extensions supported by an OMX component. 7329 */ 7330 class VendorExtensionIterator { 7331 //private: 7332 static constexpr size_t kLastIndex = ~(size_t)0; // last index marker 7333 7334 sp<IOMXNode> mNode; // component 7335 size_t mIndex; // current android extension index 7336 std::unique_ptr<uint8_t[]> mBacking; // current extension's backing 7337 VendorExtension mCurrent; // current extension 7338 7339 VendorExtensionIterator(const sp<IOMXNode> &node, size_t index) 7340 : mNode(node), 7341 mIndex(index) { 7342 mCurrent = retrieve(); 7343 } 7344 7345 friend class VendorExtensions; 7346 7347 public: 7348 // copy constructor 7349 VendorExtensionIterator(const VendorExtensionIterator &it) 7350 : VendorExtensionIterator(it.mNode, it.mIndex) { } 7351 7352 // retrieves the current extension pointed to by this iterator 7353 VendorExtension retrieve() { 7354 if (mIndex == kLastIndex) { 7355 return NO_INIT; 7356 } 7357 7358 // try with one param first, then retry if extension needs more than 1 param 7359 for (size_t paramSizeUsed = 1;; ) { 7360 if (paramSizeUsed > OMX_MAX_ANDROID_VENDOR_PARAMCOUNT) { 7361 return BAD_VALUE; // this prevents overflow in the following formula 7362 } 7363 7364 size_t size = sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE) + 7365 (paramSizeUsed - 1) * sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::param); 7366 mBacking.reset(new uint8_t[size]); 7367 if (!mBacking) { 7368 return NO_MEMORY; 7369 } 7370 7371 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = 7372 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(mBacking.get()); 7373 7374 InitOMXParams(config); 7375 config->nSize = size; 7376 config->nIndex = mIndex; 7377 config->nParamSizeUsed = paramSizeUsed; 7378 status_t err = mNode->getConfig( 7379 (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension, config, size); 7380 if (err == OK && config->nParamCount > paramSizeUsed && paramSizeUsed == 1) { 7381 // reallocate if we need a bigger config 7382 paramSizeUsed = config->nParamCount; 7383 continue; 7384 } else if (err == NOT_ENOUGH_DATA 7385 || (err != OK && mIndex == 0)) { 7386 // stop iterator on no-more signal, or if index is not at all supported 7387 mIndex = kLastIndex; 7388 return NO_INIT; 7389 } else if (err != OK) { 7390 return err; 7391 } else if (paramSizeUsed != config->nParamSizeUsed) { 7392 return BAD_VALUE; // component shall not modify size of nParam 7393 } 7394 7395 return config; 7396 } 7397 } 7398 7399 // returns extension pointed to by this iterator 7400 VendorExtension operator*() { 7401 return mCurrent; 7402 } 7403 7404 // prefix increment: move to next extension 7405 VendorExtensionIterator &operator++() { // prefix 7406 if (mIndex != kLastIndex) { 7407 ++mIndex; 7408 mCurrent = retrieve(); 7409 } 7410 return *this; 7411 } 7412 7413 // iterator equality operators 7414 bool operator==(const VendorExtensionIterator &o) { 7415 return mNode == o.mNode && mIndex == o.mIndex; 7416 } 7417 7418 bool operator!=(const VendorExtensionIterator &o) { 7419 return !(*this == o); 7420 } 7421 }; 7422 7423 /** 7424 * Iterable container for vendor extensions provided by a component 7425 */ 7426 class VendorExtensions { 7427 //private: 7428 sp<IOMXNode> mNode; 7429 7430 public: 7431 VendorExtensions(const sp<IOMXNode> &node) 7432 : mNode(node) { 7433 } 7434 7435 VendorExtensionIterator begin() { 7436 return VendorExtensionIterator(mNode, 0); 7437 } 7438 7439 VendorExtensionIterator end() { 7440 return VendorExtensionIterator(mNode, VendorExtensionIterator::kLastIndex); 7441 } 7442 }; 7443 7444 status_t ACodec::setVendorParameters(const sp<AMessage> ¶ms) { 7445 std::map<std::string, std::string> vendorKeys; // maps reduced name to actual name 7446 constexpr char prefix[] = "vendor."; 7447 constexpr size_t prefixLength = sizeof(prefix) - 1; 7448 // longest possible vendor param name 7449 char reducedKey[OMX_MAX_STRINGNAME_SIZE + OMX_MAX_STRINGVALUE_SIZE]; 7450 7451 // identify all vendor keys to speed up search later and to detect vendor keys 7452 for (size_t i = params->countEntries(); i; --i) { 7453 AMessage::Type keyType; 7454 const char* key = params->getEntryNameAt(i - 1, &keyType); 7455 if (key != nullptr && !strncmp(key, prefix, prefixLength) 7456 // it is safe to limit format keys to the max vendor param size as we only 7457 // shorten parameter names by removing any trailing 'value' tags, and we 7458 // already remove the vendor prefix. 7459 && strlen(key + prefixLength) < sizeof(reducedKey) 7460 && (keyType == AMessage::kTypeInt32 7461 || keyType == AMessage::kTypeInt64 7462 || keyType == AMessage::kTypeString)) { 7463 strcpy(reducedKey, key + prefixLength); 7464 removeTrailingTags(reducedKey, 0, "value"); 7465 auto existingKey = vendorKeys.find(reducedKey); 7466 if (existingKey != vendorKeys.end()) { 7467 ALOGW("[%s] vendor parameter '%s' aliases parameter '%s'", 7468 mComponentName.c_str(), key, existingKey->second.c_str()); 7469 // ignore for now 7470 } 7471 vendorKeys.emplace(reducedKey, key); 7472 } 7473 } 7474 7475 // don't bother component if we don't have vendor extensions as they may not have implemented 7476 // the android vendor extension support, which will lead to unnecessary OMX failure logs. 7477 if (vendorKeys.empty()) { 7478 return OK; 7479 } 7480 7481 char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) + 7482 sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey)]; 7483 7484 status_t finalError = OK; 7485 7486 // don't try again if component does not have vendor extensions 7487 if (mVendorExtensionsStatus == kExtensionsNone) { 7488 return OK; 7489 } 7490 7491 for (VendorExtension ext : VendorExtensions(mOMXNode)) { 7492 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config; 7493 if (config == nullptr) { 7494 return ext.status; 7495 } 7496 7497 mVendorExtensionsStatus = kExtensionsExist; 7498 7499 config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name 7500 strcpy(key, (const char *)config->cName); 7501 size_t nameLength = strlen(key); 7502 key[nameLength] = '.'; 7503 7504 // don't set vendor extension if client has not provided any of its parameters 7505 // or if client simply unsets parameters that are already unset 7506 bool needToSet = false; 7507 for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) { 7508 // null-terminate param key 7509 config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0'; 7510 strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey); 7511 removeTrailingTags(key, nameLength, "value"); 7512 auto existingKey = vendorKeys.find(key); 7513 7514 // don't touch (e.g. change) parameters that are not specified by client 7515 if (existingKey == vendorKeys.end()) { 7516 continue; 7517 } 7518 7519 bool wasSet = config->param[paramIndex].bSet; 7520 switch (config->param[paramIndex].eValueType) { 7521 case OMX_AndroidVendorValueInt32: 7522 { 7523 int32_t value; 7524 config->param[paramIndex].bSet = 7525 (OMX_BOOL)params->findInt32(existingKey->second.c_str(), &value); 7526 if (config->param[paramIndex].bSet) { 7527 config->param[paramIndex].nInt32 = value; 7528 } 7529 break; 7530 } 7531 case OMX_AndroidVendorValueInt64: 7532 { 7533 int64_t value; 7534 config->param[paramIndex].bSet = 7535 (OMX_BOOL)params->findAsInt64(existingKey->second.c_str(), &value); 7536 if (config->param[paramIndex].bSet) { 7537 config->param[paramIndex].nInt64 = value; 7538 } 7539 break; 7540 } 7541 case OMX_AndroidVendorValueString: 7542 { 7543 AString value; 7544 config->param[paramIndex].bSet = 7545 (OMX_BOOL)params->findString(existingKey->second.c_str(), &value); 7546 if (config->param[paramIndex].bSet) { 7547 strncpy((char *)config->param[paramIndex].cString, value.c_str(), 7548 sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cString)); 7549 } 7550 break; 7551 } 7552 default: 7553 ALOGW("[%s] vendor parameter '%s' is not a supported value", 7554 mComponentName.c_str(), key); 7555 continue; 7556 } 7557 if (config->param[paramIndex].bSet || wasSet) { 7558 needToSet = true; 7559 } 7560 } 7561 7562 if (needToSet) { 7563 status_t err = mOMXNode->setConfig( 7564 (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension, 7565 config, config->nSize); 7566 if (err != OK) { 7567 key[nameLength] = '\0'; 7568 ALOGW("[%s] failed to set vendor extension '%s'", mComponentName.c_str(), key); 7569 // try to set each extension, and return first failure 7570 if (finalError == OK) { 7571 finalError = err; 7572 } 7573 } 7574 } 7575 } 7576 7577 if (mVendorExtensionsStatus == kExtensionsUnchecked) { 7578 mVendorExtensionsStatus = kExtensionsNone; 7579 } 7580 7581 return finalError; 7582 } 7583 7584 status_t ACodec::getVendorParameters(OMX_U32 portIndex, sp<AMessage> &format) { 7585 constexpr char prefix[] = "vendor."; 7586 constexpr size_t prefixLength = sizeof(prefix) - 1; 7587 char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) + 7588 sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey) + prefixLength]; 7589 strcpy(key, prefix); 7590 7591 // don't try again if component does not have vendor extensions 7592 if (mVendorExtensionsStatus == kExtensionsNone) { 7593 return OK; 7594 } 7595 7596 for (VendorExtension ext : VendorExtensions(mOMXNode)) { 7597 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config; 7598 if (config == nullptr) { 7599 return ext.status; 7600 } 7601 7602 mVendorExtensionsStatus = kExtensionsExist; 7603 7604 if (config->eDir != (portIndex == kPortIndexInput ? OMX_DirInput : OMX_DirOutput)) { 7605 continue; 7606 } 7607 7608 config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name 7609 strcpy(key + prefixLength, (const char *)config->cName); 7610 size_t nameLength = strlen(key); 7611 key[nameLength] = '.'; 7612 7613 for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) { 7614 // null-terminate param key 7615 config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0'; 7616 strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey); 7617 removeTrailingTags(key, nameLength, "value"); 7618 if (config->param[paramIndex].bSet) { 7619 switch (config->param[paramIndex].eValueType) { 7620 case OMX_AndroidVendorValueInt32: 7621 { 7622 format->setInt32(key, config->param[paramIndex].nInt32); 7623 break; 7624 } 7625 case OMX_AndroidVendorValueInt64: 7626 { 7627 format->setInt64(key, config->param[paramIndex].nInt64); 7628 break; 7629 } 7630 case OMX_AndroidVendorValueString: 7631 { 7632 config->param[paramIndex].cString[OMX_MAX_STRINGVALUE_SIZE - 1] = '\0'; 7633 format->setString(key, (const char *)config->param[paramIndex].cString); 7634 break; 7635 } 7636 default: 7637 ALOGW("vendor parameter %s is not a supported value", key); 7638 continue; 7639 } 7640 } 7641 } 7642 } 7643 7644 if (mVendorExtensionsStatus == kExtensionsUnchecked) { 7645 mVendorExtensionsStatus = kExtensionsNone; 7646 } 7647 7648 return OK; 7649 } 7650 7651 void ACodec::onSignalEndOfInputStream() { 7652 status_t err = INVALID_OPERATION; 7653 if (mGraphicBufferSource != NULL) { 7654 err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream()); 7655 } 7656 mCallback->onSignaledInputEOS(err); 7657 } 7658 7659 void ACodec::forceStateTransition(int generation) { 7660 if (generation != mStateGeneration) { 7661 ALOGV("Ignoring stale force state transition message: #%d (now #%d)", 7662 generation, mStateGeneration); 7663 return; 7664 } 7665 ALOGE("State machine stuck"); 7666 // Error must have already been signalled to the client. 7667 7668 // Deferred messages will be handled at LoadedState at the end of the 7669 // transition. 7670 mShutdownInProgress = true; 7671 // No shutdown complete callback at the end of the transition. 7672 mExplicitShutdown = false; 7673 mKeepComponentAllocated = true; 7674 7675 status_t err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle); 7676 if (err != OK) { 7677 // TODO: do some recovery here. 7678 } else { 7679 changeState(mExecutingToIdleState); 7680 } 7681 } 7682 7683 bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { 7684 mCodec->onFrameRendered(mediaTimeUs, systemNano); 7685 return true; 7686 } 7687 7688 bool ACodec::ExecutingState::onOMXEvent( 7689 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7690 switch (event) { 7691 case OMX_EventPortSettingsChanged: 7692 { 7693 CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 7694 7695 mCodec->onOutputFormatChanged(); 7696 7697 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 7698 mCodec->mMetadataBuffersToSubmit = 0; 7699 CHECK_EQ(mCodec->mOMXNode->sendCommand( 7700 OMX_CommandPortDisable, kPortIndexOutput), 7701 (status_t)OK); 7702 7703 mCodec->freeOutputBuffersNotOwnedByComponent(); 7704 7705 mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 7706 } else if (data2 != OMX_IndexConfigCommonOutputCrop 7707 && data2 != OMX_IndexConfigAndroidIntraRefresh) { 7708 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x", 7709 mCodec->mComponentName.c_str(), data2); 7710 } 7711 7712 return true; 7713 } 7714 7715 case OMX_EventBufferFlag: 7716 { 7717 return true; 7718 } 7719 7720 default: 7721 return BaseState::onOMXEvent(event, data1, data2); 7722 } 7723 } 7724 7725 //////////////////////////////////////////////////////////////////////////////// 7726 7727 ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 7728 ACodec *codec) 7729 : BaseState(codec) { 7730 } 7731 7732 ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 7733 OMX_U32 portIndex) { 7734 if (portIndex == kPortIndexOutput) { 7735 return FREE_BUFFERS; 7736 } 7737 7738 CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 7739 7740 return RESUBMIT_BUFFERS; 7741 } 7742 7743 bool ACodec::OutputPortSettingsChangedState::onMessageReceived( 7744 const sp<AMessage> &msg) { 7745 bool handled = false; 7746 7747 switch (msg->what()) { 7748 case kWhatFlush: 7749 case kWhatShutdown: { 7750 if (mCodec->mFatalError) { 7751 sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec); 7752 msg->setInt32("generation", mCodec->mStateGeneration); 7753 msg->post(3000000); 7754 } 7755 // fall-through 7756 } 7757 case kWhatResume: 7758 case kWhatSetParameters: 7759 { 7760 if (msg->what() == kWhatResume) { 7761 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 7762 } 7763 7764 mCodec->deferMessage(msg); 7765 handled = true; 7766 break; 7767 } 7768 7769 case kWhatForceStateTransition: 7770 { 7771 int32_t generation = 0; 7772 CHECK(msg->findInt32("generation", &generation)); 7773 mCodec->forceStateTransition(generation); 7774 7775 handled = true; 7776 break; 7777 } 7778 7779 default: 7780 handled = BaseState::onMessageReceived(msg); 7781 break; 7782 } 7783 7784 return handled; 7785 } 7786 7787 void ACodec::OutputPortSettingsChangedState::stateEntered() { 7788 ALOGV("[%s] Now handling output port settings change", 7789 mCodec->mComponentName.c_str()); 7790 } 7791 7792 bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered( 7793 int64_t mediaTimeUs, nsecs_t systemNano) { 7794 mCodec->onFrameRendered(mediaTimeUs, systemNano); 7795 return true; 7796 } 7797 7798 bool ACodec::OutputPortSettingsChangedState::onOMXEvent( 7799 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7800 switch (event) { 7801 case OMX_EventCmdComplete: 7802 { 7803 if (data1 == (OMX_U32)OMX_CommandPortDisable) { 7804 if (data2 != (OMX_U32)kPortIndexOutput) { 7805 ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2); 7806 return false; 7807 } 7808 7809 ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str()); 7810 7811 status_t err = OK; 7812 if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) { 7813 ALOGE("disabled port should be empty, but has %zu buffers", 7814 mCodec->mBuffers[kPortIndexOutput].size()); 7815 err = FAILED_TRANSACTION; 7816 } else { 7817 if (mCodec->getTrebleFlag()) { 7818 mCodec->mAllocator[kPortIndexOutput].clear(); 7819 } else { 7820 mCodec->mDealer[kPortIndexOutput].clear(); 7821 } 7822 } 7823 7824 if (err == OK) { 7825 err = mCodec->mOMXNode->sendCommand( 7826 OMX_CommandPortEnable, kPortIndexOutput); 7827 } 7828 7829 if (err == OK) { 7830 err = mCodec->allocateBuffersOnPort(kPortIndexOutput); 7831 ALOGE_IF(err != OK, "Failed to allocate output port buffers after port " 7832 "reconfiguration: (%d)", err); 7833 mCodec->mCallback->onOutputBuffersChanged(); 7834 } 7835 7836 if (err != OK) { 7837 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 7838 ALOGE("Error occurred while disabling the output port"); 7839 } 7840 7841 return true; 7842 } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 7843 if (data2 != (OMX_U32)kPortIndexOutput) { 7844 ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2); 7845 return false; 7846 } 7847 7848 ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str()); 7849 7850 if (mCodec->mExecutingState->active()) { 7851 mCodec->mExecutingState->submitOutputBuffers(); 7852 } 7853 7854 mCodec->changeState(mCodec->mExecutingState); 7855 7856 return true; 7857 } 7858 7859 return false; 7860 } 7861 7862 default: 7863 return BaseState::onOMXEvent(event, data1, data2); 7864 } 7865 } 7866 7867 //////////////////////////////////////////////////////////////////////////////// 7868 7869 ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 7870 : BaseState(codec), 7871 mComponentNowIdle(false) { 7872 } 7873 7874 bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 7875 bool handled = false; 7876 7877 switch (msg->what()) { 7878 case kWhatFlush: 7879 { 7880 // Don't send me a flush request if you previously wanted me 7881 // to shutdown. 7882 ALOGW("Ignoring flush request in ExecutingToIdleState"); 7883 break; 7884 } 7885 7886 case kWhatShutdown: 7887 { 7888 mCodec->deferMessage(msg); 7889 handled = true; 7890 break; 7891 } 7892 7893 default: 7894 handled = BaseState::onMessageReceived(msg); 7895 break; 7896 } 7897 7898 return handled; 7899 } 7900 7901 void ACodec::ExecutingToIdleState::stateEntered() { 7902 ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 7903 7904 mComponentNowIdle = false; 7905 mCodec->mLastOutputFormat.clear(); 7906 } 7907 7908 bool ACodec::ExecutingToIdleState::onOMXEvent( 7909 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7910 switch (event) { 7911 case OMX_EventCmdComplete: 7912 { 7913 if (data1 != (OMX_U32)OMX_CommandStateSet 7914 || data2 != (OMX_U32)OMX_StateIdle) { 7915 ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)", 7916 asString((OMX_COMMANDTYPE)data1), data1, 7917 asString((OMX_STATETYPE)data2), data2); 7918 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7919 return true; 7920 } 7921 7922 mComponentNowIdle = true; 7923 7924 changeStateIfWeOwnAllBuffers(); 7925 7926 return true; 7927 } 7928 7929 case OMX_EventPortSettingsChanged: 7930 case OMX_EventBufferFlag: 7931 { 7932 // We're shutting down and don't care about this anymore. 7933 return true; 7934 } 7935 7936 default: 7937 return BaseState::onOMXEvent(event, data1, data2); 7938 } 7939 } 7940 7941 void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 7942 if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) { 7943 status_t err = mCodec->mOMXNode->sendCommand( 7944 OMX_CommandStateSet, OMX_StateLoaded); 7945 if (err == OK) { 7946 err = mCodec->freeBuffersOnPort(kPortIndexInput); 7947 status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput); 7948 if (err == OK) { 7949 err = err2; 7950 } 7951 } 7952 7953 if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) 7954 && mCodec->mNativeWindow != NULL) { 7955 // We push enough 1x1 blank buffers to ensure that one of 7956 // them has made it to the display. This allows the OMX 7957 // component teardown to zero out any protected buffers 7958 // without the risk of scanning out one of those buffers. 7959 pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get()); 7960 } 7961 7962 if (err != OK) { 7963 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7964 return; 7965 } 7966 7967 mCodec->changeState(mCodec->mIdleToLoadedState); 7968 } 7969 } 7970 7971 void ACodec::ExecutingToIdleState::onInputBufferFilled( 7972 const sp<AMessage> &msg) { 7973 BaseState::onInputBufferFilled(msg); 7974 7975 changeStateIfWeOwnAllBuffers(); 7976 } 7977 7978 void ACodec::ExecutingToIdleState::onOutputBufferDrained( 7979 const sp<AMessage> &msg) { 7980 BaseState::onOutputBufferDrained(msg); 7981 7982 changeStateIfWeOwnAllBuffers(); 7983 } 7984 7985 //////////////////////////////////////////////////////////////////////////////// 7986 7987 ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 7988 : BaseState(codec) { 7989 } 7990 7991 bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 7992 bool handled = false; 7993 7994 switch (msg->what()) { 7995 case kWhatShutdown: 7996 { 7997 mCodec->deferMessage(msg); 7998 handled = true; 7999 break; 8000 } 8001 8002 case kWhatFlush: 8003 { 8004 // Don't send me a flush request if you previously wanted me 8005 // to shutdown. 8006 ALOGE("Got flush request in IdleToLoadedState"); 8007 break; 8008 } 8009 8010 default: 8011 handled = BaseState::onMessageReceived(msg); 8012 break; 8013 } 8014 8015 return handled; 8016 } 8017 8018 void ACodec::IdleToLoadedState::stateEntered() { 8019 ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 8020 } 8021 8022 bool ACodec::IdleToLoadedState::onOMXEvent( 8023 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 8024 switch (event) { 8025 case OMX_EventCmdComplete: 8026 { 8027 if (data1 != (OMX_U32)OMX_CommandStateSet 8028 || data2 != (OMX_U32)OMX_StateLoaded) { 8029 ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)", 8030 asString((OMX_COMMANDTYPE)data1), data1, 8031 asString((OMX_STATETYPE)data2), data2); 8032 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 8033 return true; 8034 } 8035 8036 mCodec->changeState(mCodec->mLoadedState); 8037 8038 return true; 8039 } 8040 8041 default: 8042 return BaseState::onOMXEvent(event, data1, data2); 8043 } 8044 } 8045 8046 //////////////////////////////////////////////////////////////////////////////// 8047 8048 ACodec::FlushingState::FlushingState(ACodec *codec) 8049 : BaseState(codec) { 8050 } 8051 8052 void ACodec::FlushingState::stateEntered() { 8053 ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 8054 8055 mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 8056 } 8057 8058 bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 8059 bool handled = false; 8060 8061 switch (msg->what()) { 8062 case kWhatShutdown: 8063 { 8064 mCodec->deferMessage(msg); 8065 if (mCodec->mFatalError) { 8066 sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec); 8067 msg->setInt32("generation", mCodec->mStateGeneration); 8068 msg->post(3000000); 8069 } 8070 break; 8071 } 8072 8073 case kWhatFlush: 8074 { 8075 // We're already doing this right now. 8076 handled = true; 8077 break; 8078 } 8079 8080 case kWhatForceStateTransition: 8081 { 8082 int32_t generation = 0; 8083 CHECK(msg->findInt32("generation", &generation)); 8084 mCodec->forceStateTransition(generation); 8085 8086 handled = true; 8087 break; 8088 } 8089 8090 default: 8091 handled = BaseState::onMessageReceived(msg); 8092 break; 8093 } 8094 8095 return handled; 8096 } 8097 8098 bool ACodec::FlushingState::onOMXEvent( 8099 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 8100 ALOGV("[%s] FlushingState onOMXEvent(%u,%d)", 8101 mCodec->mComponentName.c_str(), event, (OMX_S32)data1); 8102 8103 switch (event) { 8104 case OMX_EventCmdComplete: 8105 { 8106 if (data1 != (OMX_U32)OMX_CommandFlush) { 8107 ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState", 8108 asString((OMX_COMMANDTYPE)data1), data1, data2); 8109 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 8110 return true; 8111 } 8112 8113 if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 8114 if (mFlushComplete[data2]) { 8115 ALOGW("Flush already completed for %s port", 8116 data2 == kPortIndexInput ? "input" : "output"); 8117 return true; 8118 } 8119 mFlushComplete[data2] = true; 8120 8121 if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) { 8122 changeStateIfWeOwnAllBuffers(); 8123 } 8124 } else if (data2 == OMX_ALL) { 8125 if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) { 8126 ALOGW("received flush complete event for OMX_ALL before ports have been" 8127 "flushed (%d/%d)", 8128 mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]); 8129 return false; 8130 } 8131 8132 changeStateIfWeOwnAllBuffers(); 8133 } else { 8134 ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2); 8135 } 8136 8137 return true; 8138 } 8139 8140 case OMX_EventPortSettingsChanged: 8141 { 8142 sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec); 8143 msg->setInt32("type", omx_message::EVENT); 8144 msg->setInt32("generation", mCodec->mNodeGeneration); 8145 msg->setInt32("event", event); 8146 msg->setInt32("data1", data1); 8147 msg->setInt32("data2", data2); 8148 8149 ALOGV("[%s] Deferring OMX_EventPortSettingsChanged", 8150 mCodec->mComponentName.c_str()); 8151 8152 mCodec->deferMessage(msg); 8153 8154 return true; 8155 } 8156 8157 default: 8158 return BaseState::onOMXEvent(event, data1, data2); 8159 } 8160 8161 return true; 8162 } 8163 8164 void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 8165 BaseState::onOutputBufferDrained(msg); 8166 8167 changeStateIfWeOwnAllBuffers(); 8168 } 8169 8170 void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 8171 BaseState::onInputBufferFilled(msg); 8172 8173 changeStateIfWeOwnAllBuffers(); 8174 } 8175 8176 void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 8177 if (mFlushComplete[kPortIndexInput] 8178 && mFlushComplete[kPortIndexOutput] 8179 && mCodec->allYourBuffersAreBelongToUs()) { 8180 // We now own all buffers except possibly those still queued with 8181 // the native window for rendering. Let's get those back as well. 8182 mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs(); 8183 8184 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 8185 8186 mCodec->mCallback->onFlushCompleted(); 8187 8188 mCodec->mPortEOS[kPortIndexInput] = 8189 mCodec->mPortEOS[kPortIndexOutput] = false; 8190 8191 mCodec->mInputEOSResult = OK; 8192 8193 if (mCodec->mSkipCutBuffer != NULL) { 8194 mCodec->mSkipCutBuffer->clear(); 8195 } 8196 8197 mCodec->changeState(mCodec->mExecutingState); 8198 } 8199 } 8200 8201 status_t ACodec::queryCapabilities( 8202 const AString &name, const AString &mime, bool isEncoder, 8203 sp<MediaCodecInfo::Capabilities> *caps) { 8204 (*caps).clear(); 8205 const char *role = GetComponentRole(isEncoder, mime.c_str()); 8206 if (role == NULL) { 8207 return BAD_VALUE; 8208 } 8209 8210 OMXClient client; 8211 status_t err = client.connect(); 8212 if (err != OK) { 8213 return err; 8214 } 8215 8216 sp<IOMX> omx = client.interface(); 8217 sp<CodecObserver> observer = new CodecObserver; 8218 sp<IOMXNode> omxNode; 8219 8220 err = omx->allocateNode(name.c_str(), observer, &omxNode); 8221 if (err != OK) { 8222 client.disconnect(); 8223 return err; 8224 } 8225 8226 err = SetComponentRole(omxNode, role); 8227 if (err != OK) { 8228 omxNode->freeNode(); 8229 client.disconnect(); 8230 return err; 8231 } 8232 8233 sp<MediaCodecInfo::CapabilitiesBuilder> builder = new MediaCodecInfo::CapabilitiesBuilder(); 8234 bool isVideo = mime.startsWithIgnoreCase("video/"); 8235 8236 if (isVideo) { 8237 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 8238 InitOMXParams(¶m); 8239 param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput; 8240 8241 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 8242 param.nProfileIndex = index; 8243 status_t err = omxNode->getParameter( 8244 OMX_IndexParamVideoProfileLevelQuerySupported, 8245 ¶m, sizeof(param)); 8246 if (err != OK) { 8247 break; 8248 } 8249 builder->addProfileLevel(param.eProfile, param.eLevel); 8250 8251 if (index == kMaxIndicesToCheck) { 8252 ALOGW("[%s] stopping checking profiles after %u: %x/%x", 8253 name.c_str(), index, 8254 param.eProfile, param.eLevel); 8255 } 8256 } 8257 8258 // Color format query 8259 // return colors in the order reported by the OMX component 8260 // prefix "flexible" standard ones with the flexible equivalent 8261 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 8262 InitOMXParams(&portFormat); 8263 portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput; 8264 Vector<uint32_t> supportedColors; // shadow copy to check for duplicates 8265 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 8266 portFormat.nIndex = index; 8267 status_t err = omxNode->getParameter( 8268 OMX_IndexParamVideoPortFormat, 8269 &portFormat, sizeof(portFormat)); 8270 if (err != OK) { 8271 break; 8272 } 8273 8274 OMX_U32 flexibleEquivalent; 8275 if (IsFlexibleColorFormat( 8276 omxNode, portFormat.eColorFormat, false /* usingNativeWindow */, 8277 &flexibleEquivalent)) { 8278 bool marked = false; 8279 for (size_t i = 0; i < supportedColors.size(); ++i) { 8280 if (supportedColors[i] == flexibleEquivalent) { 8281 marked = true; 8282 break; 8283 } 8284 } 8285 if (!marked) { 8286 supportedColors.push(flexibleEquivalent); 8287 builder->addColorFormat(flexibleEquivalent); 8288 } 8289 } 8290 supportedColors.push(portFormat.eColorFormat); 8291 builder->addColorFormat(portFormat.eColorFormat); 8292 8293 if (index == kMaxIndicesToCheck) { 8294 ALOGW("[%s] stopping checking formats after %u: %s(%x)", 8295 name.c_str(), index, 8296 asString(portFormat.eColorFormat), portFormat.eColorFormat); 8297 } 8298 } 8299 } else if (mime.equalsIgnoreCase(MEDIA_MIMETYPE_AUDIO_AAC)) { 8300 // More audio codecs if they have profiles. 8301 OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param; 8302 InitOMXParams(¶m); 8303 param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput; 8304 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 8305 param.nProfileIndex = index; 8306 status_t err = omxNode->getParameter( 8307 (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported, 8308 ¶m, sizeof(param)); 8309 if (err != OK) { 8310 break; 8311 } 8312 // For audio, level is ignored. 8313 builder->addProfileLevel(param.eProfile, 0 /* level */); 8314 8315 if (index == kMaxIndicesToCheck) { 8316 ALOGW("[%s] stopping checking profiles after %u: %x", 8317 name.c_str(), index, 8318 param.eProfile); 8319 } 8320 } 8321 8322 // NOTE: Without Android extensions, OMX does not provide a way to query 8323 // AAC profile support 8324 if (param.nProfileIndex == 0) { 8325 ALOGW("component %s doesn't support profile query.", name.c_str()); 8326 } 8327 } 8328 8329 if (isVideo && !isEncoder) { 8330 native_handle_t *sidebandHandle = NULL; 8331 if (omxNode->configureVideoTunnelMode( 8332 kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) { 8333 // tunneled playback includes adaptive playback 8334 builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback 8335 | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback); 8336 } else if (omxNode->setPortMode( 8337 kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK || 8338 omxNode->prepareForAdaptivePlayback( 8339 kPortIndexOutput, OMX_TRUE, 8340 1280 /* width */, 720 /* height */) == OK) { 8341 builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback); 8342 } 8343 } 8344 8345 if (isVideo && isEncoder) { 8346 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params; 8347 InitOMXParams(¶ms); 8348 params.nPortIndex = kPortIndexOutput; 8349 // TODO: should we verify if fallback is supported? 8350 if (omxNode->getConfig( 8351 (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, 8352 ¶ms, sizeof(params)) == OK) { 8353 builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh); 8354 } 8355 } 8356 8357 *caps = builder; 8358 omxNode->freeNode(); 8359 client.disconnect(); 8360 return OK; 8361 } 8362 8363 // These are supposed be equivalent to the logic in 8364 // "audio_channel_out_mask_from_count". 8365 //static 8366 status_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) { 8367 switch (numChannels) { 8368 case 1: 8369 map[0] = OMX_AUDIO_ChannelCF; 8370 break; 8371 case 2: 8372 map[0] = OMX_AUDIO_ChannelLF; 8373 map[1] = OMX_AUDIO_ChannelRF; 8374 break; 8375 case 3: 8376 map[0] = OMX_AUDIO_ChannelLF; 8377 map[1] = OMX_AUDIO_ChannelRF; 8378 map[2] = OMX_AUDIO_ChannelCF; 8379 break; 8380 case 4: 8381 map[0] = OMX_AUDIO_ChannelLF; 8382 map[1] = OMX_AUDIO_ChannelRF; 8383 map[2] = OMX_AUDIO_ChannelLR; 8384 map[3] = OMX_AUDIO_ChannelRR; 8385 break; 8386 case 5: 8387 map[0] = OMX_AUDIO_ChannelLF; 8388 map[1] = OMX_AUDIO_ChannelRF; 8389 map[2] = OMX_AUDIO_ChannelCF; 8390 map[3] = OMX_AUDIO_ChannelLR; 8391 map[4] = OMX_AUDIO_ChannelRR; 8392 break; 8393 case 6: 8394 map[0] = OMX_AUDIO_ChannelLF; 8395 map[1] = OMX_AUDIO_ChannelRF; 8396 map[2] = OMX_AUDIO_ChannelCF; 8397 map[3] = OMX_AUDIO_ChannelLFE; 8398 map[4] = OMX_AUDIO_ChannelLR; 8399 map[5] = OMX_AUDIO_ChannelRR; 8400 break; 8401 case 7: 8402 map[0] = OMX_AUDIO_ChannelLF; 8403 map[1] = OMX_AUDIO_ChannelRF; 8404 map[2] = OMX_AUDIO_ChannelCF; 8405 map[3] = OMX_AUDIO_ChannelLFE; 8406 map[4] = OMX_AUDIO_ChannelLR; 8407 map[5] = OMX_AUDIO_ChannelRR; 8408 map[6] = OMX_AUDIO_ChannelCS; 8409 break; 8410 case 8: 8411 map[0] = OMX_AUDIO_ChannelLF; 8412 map[1] = OMX_AUDIO_ChannelRF; 8413 map[2] = OMX_AUDIO_ChannelCF; 8414 map[3] = OMX_AUDIO_ChannelLFE; 8415 map[4] = OMX_AUDIO_ChannelLR; 8416 map[5] = OMX_AUDIO_ChannelRR; 8417 map[6] = OMX_AUDIO_ChannelLS; 8418 map[7] = OMX_AUDIO_ChannelRS; 8419 break; 8420 default: 8421 return -EINVAL; 8422 } 8423 8424 return OK; 8425 } 8426 8427 void ACodec::setTrebleFlag(bool trebleFlag) { 8428 mTrebleFlag = trebleFlag; 8429 } 8430 8431 bool ACodec::getTrebleFlag() const { 8432 return mTrebleFlag; 8433 } 8434 8435 } // namespace android 8436