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