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