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