ACodec.cpp revision d91dc5a0602f54fc0d4d2187f37b5b8169bb62c3
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/avc_utils.h> 34#include <media/stagefright/foundation/hexdump.h> 35#include <media/stagefright/foundation/ABuffer.h> 36#include <media/stagefright/foundation/ADebug.h> 37#include <media/stagefright/foundation/AMessage.h> 38#include <media/stagefright/foundation/AUtils.h> 39 40#include <media/stagefright/BufferProducerWrapper.h> 41#include <media/stagefright/MediaCodec.h> 42#include <media/stagefright/MediaCodecList.h> 43#include <media/stagefright/MediaDefs.h> 44#include <media/stagefright/OMXClient.h> 45#include <media/stagefright/PersistentSurface.h> 46#include <media/stagefright/SurfaceUtils.h> 47#include <media/hardware/HardwareAPI.h> 48#include <media/OMXBuffer.h> 49#include <media/omx/1.0/WOmxNode.h> 50 51#include <hidlmemory/mapping.h> 52 53#include <media/openmax/OMX_AudioExt.h> 54#include <media/openmax/OMX_VideoExt.h> 55#include <media/openmax/OMX_Component.h> 56#include <media/openmax/OMX_IndexExt.h> 57#include <media/openmax/OMX_AsString.h> 58 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 65namespace android { 66 67using binder::Status; 68 69enum { 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 87static 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 92static 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 102static 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 118static 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 130struct MessageList : public RefBase { 131 MessageList() { 132 } 133 virtual ~MessageList() { 134 } 135 std::list<sp<AMessage> > &getList() { return mList; } 136private: 137 std::list<sp<AMessage> > mList; 138 139 DISALLOW_EVIL_CONSTRUCTORS(MessageList); 140}; 141 142static 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 149struct 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 226protected: 227 virtual ~CodecObserver() {} 228 229private: 230 sp<AMessage> mNotify; 231 232 DISALLOW_EVIL_CONSTRUCTORS(CodecObserver); 233}; 234 235//////////////////////////////////////////////////////////////////////////////// 236 237struct ACodec::BaseState : public AState { 238 explicit BaseState(ACodec *codec, const sp<AState> &parentState = NULL); 239 240protected: 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 261private: 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 289struct 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 306protected: 307 virtual ~DeathNotifier() {} 308 309private: 310 sp<AMessage> mNotify; 311 312 DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier); 313}; 314 315struct ACodec::UninitializedState : public ACodec::BaseState { 316 explicit UninitializedState(ACodec *codec); 317 318protected: 319 virtual bool onMessageReceived(const sp<AMessage> &msg); 320 virtual void stateEntered(); 321 322private: 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 333struct ACodec::LoadedState : public ACodec::BaseState { 334 explicit LoadedState(ACodec *codec); 335 336protected: 337 virtual bool onMessageReceived(const sp<AMessage> &msg); 338 virtual void stateEntered(); 339 340private: 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 356struct ACodec::LoadedToIdleState : public ACodec::BaseState { 357 explicit LoadedToIdleState(ACodec *codec); 358 359protected: 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 364private: 365 status_t allocateBuffers(); 366 367 DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState); 368}; 369 370//////////////////////////////////////////////////////////////////////////////// 371 372struct ACodec::IdleToExecutingState : public ACodec::BaseState { 373 explicit IdleToExecutingState(ACodec *codec); 374 375protected: 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 380private: 381 DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState); 382}; 383 384//////////////////////////////////////////////////////////////////////////////// 385 386struct 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 400protected: 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 408private: 409 bool mActive; 410 411 DISALLOW_EVIL_CONSTRUCTORS(ExecutingState); 412}; 413 414//////////////////////////////////////////////////////////////////////////////// 415 416struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState { 417 explicit OutputPortSettingsChangedState(ACodec *codec); 418 419protected: 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 427private: 428 DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState); 429}; 430 431//////////////////////////////////////////////////////////////////////////////// 432 433struct ACodec::ExecutingToIdleState : public ACodec::BaseState { 434 explicit ExecutingToIdleState(ACodec *codec); 435 436protected: 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 445private: 446 void changeStateIfWeOwnAllBuffers(); 447 448 bool mComponentNowIdle; 449 450 DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState); 451}; 452 453//////////////////////////////////////////////////////////////////////////////// 454 455struct ACodec::IdleToLoadedState : public ACodec::BaseState { 456 explicit IdleToLoadedState(ACodec *codec); 457 458protected: 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 464private: 465 DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState); 466}; 467 468//////////////////////////////////////////////////////////////////////////////// 469 470struct ACodec::FlushingState : public ACodec::BaseState { 471 explicit FlushingState(ACodec *codec); 472 473protected: 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 482private: 483 bool mFlushComplete[2]; 484 485 void changeStateIfWeOwnAllBuffers(); 486 487 DISALLOW_EVIL_CONSTRUCTORS(FlushingState); 488}; 489 490//////////////////////////////////////////////////////////////////////////////// 491 492void 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 501void 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 510void 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 516void 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 524ACodec::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 582ACodec::~ACodec() { 583} 584 585void ACodec::initiateSetup(const sp<AMessage> &msg) { 586 msg->setWhat(kWhatSetup); 587 msg->setTarget(this); 588 msg->post(); 589} 590 591std::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 600void ACodec::signalSetParameters(const sp<AMessage> ¶ms) { 601 sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 602 msg->setMessage("params", params); 603 msg->post(); 604} 605 606void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) { 607 msg->setWhat(kWhatAllocateComponent); 608 msg->setTarget(this); 609 msg->post(); 610} 611 612void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) { 613 msg->setWhat(kWhatConfigureComponent); 614 msg->setTarget(this); 615 msg->post(); 616} 617 618status_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 631void ACodec::initiateCreateInputSurface() { 632 (new AMessage(kWhatCreateInputSurface, this))->post(); 633} 634 635void 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 642void ACodec::signalEndOfInputStream() { 643 (new AMessage(kWhatSignalEndOfInputStream, this))->post(); 644} 645 646void ACodec::initiateStart() { 647 (new AMessage(kWhatStart, this))->post(); 648} 649 650void ACodec::signalFlush() { 651 ALOGV("[%s] signalFlush", mComponentName.c_str()); 652 (new AMessage(kWhatFlush, this))->post(); 653} 654 655void ACodec::signalResume() { 656 (new AMessage(kWhatResume, this))->post(); 657} 658 659void 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 669void 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. 678void ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() { 679 if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] && 680 mMetadataBuffersToSubmit > 0) { 681 (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post(); 682 } 683} 684 685status_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 813status_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 828status_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 1054status_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 1126status_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 1219status_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 1310status_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 1351status_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 1369status_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 1380const 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 1392void 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 1405status_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 1424void 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 1435void ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { 1436 if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) { 1437 mRenderTracker.dumpRenderQueue(); 1438 } 1439} 1440 1441void 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 1460ACodec::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 1568status_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 1592status_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 1613status_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 1658ACodec::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 1675status_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 1699status_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 1713status_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 2317status_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 2328status_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 2341status_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 2357status_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 2385status_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 2428status_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 2482status_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 2585status_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 2625status_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 2656status_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 2807status_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 2839status_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 2871static 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 2916status_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 2944status_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 2953status_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 2981status_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 3052status_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 3073status_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. 3161status_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 3210static 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 3224static 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 3240static 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 3256status_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 3279status_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 3391status_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 3400status_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 3423status_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 3445status_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 3468status_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 3480status_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 3512status_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 3540status_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 3584status_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 3604status_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 3655status_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 3669status_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 3678status_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 3699status_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 3711status_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 3939status_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 3975static 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 4002static 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 4011status_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 4093status_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 4171int /* 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 4223status_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 4390status_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 4447status_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 4545status_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 4577status_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 4597void 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 4620status_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 4644status_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 4690size_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 4704size_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 4718void 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 4732bool 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 4749bool ACodec::allYourBuffersAreBelongToUs() { 4750 return allYourBuffersAreBelongToUs(kPortIndexInput) 4751 && allYourBuffersAreBelongToUs(kPortIndexOutput); 4752} 4753 4754void ACodec::deferMessage(const sp<AMessage> &msg) { 4755 mDeferredQueue.push_back(msg); 4756} 4757 4758void 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 4768status_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 5217void 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 5256void 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 5292void 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 // avoiding 32-bit overflows in intermediate values 5302 mEncoderDelay = (int32_t)((((int64_t)mEncoderDelay) * sampleRate) / mSampleRate); 5303 mEncoderPadding = (int32_t)((((int64_t)mEncoderPadding) * sampleRate) / mSampleRate); 5304 mSampleRate = sampleRate; 5305 } 5306 if (mSkipCutBuffer != NULL) { 5307 size_t prevbufsize = mSkipCutBuffer->size(); 5308 if (prevbufsize != 0) { 5309 ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize); 5310 } 5311 } 5312 mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount); 5313 } 5314 5315 // mLastOutputFormat is not used when tunneled; doing this just to stay consistent 5316 mLastOutputFormat = mOutputFormat; 5317} 5318 5319void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) { 5320 ALOGE("signalError(omxError %#x, internalError %d)", error, internalError); 5321 5322 if (internalError == UNKNOWN_ERROR) { // find better error code 5323 const status_t omxStatus = statusFromOMXError(error); 5324 if (omxStatus != 0) { 5325 internalError = omxStatus; 5326 } else { 5327 ALOGW("Invalid OMX error %#x", error); 5328 } 5329 } 5330 5331 mFatalError = true; 5332 mCallback->onError(internalError, ACTION_CODE_FATAL); 5333} 5334 5335status_t ACodec::requestIDRFrame() { 5336 if (!mIsEncoder) { 5337 return ERROR_UNSUPPORTED; 5338 } 5339 5340 OMX_CONFIG_INTRAREFRESHVOPTYPE params; 5341 InitOMXParams(¶ms); 5342 5343 params.nPortIndex = kPortIndexOutput; 5344 params.IntraRefreshVOP = OMX_TRUE; 5345 5346 return mOMXNode->setConfig( 5347 OMX_IndexConfigVideoIntraVOPRefresh, 5348 ¶ms, 5349 sizeof(params)); 5350} 5351 5352//////////////////////////////////////////////////////////////////////////////// 5353 5354ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState) 5355 : AState(parentState), 5356 mCodec(codec) { 5357} 5358 5359ACodec::BaseState::PortMode ACodec::BaseState::getPortMode( 5360 OMX_U32 /* portIndex */) { 5361 return KEEP_BUFFERS; 5362} 5363 5364void ACodec::BaseState::stateExited() { 5365 ++mCodec->mStateGeneration; 5366} 5367 5368bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { 5369 switch (msg->what()) { 5370 case kWhatInputBufferFilled: 5371 { 5372 onInputBufferFilled(msg); 5373 break; 5374 } 5375 5376 case kWhatOutputBufferDrained: 5377 { 5378 onOutputBufferDrained(msg); 5379 break; 5380 } 5381 5382 case ACodec::kWhatOMXMessageList: 5383 { 5384 return checkOMXMessage(msg) ? onOMXMessageList(msg) : true; 5385 } 5386 5387 case ACodec::kWhatOMXMessageItem: 5388 { 5389 // no need to check as we already did it for kWhatOMXMessageList 5390 return onOMXMessage(msg); 5391 } 5392 5393 case ACodec::kWhatOMXMessage: 5394 { 5395 return checkOMXMessage(msg) ? onOMXMessage(msg) : true; 5396 } 5397 5398 case ACodec::kWhatSetSurface: 5399 { 5400 sp<AReplyToken> replyID; 5401 CHECK(msg->senderAwaitsResponse(&replyID)); 5402 5403 sp<RefBase> obj; 5404 CHECK(msg->findObject("surface", &obj)); 5405 5406 status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get())); 5407 5408 sp<AMessage> response = new AMessage; 5409 response->setInt32("err", err); 5410 response->postReply(replyID); 5411 break; 5412 } 5413 5414 case ACodec::kWhatCreateInputSurface: 5415 case ACodec::kWhatSetInputSurface: 5416 case ACodec::kWhatSignalEndOfInputStream: 5417 { 5418 // This may result in an app illegal state exception. 5419 ALOGE("Message 0x%x was not handled", msg->what()); 5420 mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION); 5421 return true; 5422 } 5423 5424 case ACodec::kWhatOMXDied: 5425 { 5426 // This will result in kFlagSawMediaServerDie handling in MediaCodec. 5427 ALOGE("OMX/mediaserver died, signalling error!"); 5428 mCodec->mGraphicBufferSource.clear(); 5429 mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT); 5430 break; 5431 } 5432 5433 case ACodec::kWhatReleaseCodecInstance: 5434 { 5435 ALOGI("[%s] forcing the release of codec", 5436 mCodec->mComponentName.c_str()); 5437 status_t err = mCodec->mOMXNode->freeNode(); 5438 ALOGE_IF("[%s] failed to release codec instance: err=%d", 5439 mCodec->mComponentName.c_str(), err); 5440 mCodec->mCallback->onReleaseCompleted(); 5441 5442 mCodec->changeState(mCodec->mUninitializedState); 5443 break; 5444 } 5445 5446 case ACodec::kWhatForceStateTransition: 5447 { 5448 ALOGV("Already transitioned --- ignore"); 5449 break; 5450 } 5451 5452 default: 5453 return false; 5454 } 5455 5456 return true; 5457} 5458 5459bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) { 5460 // there is a possibility that this is an outstanding message for a 5461 // codec that we have already destroyed 5462 if (mCodec->mOMXNode == NULL) { 5463 ALOGI("ignoring message as already freed component: %s", 5464 msg->debugString().c_str()); 5465 return false; 5466 } 5467 5468 int32_t generation; 5469 CHECK(msg->findInt32("generation", (int32_t*)&generation)); 5470 if (generation != mCodec->mNodeGeneration) { 5471 ALOGW("Unexpected message for component: %s, gen %u, cur %u", 5472 msg->debugString().c_str(), generation, mCodec->mNodeGeneration); 5473 return false; 5474 } 5475 return true; 5476} 5477 5478bool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) { 5479 sp<RefBase> obj; 5480 CHECK(msg->findObject("messages", &obj)); 5481 sp<MessageList> msgList = static_cast<MessageList *>(obj.get()); 5482 5483 bool receivedRenderedEvents = false; 5484 for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin(); 5485 it != msgList->getList().cend(); ++it) { 5486 (*it)->setWhat(ACodec::kWhatOMXMessageItem); 5487 mCodec->handleMessage(*it); 5488 int32_t type; 5489 CHECK((*it)->findInt32("type", &type)); 5490 if (type == omx_message::FRAME_RENDERED) { 5491 receivedRenderedEvents = true; 5492 } 5493 } 5494 5495 if (receivedRenderedEvents) { 5496 // NOTE: all buffers are rendered in this case 5497 mCodec->notifyOfRenderedFrames(); 5498 } 5499 return true; 5500} 5501 5502bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { 5503 int32_t type; 5504 CHECK(msg->findInt32("type", &type)); 5505 5506 switch (type) { 5507 case omx_message::EVENT: 5508 { 5509 int32_t event, data1, data2; 5510 CHECK(msg->findInt32("event", &event)); 5511 CHECK(msg->findInt32("data1", &data1)); 5512 CHECK(msg->findInt32("data2", &data2)); 5513 5514 if (event == OMX_EventCmdComplete 5515 && data1 == OMX_CommandFlush 5516 && data2 == (int32_t)OMX_ALL) { 5517 // Use of this notification is not consistent across 5518 // implementations. We'll drop this notification and rely 5519 // on flush-complete notifications on the individual port 5520 // indices instead. 5521 5522 return true; 5523 } 5524 5525 return onOMXEvent( 5526 static_cast<OMX_EVENTTYPE>(event), 5527 static_cast<OMX_U32>(data1), 5528 static_cast<OMX_U32>(data2)); 5529 } 5530 5531 case omx_message::EMPTY_BUFFER_DONE: 5532 { 5533 IOMX::buffer_id bufferID; 5534 int32_t fenceFd; 5535 5536 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 5537 CHECK(msg->findInt32("fence_fd", &fenceFd)); 5538 5539 return onOMXEmptyBufferDone(bufferID, fenceFd); 5540 } 5541 5542 case omx_message::FILL_BUFFER_DONE: 5543 { 5544 IOMX::buffer_id bufferID; 5545 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 5546 5547 int32_t rangeOffset, rangeLength, flags, fenceFd; 5548 int64_t timeUs; 5549 5550 CHECK(msg->findInt32("range_offset", &rangeOffset)); 5551 CHECK(msg->findInt32("range_length", &rangeLength)); 5552 CHECK(msg->findInt32("flags", &flags)); 5553 CHECK(msg->findInt64("timestamp", &timeUs)); 5554 CHECK(msg->findInt32("fence_fd", &fenceFd)); 5555 5556 return onOMXFillBufferDone( 5557 bufferID, 5558 (size_t)rangeOffset, (size_t)rangeLength, 5559 (OMX_U32)flags, 5560 timeUs, 5561 fenceFd); 5562 } 5563 5564 case omx_message::FRAME_RENDERED: 5565 { 5566 int64_t mediaTimeUs, systemNano; 5567 5568 CHECK(msg->findInt64("media_time_us", &mediaTimeUs)); 5569 CHECK(msg->findInt64("system_nano", &systemNano)); 5570 5571 return onOMXFrameRendered( 5572 mediaTimeUs, systemNano); 5573 } 5574 5575 default: 5576 ALOGE("Unexpected message type: %d", type); 5577 return false; 5578 } 5579} 5580 5581bool ACodec::BaseState::onOMXFrameRendered( 5582 int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) { 5583 // ignore outside of Executing and PortSettingsChanged states 5584 return true; 5585} 5586 5587bool ACodec::BaseState::onOMXEvent( 5588 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5589 if (event == OMX_EventDataSpaceChanged) { 5590 ColorAspects aspects = ColorUtils::unpackToColorAspects(data2); 5591 5592 mCodec->onDataSpaceChanged((android_dataspace)data1, aspects); 5593 return true; 5594 } 5595 5596 if (event != OMX_EventError) { 5597 ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)", 5598 mCodec->mComponentName.c_str(), event, data1, data2); 5599 5600 return false; 5601 } 5602 5603 ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1); 5604 5605 // verify OMX component sends back an error we expect. 5606 OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1; 5607 if (!isOMXError(omxError)) { 5608 ALOGW("Invalid OMX error %#x", omxError); 5609 omxError = OMX_ErrorUndefined; 5610 } 5611 mCodec->signalError(omxError); 5612 5613 return true; 5614} 5615 5616bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) { 5617 ALOGV("[%s] onOMXEmptyBufferDone %u", 5618 mCodec->mComponentName.c_str(), bufferID); 5619 5620 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 5621 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5622 if (status != BufferInfo::OWNED_BY_COMPONENT) { 5623 ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5624 mCodec->dumpBuffers(kPortIndexInput); 5625 if (fenceFd >= 0) { 5626 ::close(fenceFd); 5627 } 5628 return false; 5629 } 5630 info->mStatus = BufferInfo::OWNED_BY_US; 5631 5632 // input buffers cannot take fences, so wait for any fence now 5633 (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone"); 5634 fenceFd = -1; 5635 5636 // still save fence for completeness 5637 info->setWriteFence(fenceFd, "onOMXEmptyBufferDone"); 5638 5639 // We're in "store-metadata-in-buffers" mode, the underlying 5640 // OMX component had access to data that's implicitly refcounted 5641 // by this "MediaBuffer" object. Now that the OMX component has 5642 // told us that it's done with the input buffer, we can decrement 5643 // the mediaBuffer's reference count. 5644 info->mData->setMediaBufferBase(NULL); 5645 5646 PortMode mode = getPortMode(kPortIndexInput); 5647 5648 switch (mode) { 5649 case KEEP_BUFFERS: 5650 break; 5651 5652 case RESUBMIT_BUFFERS: 5653 postFillThisBuffer(info); 5654 break; 5655 5656 case FREE_BUFFERS: 5657 default: 5658 ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers"); 5659 return false; 5660 } 5661 5662 return true; 5663} 5664 5665void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) { 5666 if (mCodec->mPortEOS[kPortIndexInput]) { 5667 return; 5668 } 5669 5670 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 5671 5672 info->mData->setFormat(mCodec->mInputFormat); 5673 mCodec->mBufferChannel->fillThisBuffer(info->mBufferID); 5674 info->mData.clear(); 5675 info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 5676} 5677 5678void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { 5679 IOMX::buffer_id bufferID; 5680 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 5681 sp<MediaCodecBuffer> buffer; 5682 int32_t err = OK; 5683 bool eos = false; 5684 PortMode mode = getPortMode(kPortIndexInput); 5685 int32_t discarded = 0; 5686 if (msg->findInt32("discarded", &discarded) && discarded) { 5687 // these are unfilled buffers returned by client 5688 // buffers are returned on MediaCodec.flush 5689 mode = KEEP_BUFFERS; 5690 } 5691 sp<RefBase> obj; 5692 CHECK(msg->findObject("buffer", &obj)); 5693 buffer = static_cast<MediaCodecBuffer *>(obj.get()); 5694 5695 int32_t tmp; 5696 if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) { 5697 eos = true; 5698 err = ERROR_END_OF_STREAM; 5699 } 5700 5701 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 5702 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5703 if (status != BufferInfo::OWNED_BY_UPSTREAM) { 5704 ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID); 5705 mCodec->dumpBuffers(kPortIndexInput); 5706 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5707 return; 5708 } 5709 5710 info->mStatus = BufferInfo::OWNED_BY_US; 5711 info->mData = buffer; 5712 5713 switch (mode) { 5714 case KEEP_BUFFERS: 5715 { 5716 if (eos) { 5717 if (!mCodec->mPortEOS[kPortIndexInput]) { 5718 mCodec->mPortEOS[kPortIndexInput] = true; 5719 mCodec->mInputEOSResult = err; 5720 } 5721 } 5722 break; 5723 } 5724 5725 case RESUBMIT_BUFFERS: 5726 { 5727 if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) { 5728 // Do not send empty input buffer w/o EOS to the component. 5729 if (buffer->size() == 0 && !eos) { 5730 postFillThisBuffer(info); 5731 break; 5732 } 5733 5734 int64_t timeUs; 5735 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 5736 5737 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 5738 5739 int32_t isCSD = 0; 5740 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) { 5741 if (mCodec->mIsLegacyVP9Decoder) { 5742 ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data", 5743 mCodec->mComponentName.c_str(), bufferID); 5744 postFillThisBuffer(info); 5745 break; 5746 } 5747 flags |= OMX_BUFFERFLAG_CODECCONFIG; 5748 } 5749 5750 if (eos) { 5751 flags |= OMX_BUFFERFLAG_EOS; 5752 } 5753 5754 size_t size = buffer->size(); 5755 size_t offset = buffer->offset(); 5756 if (buffer->base() != info->mCodecData->base()) { 5757 ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)", 5758 mCodec->mComponentName.c_str(), 5759 bufferID, 5760 buffer->base(), info->mCodecData->base()); 5761 5762 sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput]; 5763 if (converter == NULL || isCSD) { 5764 converter = getCopyConverter(); 5765 } 5766 status_t err = converter->convert(buffer, info->mCodecData); 5767 if (err != OK) { 5768 mCodec->signalError(OMX_ErrorUndefined, err); 5769 return; 5770 } 5771 size = info->mCodecData->size(); 5772 } else { 5773 info->mCodecData->setRange(offset, size); 5774 } 5775 5776 if (flags & OMX_BUFFERFLAG_CODECCONFIG) { 5777 ALOGV("[%s] calling emptyBuffer %u w/ codec specific data", 5778 mCodec->mComponentName.c_str(), bufferID); 5779 } else if (flags & OMX_BUFFERFLAG_EOS) { 5780 ALOGV("[%s] calling emptyBuffer %u w/ EOS", 5781 mCodec->mComponentName.c_str(), bufferID); 5782 } else { 5783#if TRACK_BUFFER_TIMING 5784 ALOGI("[%s] calling emptyBuffer %u w/ time %lld us", 5785 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 5786#else 5787 ALOGV("[%s] calling emptyBuffer %u w/ time %lld us", 5788 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 5789#endif 5790 } 5791 5792#if TRACK_BUFFER_TIMING 5793 ACodec::BufferStats stats; 5794 stats.mEmptyBufferTimeUs = ALooper::GetNowUs(); 5795 stats.mFillBufferDoneTimeUs = -1ll; 5796 mCodec->mBufferStats.add(timeUs, stats); 5797#endif 5798 5799 if (mCodec->storingMetadataInDecodedBuffers()) { 5800 // try to submit an output buffer for each input buffer 5801 PortMode outputMode = getPortMode(kPortIndexOutput); 5802 5803 ALOGV("MetadataBuffersToSubmit=%u portMode=%s", 5804 mCodec->mMetadataBuffersToSubmit, 5805 (outputMode == FREE_BUFFERS ? "FREE" : 5806 outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT")); 5807 if (outputMode == RESUBMIT_BUFFERS) { 5808 mCodec->submitOutputMetadataBuffer(); 5809 } 5810 } 5811 info->checkReadFence("onInputBufferFilled"); 5812 5813 status_t err2 = OK; 5814 switch (mCodec->mPortMode[kPortIndexInput]) { 5815 case IOMX::kPortModePresetByteBuffer: 5816 case IOMX::kPortModePresetANWBuffer: 5817 case IOMX::kPortModePresetSecureBuffer: 5818 { 5819 err2 = mCodec->mOMXNode->emptyBuffer( 5820 bufferID, info->mCodecData, flags, timeUs, info->mFenceFd); 5821 } 5822 break; 5823#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 5824 case IOMX::kPortModeDynamicNativeHandle: 5825 if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) { 5826 VideoNativeHandleMetadata *vnhmd = 5827 (VideoNativeHandleMetadata*)info->mCodecData->base(); 5828 sp<NativeHandle> handle = NativeHandle::create( 5829 vnhmd->pHandle, false /* ownsHandle */); 5830 err2 = mCodec->mOMXNode->emptyBuffer( 5831 bufferID, handle, flags, timeUs, info->mFenceFd); 5832 } 5833 break; 5834 case IOMX::kPortModeDynamicANWBuffer: 5835 if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) { 5836 VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base(); 5837 sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(vnmd->pBuffer); 5838 err2 = mCodec->mOMXNode->emptyBuffer( 5839 bufferID, graphicBuffer, flags, timeUs, info->mFenceFd); 5840 } 5841 break; 5842#endif 5843 default: 5844 ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode", 5845 asString(mCodec->mPortMode[kPortIndexInput]), 5846 info->mCodecData->size(), 5847 sizeof(buffer_handle_t) * 8); 5848 err2 = ERROR_UNSUPPORTED; 5849 break; 5850 } 5851 5852 info->mFenceFd = -1; 5853 if (err2 != OK) { 5854 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 5855 return; 5856 } 5857 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5858 // Hold the reference while component is using the buffer. 5859 info->mData = buffer; 5860 5861 if (!eos && err == OK) { 5862 getMoreInputDataIfPossible(); 5863 } else { 5864 ALOGV("[%s] Signalled EOS (%d) on the input port", 5865 mCodec->mComponentName.c_str(), err); 5866 5867 mCodec->mPortEOS[kPortIndexInput] = true; 5868 mCodec->mInputEOSResult = err; 5869 } 5870 } else if (!mCodec->mPortEOS[kPortIndexInput]) { 5871 if (err != OK && err != ERROR_END_OF_STREAM) { 5872 ALOGV("[%s] Signalling EOS on the input port due to error %d", 5873 mCodec->mComponentName.c_str(), err); 5874 } else { 5875 ALOGV("[%s] Signalling EOS on the input port", 5876 mCodec->mComponentName.c_str()); 5877 } 5878 5879 ALOGV("[%s] calling emptyBuffer %u signalling EOS", 5880 mCodec->mComponentName.c_str(), bufferID); 5881 5882 info->checkReadFence("onInputBufferFilled"); 5883 status_t err2 = mCodec->mOMXNode->emptyBuffer( 5884 bufferID, OMXBuffer::sPreset, OMX_BUFFERFLAG_EOS, 0, info->mFenceFd); 5885 info->mFenceFd = -1; 5886 if (err2 != OK) { 5887 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 5888 return; 5889 } 5890 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5891 5892 mCodec->mPortEOS[kPortIndexInput] = true; 5893 mCodec->mInputEOSResult = err; 5894 } 5895 break; 5896 } 5897 5898 case FREE_BUFFERS: 5899 break; 5900 5901 default: 5902 ALOGE("invalid port mode: %d", mode); 5903 break; 5904 } 5905} 5906 5907void ACodec::BaseState::getMoreInputDataIfPossible() { 5908 if (mCodec->mPortEOS[kPortIndexInput]) { 5909 return; 5910 } 5911 5912 BufferInfo *eligible = NULL; 5913 5914 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 5915 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 5916 5917#if 0 5918 if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 5919 // There's already a "read" pending. 5920 return; 5921 } 5922#endif 5923 5924 if (info->mStatus == BufferInfo::OWNED_BY_US) { 5925 eligible = info; 5926 } 5927 } 5928 5929 if (eligible == NULL) { 5930 return; 5931 } 5932 5933 postFillThisBuffer(eligible); 5934} 5935 5936bool ACodec::BaseState::onOMXFillBufferDone( 5937 IOMX::buffer_id bufferID, 5938 size_t rangeOffset, size_t rangeLength, 5939 OMX_U32 flags, 5940 int64_t timeUs, 5941 int fenceFd) { 5942 ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x", 5943 mCodec->mComponentName.c_str(), bufferID, timeUs, flags); 5944 5945 ssize_t index; 5946 status_t err= OK; 5947 5948#if TRACK_BUFFER_TIMING 5949 index = mCodec->mBufferStats.indexOfKey(timeUs); 5950 if (index >= 0) { 5951 ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index); 5952 stats->mFillBufferDoneTimeUs = ALooper::GetNowUs(); 5953 5954 ALOGI("frame PTS %lld: %lld", 5955 timeUs, 5956 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs); 5957 5958 mCodec->mBufferStats.removeItemsAt(index); 5959 stats = NULL; 5960 } 5961#endif 5962 5963 BufferInfo *info = 5964 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 5965 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5966 if (status != BufferInfo::OWNED_BY_COMPONENT) { 5967 ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5968 mCodec->dumpBuffers(kPortIndexOutput); 5969 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5970 if (fenceFd >= 0) { 5971 ::close(fenceFd); 5972 } 5973 return true; 5974 } 5975 5976 info->mDequeuedAt = ++mCodec->mDequeueCounter; 5977 info->mStatus = BufferInfo::OWNED_BY_US; 5978 5979 if (info->mRenderInfo != NULL) { 5980 // The fence for an emptied buffer must have signaled, but there still could be queued 5981 // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these, 5982 // as we will soon requeue this buffer to the surface. While in theory we could still keep 5983 // track of buffers that are requeued to the surface, it is better to add support to the 5984 // buffer-queue to notify us of released buffers and their fences (in the future). 5985 mCodec->notifyOfRenderedFrames(true /* dropIncomplete */); 5986 } 5987 5988 // byte buffers cannot take fences, so wait for any fence now 5989 if (mCodec->mNativeWindow == NULL) { 5990 (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone"); 5991 fenceFd = -1; 5992 } 5993 info->setReadFence(fenceFd, "onOMXFillBufferDone"); 5994 5995 PortMode mode = getPortMode(kPortIndexOutput); 5996 5997 switch (mode) { 5998 case KEEP_BUFFERS: 5999 break; 6000 6001 case RESUBMIT_BUFFERS: 6002 { 6003 if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS) 6004 || mCodec->mPortEOS[kPortIndexOutput])) { 6005 ALOGV("[%s] calling fillBuffer %u", 6006 mCodec->mComponentName.c_str(), info->mBufferID); 6007 6008 err = mCodec->fillBuffer(info); 6009 if (err != OK) { 6010 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6011 return true; 6012 } 6013 break; 6014 } 6015 6016 sp<MediaCodecBuffer> buffer = info->mData; 6017 6018 if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) { 6019 // pretend that output format has changed on the first frame (we used to do this) 6020 if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) { 6021 mCodec->onOutputFormatChanged(mCodec->mOutputFormat); 6022 } 6023 mCodec->sendFormatChange(); 6024 } 6025 buffer->setFormat(mCodec->mOutputFormat); 6026 6027 if (mCodec->usingSecureBufferOnEncoderOutput()) { 6028 native_handle_t *handle = NULL; 6029 sp<SecureBuffer> secureBuffer = static_cast<SecureBuffer *>(buffer.get()); 6030 if (secureBuffer != NULL) { 6031#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 6032 // handle is only valid on 32-bit/mediaserver process 6033 handle = NULL; 6034#else 6035 handle = (native_handle_t *)secureBuffer->getDestinationPointer(); 6036#endif 6037 } 6038 buffer->meta()->setPointer("handle", handle); 6039 buffer->meta()->setInt32("rangeOffset", rangeOffset); 6040 buffer->meta()->setInt32("rangeLength", rangeLength); 6041 } else if (buffer->base() == info->mCodecData->base()) { 6042 buffer->setRange(rangeOffset, rangeLength); 6043 } else { 6044 info->mCodecData->setRange(rangeOffset, rangeLength); 6045 // in this case we know that mConverter is not null 6046 status_t err = mCodec->mConverter[kPortIndexOutput]->convert( 6047 info->mCodecData, buffer); 6048 if (err != OK) { 6049 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6050 return true; 6051 } 6052 } 6053#if 0 6054 if (mCodec->mNativeWindow == NULL) { 6055 if (IsIDR(info->mData->data(), info->mData->size())) { 6056 ALOGI("IDR frame"); 6057 } 6058 } 6059#endif 6060 6061 if (mCodec->mSkipCutBuffer != NULL) { 6062 mCodec->mSkipCutBuffer->submit(buffer); 6063 } 6064 buffer->meta()->setInt64("timeUs", timeUs); 6065 6066 info->mData.clear(); 6067 6068 mCodec->mBufferChannel->drainThisBuffer(info->mBufferID, flags); 6069 6070 info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 6071 6072 if (flags & OMX_BUFFERFLAG_EOS) { 6073 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str()); 6074 6075 mCodec->mCallback->onEos(mCodec->mInputEOSResult); 6076 mCodec->mPortEOS[kPortIndexOutput] = true; 6077 } 6078 break; 6079 } 6080 6081 case FREE_BUFFERS: 6082 err = mCodec->freeBuffer(kPortIndexOutput, index); 6083 if (err != OK) { 6084 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6085 return true; 6086 } 6087 break; 6088 6089 default: 6090 ALOGE("Invalid port mode: %d", mode); 6091 return false; 6092 } 6093 6094 return true; 6095} 6096 6097void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 6098 IOMX::buffer_id bufferID; 6099 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 6100 sp<RefBase> obj; 6101 CHECK(msg->findObject("buffer", &obj)); 6102 sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get()); 6103 int32_t discarded = 0; 6104 msg->findInt32("discarded", &discarded); 6105 6106 ssize_t index; 6107 BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 6108 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 6109 if (status != BufferInfo::OWNED_BY_DOWNSTREAM) { 6110 ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 6111 mCodec->dumpBuffers(kPortIndexOutput); 6112 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6113 return; 6114 } 6115 info->mData = buffer; 6116 int32_t render; 6117 if (mCodec->mNativeWindow != NULL 6118 && msg->findInt32("render", &render) && render != 0 6119 && !discarded && buffer->size() != 0) { 6120 ATRACE_NAME("render"); 6121 // The client wants this buffer to be rendered. 6122 6123 android_native_rect_t crop; 6124 if (buffer->format()->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) { 6125 // NOTE: native window uses extended right-bottom coordinate 6126 ++crop.right; 6127 ++crop.bottom; 6128 if (memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) { 6129 mCodec->mLastNativeWindowCrop = crop; 6130 status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop); 6131 ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err); 6132 } 6133 } 6134 6135 int32_t dataSpace; 6136 if (buffer->format()->findInt32("android._dataspace", &dataSpace) 6137 && dataSpace != mCodec->mLastNativeWindowDataSpace) { 6138 status_t err = native_window_set_buffers_data_space( 6139 mCodec->mNativeWindow.get(), (android_dataspace)dataSpace); 6140 mCodec->mLastNativeWindowDataSpace = dataSpace; 6141 ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err); 6142 } 6143 6144 // save buffers sent to the surface so we can get render time when they return 6145 int64_t mediaTimeUs = -1; 6146 buffer->meta()->findInt64("timeUs", &mediaTimeUs); 6147 if (mediaTimeUs >= 0) { 6148 mCodec->mRenderTracker.onFrameQueued( 6149 mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd))); 6150 } 6151 6152 int64_t timestampNs = 0; 6153 if (!msg->findInt64("timestampNs", ×tampNs)) { 6154 // use media timestamp if client did not request a specific render timestamp 6155 if (buffer->meta()->findInt64("timeUs", ×tampNs)) { 6156 ALOGV("using buffer PTS of %lld", (long long)timestampNs); 6157 timestampNs *= 1000; 6158 } 6159 } 6160 6161 status_t err; 6162 err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs); 6163 ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err); 6164 6165 info->checkReadFence("onOutputBufferDrained before queueBuffer"); 6166 err = mCodec->mNativeWindow->queueBuffer( 6167 mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd); 6168 info->mFenceFd = -1; 6169 if (err == OK) { 6170 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 6171 } else { 6172 ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err); 6173 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6174 info->mStatus = BufferInfo::OWNED_BY_US; 6175 // keeping read fence as write fence to avoid clobbering 6176 info->mIsReadFence = false; 6177 } 6178 } else { 6179 if (mCodec->mNativeWindow != NULL && (discarded || buffer->size() != 0)) { 6180 // move read fence into write fence to avoid clobbering 6181 info->mIsReadFence = false; 6182 ATRACE_NAME("frame-drop"); 6183 } 6184 info->mStatus = BufferInfo::OWNED_BY_US; 6185 } 6186 6187 PortMode mode = getPortMode(kPortIndexOutput); 6188 6189 switch (mode) { 6190 case KEEP_BUFFERS: 6191 { 6192 // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 6193 6194 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6195 // We cannot resubmit the buffer we just rendered, dequeue 6196 // the spare instead. 6197 6198 info = mCodec->dequeueBufferFromNativeWindow(); 6199 } 6200 break; 6201 } 6202 6203 case RESUBMIT_BUFFERS: 6204 { 6205 if (!mCodec->mPortEOS[kPortIndexOutput]) { 6206 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6207 // We cannot resubmit the buffer we just rendered, dequeue 6208 // the spare instead. 6209 6210 info = mCodec->dequeueBufferFromNativeWindow(); 6211 } 6212 6213 if (info != NULL) { 6214 ALOGV("[%s] calling fillBuffer %u", 6215 mCodec->mComponentName.c_str(), info->mBufferID); 6216 info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS"); 6217 status_t err = mCodec->fillBuffer(info); 6218 if (err != OK) { 6219 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6220 } 6221 } 6222 } 6223 break; 6224 } 6225 6226 case FREE_BUFFERS: 6227 { 6228 status_t err = mCodec->freeBuffer(kPortIndexOutput, index); 6229 if (err != OK) { 6230 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6231 } 6232 break; 6233 } 6234 6235 default: 6236 ALOGE("Invalid port mode: %d", mode); 6237 return; 6238 } 6239} 6240 6241//////////////////////////////////////////////////////////////////////////////// 6242 6243ACodec::UninitializedState::UninitializedState(ACodec *codec) 6244 : BaseState(codec) { 6245} 6246 6247void ACodec::UninitializedState::stateEntered() { 6248 ALOGV("Now uninitialized"); 6249 6250 if (mDeathNotifier != NULL) { 6251 if (mCodec->mOMXNode != NULL) { 6252 if (mCodec->getTrebleFlag()) { 6253 auto tOmxNode = mCodec->mOMXNode->getHalInterface(); 6254 tOmxNode->unlinkToDeath(mDeathNotifier); 6255 } else { 6256 sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode); 6257 binder->unlinkToDeath(mDeathNotifier); 6258 } 6259 } 6260 mDeathNotifier.clear(); 6261 } 6262 6263 mCodec->mUsingNativeWindow = false; 6264 mCodec->mNativeWindow.clear(); 6265 mCodec->mNativeWindowUsageBits = 0; 6266 mCodec->mOMX.clear(); 6267 mCodec->mOMXNode.clear(); 6268 mCodec->mFlags = 0; 6269 mCodec->mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer; 6270 mCodec->mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer; 6271 mCodec->mConverter[0].clear(); 6272 mCodec->mConverter[1].clear(); 6273 mCodec->mComponentName.clear(); 6274} 6275 6276bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 6277 bool handled = false; 6278 6279 switch (msg->what()) { 6280 case ACodec::kWhatSetup: 6281 { 6282 onSetup(msg); 6283 6284 handled = true; 6285 break; 6286 } 6287 6288 case ACodec::kWhatAllocateComponent: 6289 { 6290 onAllocateComponent(msg); 6291 handled = true; 6292 break; 6293 } 6294 6295 case ACodec::kWhatShutdown: 6296 { 6297 int32_t keepComponentAllocated; 6298 CHECK(msg->findInt32( 6299 "keepComponentAllocated", &keepComponentAllocated)); 6300 ALOGW_IF(keepComponentAllocated, 6301 "cannot keep component allocated on shutdown in Uninitialized state"); 6302 if (keepComponentAllocated) { 6303 mCodec->mCallback->onStopCompleted(); 6304 } else { 6305 mCodec->mCallback->onReleaseCompleted(); 6306 } 6307 handled = true; 6308 break; 6309 } 6310 6311 case ACodec::kWhatFlush: 6312 { 6313 mCodec->mCallback->onFlushCompleted(); 6314 handled = true; 6315 break; 6316 } 6317 6318 case ACodec::kWhatReleaseCodecInstance: 6319 { 6320 // nothing to do, as we have already signaled shutdown 6321 handled = true; 6322 break; 6323 } 6324 6325 default: 6326 return BaseState::onMessageReceived(msg); 6327 } 6328 6329 return handled; 6330} 6331 6332void ACodec::UninitializedState::onSetup( 6333 const sp<AMessage> &msg) { 6334 if (onAllocateComponent(msg) 6335 && mCodec->mLoadedState->onConfigureComponent(msg)) { 6336 mCodec->mLoadedState->onStart(); 6337 } 6338} 6339 6340bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { 6341 ALOGV("onAllocateComponent"); 6342 6343 CHECK(mCodec->mOMXNode == NULL); 6344 6345 sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec); 6346 6347 Vector<AString> matchingCodecs; 6348 Vector<AString> owners; 6349 6350 AString mime; 6351 6352 AString componentName; 6353 int32_t encoder = false; 6354 if (msg->findString("componentName", &componentName)) { 6355 sp<IMediaCodecList> list = MediaCodecList::getInstance(); 6356 if (list == nullptr) { 6357 ALOGE("Unable to obtain MediaCodecList while " 6358 "attempting to create codec \"%s\"", 6359 componentName.c_str()); 6360 mCodec->signalError(OMX_ErrorUndefined, NO_INIT); 6361 return false; 6362 } 6363 ssize_t index = list->findCodecByName(componentName.c_str()); 6364 if (index < 0) { 6365 ALOGE("Unable to find codec \"%s\"", 6366 componentName.c_str()); 6367 mCodec->signalError(OMX_ErrorInvalidComponent, NAME_NOT_FOUND); 6368 return false; 6369 } 6370 sp<MediaCodecInfo> info = list->getCodecInfo(index); 6371 if (info == nullptr) { 6372 ALOGE("Unexpected error (index out-of-bound) while " 6373 "retrieving information for codec \"%s\"", 6374 componentName.c_str()); 6375 mCodec->signalError(OMX_ErrorUndefined, UNKNOWN_ERROR); 6376 return false; 6377 } 6378 matchingCodecs.add(info->getCodecName()); 6379 owners.add(info->getOwnerName() == nullptr ? 6380 "default" : info->getOwnerName()); 6381 } else { 6382 CHECK(msg->findString("mime", &mime)); 6383 6384 if (!msg->findInt32("encoder", &encoder)) { 6385 encoder = false; 6386 } 6387 6388 MediaCodecList::findMatchingCodecs( 6389 mime.c_str(), 6390 encoder, // createEncoder 6391 0, // flags 6392 &matchingCodecs, 6393 &owners); 6394 } 6395 6396 sp<CodecObserver> observer = new CodecObserver; 6397 sp<IOMX> omx; 6398 sp<IOMXNode> omxNode; 6399 6400 status_t err = NAME_NOT_FOUND; 6401 for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); 6402 ++matchIndex) { 6403 componentName = matchingCodecs[matchIndex]; 6404 6405 OMXClient client; 6406 bool trebleFlag; 6407 if (client.connect(owners[matchIndex].c_str(), &trebleFlag) != OK) { 6408 mCodec->signalError(OMX_ErrorUndefined, NO_INIT); 6409 return false; 6410 } 6411 omx = client.interface(); 6412 6413 pid_t tid = gettid(); 6414 int prevPriority = androidGetThreadPriority(tid); 6415 androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); 6416 err = omx->allocateNode(componentName.c_str(), observer, &omxNode); 6417 androidSetThreadPriority(tid, prevPriority); 6418 6419 if (err == OK) { 6420 mCodec->setTrebleFlag(trebleFlag); 6421 break; 6422 } else { 6423 ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str()); 6424 } 6425 6426 omxNode = NULL; 6427 } 6428 6429 if (omxNode == NULL) { 6430 if (!mime.empty()) { 6431 ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.", 6432 encoder ? "en" : "de", mime.c_str(), err); 6433 } else { 6434 ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err); 6435 } 6436 6437 mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err)); 6438 return false; 6439 } 6440 6441 mDeathNotifier = new DeathNotifier(notify); 6442 if (mCodec->getTrebleFlag()) { 6443 auto tOmxNode = omxNode->getHalInterface(); 6444 if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) { 6445 mDeathNotifier.clear(); 6446 } 6447 } else { 6448 if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) { 6449 // This was a local binder, if it dies so do we, we won't care 6450 // about any notifications in the afterlife. 6451 mDeathNotifier.clear(); 6452 } 6453 } 6454 6455 notify = new AMessage(kWhatOMXMessageList, mCodec); 6456 notify->setInt32("generation", ++mCodec->mNodeGeneration); 6457 observer->setNotificationMessage(notify); 6458 6459 mCodec->mComponentName = componentName; 6460 mCodec->mRenderTracker.setComponentName(componentName); 6461 mCodec->mFlags = 0; 6462 6463 if (componentName.endsWith(".secure")) { 6464 mCodec->mFlags |= kFlagIsSecure; 6465 mCodec->mFlags |= kFlagIsGrallocUsageProtected; 6466 mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 6467 } 6468 6469 mCodec->mOMX = omx; 6470 mCodec->mOMXNode = omxNode; 6471 mCodec->mCallback->onComponentAllocated(mCodec->mComponentName.c_str()); 6472 mCodec->changeState(mCodec->mLoadedState); 6473 6474 return true; 6475} 6476 6477//////////////////////////////////////////////////////////////////////////////// 6478 6479ACodec::LoadedState::LoadedState(ACodec *codec) 6480 : BaseState(codec) { 6481} 6482 6483void ACodec::LoadedState::stateEntered() { 6484 ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 6485 6486 mCodec->mPortEOS[kPortIndexInput] = 6487 mCodec->mPortEOS[kPortIndexOutput] = false; 6488 6489 mCodec->mInputEOSResult = OK; 6490 6491 mCodec->mDequeueCounter = 0; 6492 mCodec->mMetadataBuffersToSubmit = 0; 6493 mCodec->mRepeatFrameDelayUs = -1ll; 6494 mCodec->mInputFormat.clear(); 6495 mCodec->mOutputFormat.clear(); 6496 mCodec->mBaseOutputFormat.clear(); 6497 mCodec->mGraphicBufferSource.clear(); 6498 6499 if (mCodec->mShutdownInProgress) { 6500 bool keepComponentAllocated = mCodec->mKeepComponentAllocated; 6501 6502 mCodec->mShutdownInProgress = false; 6503 mCodec->mKeepComponentAllocated = false; 6504 6505 onShutdown(keepComponentAllocated); 6506 } 6507 mCodec->mExplicitShutdown = false; 6508 6509 mCodec->processDeferredMessages(); 6510} 6511 6512void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) { 6513 if (!keepComponentAllocated) { 6514 (void)mCodec->mOMXNode->freeNode(); 6515 6516 mCodec->changeState(mCodec->mUninitializedState); 6517 } 6518 6519 if (mCodec->mExplicitShutdown) { 6520 if (keepComponentAllocated) { 6521 mCodec->mCallback->onStopCompleted(); 6522 } else { 6523 mCodec->mCallback->onReleaseCompleted(); 6524 } 6525 mCodec->mExplicitShutdown = false; 6526 } 6527} 6528 6529bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) { 6530 bool handled = false; 6531 6532 switch (msg->what()) { 6533 case ACodec::kWhatConfigureComponent: 6534 { 6535 onConfigureComponent(msg); 6536 handled = true; 6537 break; 6538 } 6539 6540 case ACodec::kWhatCreateInputSurface: 6541 { 6542 onCreateInputSurface(msg); 6543 handled = true; 6544 break; 6545 } 6546 6547 case ACodec::kWhatSetInputSurface: 6548 { 6549 onSetInputSurface(msg); 6550 handled = true; 6551 break; 6552 } 6553 6554 case ACodec::kWhatStart: 6555 { 6556 onStart(); 6557 handled = true; 6558 break; 6559 } 6560 6561 case ACodec::kWhatShutdown: 6562 { 6563 int32_t keepComponentAllocated; 6564 CHECK(msg->findInt32( 6565 "keepComponentAllocated", &keepComponentAllocated)); 6566 6567 mCodec->mExplicitShutdown = true; 6568 onShutdown(keepComponentAllocated); 6569 6570 handled = true; 6571 break; 6572 } 6573 6574 case ACodec::kWhatFlush: 6575 { 6576 mCodec->mCallback->onFlushCompleted(); 6577 handled = true; 6578 break; 6579 } 6580 6581 default: 6582 return BaseState::onMessageReceived(msg); 6583 } 6584 6585 return handled; 6586} 6587 6588bool ACodec::LoadedState::onConfigureComponent( 6589 const sp<AMessage> &msg) { 6590 ALOGV("onConfigureComponent"); 6591 6592 CHECK(mCodec->mOMXNode != NULL); 6593 6594 status_t err = OK; 6595 AString mime; 6596 if (!msg->findString("mime", &mime)) { 6597 err = BAD_VALUE; 6598 } else { 6599 err = mCodec->configureCodec(mime.c_str(), msg); 6600 } 6601 if (err != OK) { 6602 ALOGE("[%s] configureCodec returning error %d", 6603 mCodec->mComponentName.c_str(), err); 6604 6605 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6606 return false; 6607 } 6608 6609 mCodec->mCallback->onComponentConfigured(mCodec->mInputFormat, mCodec->mOutputFormat); 6610 6611 return true; 6612} 6613 6614status_t ACodec::LoadedState::setupInputSurface() { 6615 if (mCodec->mGraphicBufferSource == NULL) { 6616 return BAD_VALUE; 6617 } 6618 6619 android_dataspace dataSpace; 6620 status_t err = 6621 mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace); 6622 if (err != OK) { 6623 ALOGE("Failed to get default data space"); 6624 return err; 6625 } 6626 6627 err = statusFromBinderStatus( 6628 mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace)); 6629 if (err != OK) { 6630 ALOGE("[%s] Unable to configure for node (err %d)", 6631 mCodec->mComponentName.c_str(), err); 6632 return err; 6633 } 6634 6635 if (mCodec->mRepeatFrameDelayUs > 0ll) { 6636 err = statusFromBinderStatus( 6637 mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs( 6638 mCodec->mRepeatFrameDelayUs)); 6639 6640 if (err != OK) { 6641 ALOGE("[%s] Unable to configure option to repeat previous " 6642 "frames (err %d)", 6643 mCodec->mComponentName.c_str(), err); 6644 return err; 6645 } 6646 } 6647 6648 if (mCodec->mMaxPtsGapUs > 0ll) { 6649 OMX_PARAM_U32TYPE maxPtsGapParams; 6650 InitOMXParams(&maxPtsGapParams); 6651 maxPtsGapParams.nPortIndex = kPortIndexInput; 6652 maxPtsGapParams.nU32 = (uint32_t) mCodec->mMaxPtsGapUs; 6653 6654 err = mCodec->mOMXNode->setParameter( 6655 (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl, 6656 &maxPtsGapParams, sizeof(maxPtsGapParams)); 6657 6658 if (err != OK) { 6659 ALOGE("[%s] Unable to configure max timestamp gap (err %d)", 6660 mCodec->mComponentName.c_str(), err); 6661 return err; 6662 } 6663 } 6664 6665 if (mCodec->mMaxFps > 0) { 6666 err = statusFromBinderStatus( 6667 mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps)); 6668 6669 if (err != OK) { 6670 ALOGE("[%s] Unable to configure max fps (err %d)", 6671 mCodec->mComponentName.c_str(), err); 6672 return err; 6673 } 6674 } 6675 6676 if (mCodec->mCaptureFps > 0. && mCodec->mFps > 0.) { 6677 err = statusFromBinderStatus( 6678 mCodec->mGraphicBufferSource->setTimeLapseConfig( 6679 mCodec->mFps, mCodec->mCaptureFps)); 6680 6681 if (err != OK) { 6682 ALOGE("[%s] Unable to configure time lapse (err %d)", 6683 mCodec->mComponentName.c_str(), err); 6684 return err; 6685 } 6686 } 6687 6688 if (mCodec->mCreateInputBuffersSuspended) { 6689 err = statusFromBinderStatus( 6690 mCodec->mGraphicBufferSource->setSuspend(true, -1)); 6691 6692 if (err != OK) { 6693 ALOGE("[%s] Unable to configure option to suspend (err %d)", 6694 mCodec->mComponentName.c_str(), err); 6695 return err; 6696 } 6697 } 6698 6699 uint32_t usageBits; 6700 if (mCodec->mOMXNode->getParameter( 6701 (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, 6702 &usageBits, sizeof(usageBits)) == OK) { 6703 mCodec->mInputFormat->setInt32( 6704 "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN)); 6705 } 6706 6707 sp<ABuffer> colorAspectsBuffer; 6708 if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) { 6709 if (colorAspectsBuffer->size() != sizeof(ColorAspects)) { 6710 return INVALID_OPERATION; 6711 } 6712 6713 err = statusFromBinderStatus( 6714 mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32( 6715 *(ColorAspects *)colorAspectsBuffer->base()))); 6716 6717 if (err != OK) { 6718 ALOGE("[%s] Unable to configure color aspects (err %d)", 6719 mCodec->mComponentName.c_str(), err); 6720 return err; 6721 } 6722 } 6723 return OK; 6724} 6725 6726void ACodec::LoadedState::onCreateInputSurface( 6727 const sp<AMessage> & /* msg */) { 6728 ALOGV("onCreateInputSurface"); 6729 6730 sp<IGraphicBufferProducer> bufferProducer; 6731 status_t err = mCodec->mOMX->createInputSurface( 6732 &bufferProducer, &mCodec->mGraphicBufferSource); 6733 6734 if (err == OK) { 6735 err = setupInputSurface(); 6736 } 6737 6738 if (err == OK) { 6739 mCodec->mCallback->onInputSurfaceCreated( 6740 mCodec->mInputFormat, 6741 mCodec->mOutputFormat, 6742 new BufferProducerWrapper(bufferProducer)); 6743 } else { 6744 // Can't use mCodec->signalError() here -- MediaCodec won't forward 6745 // the error through because it's in the "configured" state. We 6746 // send a kWhatInputSurfaceCreated with an error value instead. 6747 ALOGE("[%s] onCreateInputSurface returning error %d", 6748 mCodec->mComponentName.c_str(), err); 6749 mCodec->mCallback->onInputSurfaceCreationFailed(err); 6750 } 6751} 6752 6753void ACodec::LoadedState::onSetInputSurface(const sp<AMessage> &msg) { 6754 ALOGV("onSetInputSurface"); 6755 6756 sp<RefBase> obj; 6757 CHECK(msg->findObject("input-surface", &obj)); 6758 sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get()); 6759 mCodec->mGraphicBufferSource = surface->getBufferSource(); 6760 6761 status_t err = setupInputSurface(); 6762 6763 if (err == OK) { 6764 mCodec->mCallback->onInputSurfaceAccepted( 6765 mCodec->mInputFormat, mCodec->mOutputFormat); 6766 } else { 6767 // Can't use mCodec->signalError() here -- MediaCodec won't forward 6768 // the error through because it's in the "configured" state. We 6769 // send a kWhatInputSurfaceAccepted with an error value instead. 6770 ALOGE("[%s] onSetInputSurface returning error %d", 6771 mCodec->mComponentName.c_str(), err); 6772 mCodec->mCallback->onInputSurfaceDeclined(err); 6773 } 6774} 6775 6776void ACodec::LoadedState::onStart() { 6777 ALOGV("onStart"); 6778 6779 status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle); 6780 if (err != OK) { 6781 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6782 } else { 6783 mCodec->changeState(mCodec->mLoadedToIdleState); 6784 } 6785} 6786 6787//////////////////////////////////////////////////////////////////////////////// 6788 6789ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 6790 : BaseState(codec) { 6791} 6792 6793void ACodec::LoadedToIdleState::stateEntered() { 6794 ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 6795 6796 status_t err; 6797 if ((err = allocateBuffers()) != OK) { 6798 ALOGE("Failed to allocate buffers after transitioning to IDLE state " 6799 "(error 0x%08x)", 6800 err); 6801 6802 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6803 6804 mCodec->mOMXNode->sendCommand( 6805 OMX_CommandStateSet, OMX_StateLoaded); 6806 if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) { 6807 mCodec->freeBuffersOnPort(kPortIndexInput); 6808 } 6809 if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) { 6810 mCodec->freeBuffersOnPort(kPortIndexOutput); 6811 } 6812 6813 mCodec->changeState(mCodec->mLoadedState); 6814 } 6815} 6816 6817status_t ACodec::LoadedToIdleState::allocateBuffers() { 6818 status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 6819 if (err != OK) { 6820 return err; 6821 } 6822 6823 err = mCodec->allocateBuffersOnPort(kPortIndexOutput); 6824 if (err != OK) { 6825 return err; 6826 } 6827 6828 mCodec->mCallback->onStartCompleted(); 6829 6830 return OK; 6831} 6832 6833bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 6834 switch (msg->what()) { 6835 case kWhatSetParameters: 6836 case kWhatShutdown: 6837 { 6838 mCodec->deferMessage(msg); 6839 return true; 6840 } 6841 6842 case kWhatSignalEndOfInputStream: 6843 { 6844 mCodec->onSignalEndOfInputStream(); 6845 return true; 6846 } 6847 6848 case kWhatResume: 6849 { 6850 // We'll be active soon enough. 6851 return true; 6852 } 6853 6854 case kWhatFlush: 6855 { 6856 // We haven't even started yet, so we're flushed alright... 6857 mCodec->mCallback->onFlushCompleted(); 6858 return true; 6859 } 6860 6861 default: 6862 return BaseState::onMessageReceived(msg); 6863 } 6864} 6865 6866bool ACodec::LoadedToIdleState::onOMXEvent( 6867 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6868 switch (event) { 6869 case OMX_EventCmdComplete: 6870 { 6871 status_t err = OK; 6872 if (data1 != (OMX_U32)OMX_CommandStateSet 6873 || data2 != (OMX_U32)OMX_StateIdle) { 6874 ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)", 6875 asString((OMX_COMMANDTYPE)data1), data1, 6876 asString((OMX_STATETYPE)data2), data2); 6877 err = FAILED_TRANSACTION; 6878 } 6879 6880 if (err == OK) { 6881 err = mCodec->mOMXNode->sendCommand( 6882 OMX_CommandStateSet, OMX_StateExecuting); 6883 } 6884 6885 if (err != OK) { 6886 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6887 } else { 6888 mCodec->changeState(mCodec->mIdleToExecutingState); 6889 } 6890 6891 return true; 6892 } 6893 6894 default: 6895 return BaseState::onOMXEvent(event, data1, data2); 6896 } 6897} 6898 6899//////////////////////////////////////////////////////////////////////////////// 6900 6901ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 6902 : BaseState(codec) { 6903} 6904 6905void ACodec::IdleToExecutingState::stateEntered() { 6906 ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 6907} 6908 6909bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 6910 switch (msg->what()) { 6911 case kWhatSetParameters: 6912 case kWhatShutdown: 6913 { 6914 mCodec->deferMessage(msg); 6915 return true; 6916 } 6917 6918 case kWhatResume: 6919 { 6920 // We'll be active soon enough. 6921 return true; 6922 } 6923 6924 case kWhatFlush: 6925 { 6926 // We haven't even started yet, so we're flushed alright... 6927 mCodec->mCallback->onFlushCompleted(); 6928 return true; 6929 } 6930 6931 case kWhatSignalEndOfInputStream: 6932 { 6933 mCodec->onSignalEndOfInputStream(); 6934 return true; 6935 } 6936 6937 default: 6938 return BaseState::onMessageReceived(msg); 6939 } 6940} 6941 6942bool ACodec::IdleToExecutingState::onOMXEvent( 6943 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6944 switch (event) { 6945 case OMX_EventCmdComplete: 6946 { 6947 if (data1 != (OMX_U32)OMX_CommandStateSet 6948 || data2 != (OMX_U32)OMX_StateExecuting) { 6949 ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)", 6950 asString((OMX_COMMANDTYPE)data1), data1, 6951 asString((OMX_STATETYPE)data2), data2); 6952 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6953 return true; 6954 } 6955 6956 mCodec->mExecutingState->resume(); 6957 mCodec->changeState(mCodec->mExecutingState); 6958 6959 return true; 6960 } 6961 6962 default: 6963 return BaseState::onOMXEvent(event, data1, data2); 6964 } 6965} 6966 6967//////////////////////////////////////////////////////////////////////////////// 6968 6969ACodec::ExecutingState::ExecutingState(ACodec *codec) 6970 : BaseState(codec), 6971 mActive(false) { 6972} 6973 6974ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 6975 OMX_U32 /* portIndex */) { 6976 return RESUBMIT_BUFFERS; 6977} 6978 6979void ACodec::ExecutingState::submitOutputMetaBuffers() { 6980 // submit as many buffers as there are input buffers with the codec 6981 // in case we are in port reconfiguring 6982 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 6983 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 6984 6985 if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) { 6986 if (mCodec->submitOutputMetadataBuffer() != OK) 6987 break; 6988 } 6989 } 6990 6991 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 6992 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 6993} 6994 6995void ACodec::ExecutingState::submitRegularOutputBuffers() { 6996 bool failed = false; 6997 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 6998 BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 6999 7000 if (mCodec->mNativeWindow != NULL) { 7001 if (info->mStatus != BufferInfo::OWNED_BY_US 7002 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 7003 ALOGE("buffers should be owned by us or the surface"); 7004 failed = true; 7005 break; 7006 } 7007 7008 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 7009 continue; 7010 } 7011 } else { 7012 if (info->mStatus != BufferInfo::OWNED_BY_US) { 7013 ALOGE("buffers should be owned by us"); 7014 failed = true; 7015 break; 7016 } 7017 } 7018 7019 ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID); 7020 7021 info->checkWriteFence("submitRegularOutputBuffers"); 7022 status_t err = mCodec->fillBuffer(info); 7023 if (err != OK) { 7024 failed = true; 7025 break; 7026 } 7027 } 7028 7029 if (failed) { 7030 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7031 } 7032} 7033 7034void ACodec::ExecutingState::submitOutputBuffers() { 7035 submitRegularOutputBuffers(); 7036 if (mCodec->storingMetadataInDecodedBuffers()) { 7037 submitOutputMetaBuffers(); 7038 } 7039} 7040 7041void ACodec::ExecutingState::resume() { 7042 if (mActive) { 7043 ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str()); 7044 return; 7045 } 7046 7047 submitOutputBuffers(); 7048 7049 // Post all available input buffers 7050 if (mCodec->mBuffers[kPortIndexInput].size() == 0u) { 7051 ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str()); 7052 } 7053 7054 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) { 7055 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 7056 if (info->mStatus == BufferInfo::OWNED_BY_US) { 7057 postFillThisBuffer(info); 7058 } 7059 } 7060 7061 mActive = true; 7062} 7063 7064void ACodec::ExecutingState::stateEntered() { 7065 ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 7066 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 7067 mCodec->processDeferredMessages(); 7068} 7069 7070bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 7071 bool handled = false; 7072 7073 switch (msg->what()) { 7074 case kWhatShutdown: 7075 { 7076 int32_t keepComponentAllocated; 7077 CHECK(msg->findInt32( 7078 "keepComponentAllocated", &keepComponentAllocated)); 7079 7080 mCodec->mShutdownInProgress = true; 7081 mCodec->mExplicitShutdown = true; 7082 mCodec->mKeepComponentAllocated = keepComponentAllocated; 7083 7084 mActive = false; 7085 7086 status_t err = mCodec->mOMXNode->sendCommand( 7087 OMX_CommandStateSet, OMX_StateIdle); 7088 if (err != OK) { 7089 if (keepComponentAllocated) { 7090 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7091 } 7092 // TODO: do some recovery here. 7093 } else { 7094 mCodec->changeState(mCodec->mExecutingToIdleState); 7095 } 7096 7097 handled = true; 7098 break; 7099 } 7100 7101 case kWhatFlush: 7102 { 7103 ALOGV("[%s] ExecutingState flushing now " 7104 "(codec owns %zu/%zu input, %zu/%zu output).", 7105 mCodec->mComponentName.c_str(), 7106 mCodec->countBuffersOwnedByComponent(kPortIndexInput), 7107 mCodec->mBuffers[kPortIndexInput].size(), 7108 mCodec->countBuffersOwnedByComponent(kPortIndexOutput), 7109 mCodec->mBuffers[kPortIndexOutput].size()); 7110 7111 mActive = false; 7112 7113 status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL); 7114 if (err != OK) { 7115 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7116 } else { 7117 mCodec->changeState(mCodec->mFlushingState); 7118 } 7119 7120 handled = true; 7121 break; 7122 } 7123 7124 case kWhatResume: 7125 { 7126 resume(); 7127 7128 handled = true; 7129 break; 7130 } 7131 7132 case kWhatRequestIDRFrame: 7133 { 7134 status_t err = mCodec->requestIDRFrame(); 7135 if (err != OK) { 7136 ALOGW("Requesting an IDR frame failed."); 7137 } 7138 7139 handled = true; 7140 break; 7141 } 7142 7143 case kWhatSetParameters: 7144 { 7145 sp<AMessage> params; 7146 CHECK(msg->findMessage("params", ¶ms)); 7147 7148 status_t err = mCodec->setParameters(params); 7149 7150 sp<AMessage> reply; 7151 if (msg->findMessage("reply", &reply)) { 7152 reply->setInt32("err", err); 7153 reply->post(); 7154 } 7155 7156 handled = true; 7157 break; 7158 } 7159 7160 case ACodec::kWhatSignalEndOfInputStream: 7161 { 7162 mCodec->onSignalEndOfInputStream(); 7163 handled = true; 7164 break; 7165 } 7166 7167 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 7168 case kWhatSubmitOutputMetadataBufferIfEOS: 7169 { 7170 if (mCodec->mPortEOS[kPortIndexInput] && 7171 !mCodec->mPortEOS[kPortIndexOutput]) { 7172 status_t err = mCodec->submitOutputMetadataBuffer(); 7173 if (err == OK) { 7174 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 7175 } 7176 } 7177 return true; 7178 } 7179 7180 default: 7181 handled = BaseState::onMessageReceived(msg); 7182 break; 7183 } 7184 7185 return handled; 7186} 7187 7188status_t ACodec::setParameters(const sp<AMessage> ¶ms) { 7189 int32_t videoBitrate; 7190 if (params->findInt32("video-bitrate", &videoBitrate)) { 7191 OMX_VIDEO_CONFIG_BITRATETYPE configParams; 7192 InitOMXParams(&configParams); 7193 configParams.nPortIndex = kPortIndexOutput; 7194 configParams.nEncodeBitrate = videoBitrate; 7195 7196 status_t err = mOMXNode->setConfig( 7197 OMX_IndexConfigVideoBitrate, 7198 &configParams, 7199 sizeof(configParams)); 7200 7201 if (err != OK) { 7202 ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d", 7203 videoBitrate, err); 7204 7205 return err; 7206 } 7207 } 7208 7209 int64_t timeOffsetUs; 7210 if (params->findInt64("time-offset-us", &timeOffsetUs)) { 7211 if (mGraphicBufferSource == NULL) { 7212 ALOGE("[%s] Invalid to set input buffer time offset without surface", 7213 mComponentName.c_str()); 7214 return INVALID_OPERATION; 7215 } 7216 7217 status_t err = statusFromBinderStatus( 7218 mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs)); 7219 7220 if (err != OK) { 7221 ALOGE("[%s] Unable to set input buffer time offset (err %d)", 7222 mComponentName.c_str(), 7223 err); 7224 return err; 7225 } 7226 } 7227 7228 int64_t skipFramesBeforeUs; 7229 if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) { 7230 if (mGraphicBufferSource == NULL) { 7231 ALOGE("[%s] Invalid to set start time without surface", 7232 mComponentName.c_str()); 7233 return INVALID_OPERATION; 7234 } 7235 7236 status_t err = statusFromBinderStatus( 7237 mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs)); 7238 7239 if (err != OK) { 7240 ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err); 7241 return err; 7242 } 7243 } 7244 7245 int32_t dropInputFrames; 7246 if (params->findInt32("drop-input-frames", &dropInputFrames)) { 7247 if (mGraphicBufferSource == NULL) { 7248 ALOGE("[%s] Invalid to set suspend without surface", 7249 mComponentName.c_str()); 7250 return INVALID_OPERATION; 7251 } 7252 7253 int64_t suspendStartTimeUs = -1; 7254 (void) params->findInt64("drop-start-time-us", &suspendStartTimeUs); 7255 status_t err = statusFromBinderStatus( 7256 mGraphicBufferSource->setSuspend(dropInputFrames != 0, suspendStartTimeUs)); 7257 7258 if (err != OK) { 7259 ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err); 7260 return err; 7261 } 7262 } 7263 7264 int64_t stopTimeUs; 7265 if (params->findInt64("stop-time-us", &stopTimeUs)) { 7266 if (mGraphicBufferSource == NULL) { 7267 ALOGE("[%s] Invalid to set stop time without surface", 7268 mComponentName.c_str()); 7269 return INVALID_OPERATION; 7270 } 7271 status_t err = statusFromBinderStatus( 7272 mGraphicBufferSource->setStopTimeUs(stopTimeUs)); 7273 7274 if (err != OK) { 7275 ALOGE("Failed to set parameter 'stop-time-us' (err %d)", err); 7276 return err; 7277 } 7278 7279 int64_t stopTimeOffsetUs; 7280 err = statusFromBinderStatus( 7281 mGraphicBufferSource->getStopTimeOffsetUs(&stopTimeOffsetUs)); 7282 7283 if (err != OK) { 7284 ALOGE("Failed to get stop time offset (err %d)", err); 7285 return err; 7286 } 7287 mInputFormat->setInt64("android._stop-time-offset-us", stopTimeOffsetUs); 7288 } 7289 7290 int32_t dummy; 7291 if (params->findInt32("request-sync", &dummy)) { 7292 status_t err = requestIDRFrame(); 7293 7294 if (err != OK) { 7295 ALOGE("Requesting a sync frame failed w/ err %d", err); 7296 return err; 7297 } 7298 } 7299 7300 float rate; 7301 if (params->findFloat("operating-rate", &rate) && rate > 0) { 7302 status_t err = setOperatingRate(rate, mIsVideo); 7303 if (err != OK) { 7304 ALOGE("Failed to set parameter 'operating-rate' (err %d)", err); 7305 return err; 7306 } 7307 } 7308 7309 int32_t intraRefreshPeriod = 0; 7310 if (params->findInt32("intra-refresh-period", &intraRefreshPeriod) 7311 && intraRefreshPeriod > 0) { 7312 status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false); 7313 if (err != OK) { 7314 ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional", 7315 mComponentName.c_str()); 7316 err = OK; 7317 } 7318 } 7319 7320 int32_t latency = 0; 7321 if (params->findInt32("latency", &latency) && latency > 0) { 7322 status_t err = setLatency(latency); 7323 if (err != OK) { 7324 ALOGI("[%s] failed setLatency. Failure is fine since this key is optional", 7325 mComponentName.c_str()); 7326 err = OK; 7327 } 7328 } 7329 7330 status_t err = configureTemporalLayers(params, false /* inConfigure */, mOutputFormat); 7331 if (err != OK) { 7332 err = OK; // ignore failure 7333 } 7334 7335 return setVendorParameters(params); 7336} 7337 7338// Removes trailing tags matching |tag| from |key| (e.g. a settings name). |minLength| specifies 7339// the minimum number of characters to keep in |key| (even if it has trailing tags). 7340// (Used to remove trailing 'value' tags in settings names, e.g. to normalize 7341// 'vendor.settingsX.value' to 'vendor.settingsX') 7342static void removeTrailingTags(char *key, size_t minLength, const char *tag) { 7343 size_t length = strlen(key); 7344 size_t tagLength = strlen(tag); 7345 while (length > minLength + tagLength 7346 && !strcmp(key + length - tagLength, tag) 7347 && key[length - tagLength - 1] == '.') { 7348 length -= tagLength + 1; 7349 key[length] = '\0'; 7350 } 7351} 7352 7353/** 7354 * Struct encompassing a vendor extension config structure and a potential error status (in case 7355 * the structure is null). Used to iterate through vendor extensions. 7356 */ 7357struct VendorExtension { 7358 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config; // structure does not own config 7359 status_t status; 7360 7361 // create based on an error status 7362 VendorExtension(status_t s_ = NO_INIT) : config(nullptr), status(s_) { } 7363 7364 // create based on a successfully retrieved config structure 7365 VendorExtension(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *c_) : config(c_), status(OK) { } 7366}; 7367 7368// class VendorExtensions; 7369/** 7370 * Forward iterator to enumerate vendor extensions supported by an OMX component. 7371 */ 7372class VendorExtensionIterator { 7373//private: 7374 static constexpr size_t kLastIndex = ~(size_t)0; // last index marker 7375 7376 sp<IOMXNode> mNode; // component 7377 size_t mIndex; // current android extension index 7378 std::unique_ptr<uint8_t[]> mBacking; // current extension's backing 7379 VendorExtension mCurrent; // current extension 7380 7381 VendorExtensionIterator(const sp<IOMXNode> &node, size_t index) 7382 : mNode(node), 7383 mIndex(index) { 7384 mCurrent = retrieve(); 7385 } 7386 7387 friend class VendorExtensions; 7388 7389public: 7390 // copy constructor 7391 VendorExtensionIterator(const VendorExtensionIterator &it) 7392 : VendorExtensionIterator(it.mNode, it.mIndex) { } 7393 7394 // retrieves the current extension pointed to by this iterator 7395 VendorExtension retrieve() { 7396 if (mIndex == kLastIndex) { 7397 return NO_INIT; 7398 } 7399 7400 // try with one param first, then retry if extension needs more than 1 param 7401 for (size_t paramSizeUsed = 1;; ) { 7402 if (paramSizeUsed > OMX_MAX_ANDROID_VENDOR_PARAMCOUNT) { 7403 return BAD_VALUE; // this prevents overflow in the following formula 7404 } 7405 7406 size_t size = sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE) + 7407 (paramSizeUsed - 1) * sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::param); 7408 mBacking.reset(new uint8_t[size]); 7409 if (!mBacking) { 7410 return NO_MEMORY; 7411 } 7412 7413 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = 7414 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(mBacking.get()); 7415 7416 InitOMXParams(config); 7417 config->nSize = size; 7418 config->nIndex = mIndex; 7419 config->nParamSizeUsed = paramSizeUsed; 7420 status_t err = mNode->getConfig( 7421 (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension, config, size); 7422 if (err == OK && config->nParamCount > paramSizeUsed && paramSizeUsed == 1) { 7423 // reallocate if we need a bigger config 7424 paramSizeUsed = config->nParamCount; 7425 continue; 7426 } else if (err == NOT_ENOUGH_DATA 7427 || (err != OK && mIndex == 0)) { 7428 // stop iterator on no-more signal, or if index is not at all supported 7429 mIndex = kLastIndex; 7430 return NO_INIT; 7431 } else if (err != OK) { 7432 return err; 7433 } else if (paramSizeUsed != config->nParamSizeUsed) { 7434 return BAD_VALUE; // component shall not modify size of nParam 7435 } 7436 7437 return config; 7438 } 7439 } 7440 7441 // returns extension pointed to by this iterator 7442 VendorExtension operator*() { 7443 return mCurrent; 7444 } 7445 7446 // prefix increment: move to next extension 7447 VendorExtensionIterator &operator++() { // prefix 7448 if (mIndex != kLastIndex) { 7449 ++mIndex; 7450 mCurrent = retrieve(); 7451 } 7452 return *this; 7453 } 7454 7455 // iterator equality operators 7456 bool operator==(const VendorExtensionIterator &o) { 7457 return mNode == o.mNode && mIndex == o.mIndex; 7458 } 7459 7460 bool operator!=(const VendorExtensionIterator &o) { 7461 return !(*this == o); 7462 } 7463}; 7464 7465/** 7466 * Iterable container for vendor extensions provided by a component 7467 */ 7468class VendorExtensions { 7469//private: 7470 sp<IOMXNode> mNode; 7471 7472public: 7473 VendorExtensions(const sp<IOMXNode> &node) 7474 : mNode(node) { 7475 } 7476 7477 VendorExtensionIterator begin() { 7478 return VendorExtensionIterator(mNode, 0); 7479 } 7480 7481 VendorExtensionIterator end() { 7482 return VendorExtensionIterator(mNode, VendorExtensionIterator::kLastIndex); 7483 } 7484}; 7485 7486status_t ACodec::setVendorParameters(const sp<AMessage> ¶ms) { 7487 std::map<std::string, std::string> vendorKeys; // maps reduced name to actual name 7488 constexpr char prefix[] = "vendor."; 7489 constexpr size_t prefixLength = sizeof(prefix) - 1; 7490 // longest possible vendor param name 7491 char reducedKey[OMX_MAX_STRINGNAME_SIZE + OMX_MAX_STRINGVALUE_SIZE]; 7492 7493 // identify all vendor keys to speed up search later and to detect vendor keys 7494 for (size_t i = params->countEntries(); i; --i) { 7495 AMessage::Type keyType; 7496 const char* key = params->getEntryNameAt(i - 1, &keyType); 7497 if (key != nullptr && !strncmp(key, prefix, prefixLength) 7498 // it is safe to limit format keys to the max vendor param size as we only 7499 // shorten parameter names by removing any trailing 'value' tags, and we 7500 // already remove the vendor prefix. 7501 && strlen(key + prefixLength) < sizeof(reducedKey) 7502 && (keyType == AMessage::kTypeInt32 7503 || keyType == AMessage::kTypeInt64 7504 || keyType == AMessage::kTypeString)) { 7505 strcpy(reducedKey, key + prefixLength); 7506 removeTrailingTags(reducedKey, 0, "value"); 7507 auto existingKey = vendorKeys.find(reducedKey); 7508 if (existingKey != vendorKeys.end()) { 7509 ALOGW("[%s] vendor parameter '%s' aliases parameter '%s'", 7510 mComponentName.c_str(), key, existingKey->second.c_str()); 7511 // ignore for now 7512 } 7513 vendorKeys.emplace(reducedKey, key); 7514 } 7515 } 7516 7517 // don't bother component if we don't have vendor extensions as they may not have implemented 7518 // the android vendor extension support, which will lead to unnecessary OMX failure logs. 7519 if (vendorKeys.empty()) { 7520 return OK; 7521 } 7522 7523 char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) + 7524 sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey)]; 7525 7526 status_t finalError = OK; 7527 7528 // don't try again if component does not have vendor extensions 7529 if (mVendorExtensionsStatus == kExtensionsNone) { 7530 return OK; 7531 } 7532 7533 for (VendorExtension ext : VendorExtensions(mOMXNode)) { 7534 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config; 7535 if (config == nullptr) { 7536 return ext.status; 7537 } 7538 7539 mVendorExtensionsStatus = kExtensionsExist; 7540 7541 config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name 7542 strcpy(key, (const char *)config->cName); 7543 size_t nameLength = strlen(key); 7544 key[nameLength] = '.'; 7545 7546 // don't set vendor extension if client has not provided any of its parameters 7547 // or if client simply unsets parameters that are already unset 7548 bool needToSet = false; 7549 for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) { 7550 // null-terminate param key 7551 config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0'; 7552 strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey); 7553 removeTrailingTags(key, nameLength, "value"); 7554 auto existingKey = vendorKeys.find(key); 7555 7556 // don't touch (e.g. change) parameters that are not specified by client 7557 if (existingKey == vendorKeys.end()) { 7558 continue; 7559 } 7560 7561 bool wasSet = config->param[paramIndex].bSet; 7562 switch (config->param[paramIndex].eValueType) { 7563 case OMX_AndroidVendorValueInt32: 7564 { 7565 int32_t value; 7566 config->param[paramIndex].bSet = 7567 (OMX_BOOL)params->findInt32(existingKey->second.c_str(), &value); 7568 if (config->param[paramIndex].bSet) { 7569 config->param[paramIndex].nInt32 = value; 7570 } 7571 break; 7572 } 7573 case OMX_AndroidVendorValueInt64: 7574 { 7575 int64_t value; 7576 config->param[paramIndex].bSet = 7577 (OMX_BOOL)params->findAsInt64(existingKey->second.c_str(), &value); 7578 if (config->param[paramIndex].bSet) { 7579 config->param[paramIndex].nInt64 = value; 7580 } 7581 break; 7582 } 7583 case OMX_AndroidVendorValueString: 7584 { 7585 AString value; 7586 config->param[paramIndex].bSet = 7587 (OMX_BOOL)params->findString(existingKey->second.c_str(), &value); 7588 if (config->param[paramIndex].bSet) { 7589 strncpy((char *)config->param[paramIndex].cString, value.c_str(), 7590 sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cString)); 7591 } 7592 break; 7593 } 7594 default: 7595 ALOGW("[%s] vendor parameter '%s' is not a supported value", 7596 mComponentName.c_str(), key); 7597 continue; 7598 } 7599 if (config->param[paramIndex].bSet || wasSet) { 7600 needToSet = true; 7601 } 7602 } 7603 7604 if (needToSet) { 7605 status_t err = mOMXNode->setConfig( 7606 (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension, 7607 config, config->nSize); 7608 if (err != OK) { 7609 key[nameLength] = '\0'; 7610 ALOGW("[%s] failed to set vendor extension '%s'", mComponentName.c_str(), key); 7611 // try to set each extension, and return first failure 7612 if (finalError == OK) { 7613 finalError = err; 7614 } 7615 } 7616 } 7617 } 7618 7619 if (mVendorExtensionsStatus == kExtensionsUnchecked) { 7620 mVendorExtensionsStatus = kExtensionsNone; 7621 } 7622 7623 return finalError; 7624} 7625 7626status_t ACodec::getVendorParameters(OMX_U32 portIndex, sp<AMessage> &format) { 7627 constexpr char prefix[] = "vendor."; 7628 constexpr size_t prefixLength = sizeof(prefix) - 1; 7629 char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) + 7630 sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey) + prefixLength]; 7631 strcpy(key, prefix); 7632 7633 // don't try again if component does not have vendor extensions 7634 if (mVendorExtensionsStatus == kExtensionsNone) { 7635 return OK; 7636 } 7637 7638 for (VendorExtension ext : VendorExtensions(mOMXNode)) { 7639 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config; 7640 if (config == nullptr) { 7641 return ext.status; 7642 } 7643 7644 mVendorExtensionsStatus = kExtensionsExist; 7645 7646 if (config->eDir != (portIndex == kPortIndexInput ? OMX_DirInput : OMX_DirOutput)) { 7647 continue; 7648 } 7649 7650 config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name 7651 strcpy(key + prefixLength, (const char *)config->cName); 7652 size_t nameLength = strlen(key); 7653 key[nameLength] = '.'; 7654 7655 for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) { 7656 // null-terminate param key 7657 config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0'; 7658 strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey); 7659 removeTrailingTags(key, nameLength, "value"); 7660 if (config->param[paramIndex].bSet) { 7661 switch (config->param[paramIndex].eValueType) { 7662 case OMX_AndroidVendorValueInt32: 7663 { 7664 format->setInt32(key, config->param[paramIndex].nInt32); 7665 break; 7666 } 7667 case OMX_AndroidVendorValueInt64: 7668 { 7669 format->setInt64(key, config->param[paramIndex].nInt64); 7670 break; 7671 } 7672 case OMX_AndroidVendorValueString: 7673 { 7674 config->param[paramIndex].cString[OMX_MAX_STRINGVALUE_SIZE - 1] = '\0'; 7675 format->setString(key, (const char *)config->param[paramIndex].cString); 7676 break; 7677 } 7678 default: 7679 ALOGW("vendor parameter %s is not a supported value", key); 7680 continue; 7681 } 7682 } 7683 } 7684 } 7685 7686 if (mVendorExtensionsStatus == kExtensionsUnchecked) { 7687 mVendorExtensionsStatus = kExtensionsNone; 7688 } 7689 7690 return OK; 7691} 7692 7693void ACodec::onSignalEndOfInputStream() { 7694 status_t err = INVALID_OPERATION; 7695 if (mGraphicBufferSource != NULL) { 7696 err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream()); 7697 } 7698 mCallback->onSignaledInputEOS(err); 7699} 7700 7701void ACodec::forceStateTransition(int generation) { 7702 if (generation != mStateGeneration) { 7703 ALOGV("Ignoring stale force state transition message: #%d (now #%d)", 7704 generation, mStateGeneration); 7705 return; 7706 } 7707 ALOGE("State machine stuck"); 7708 // Error must have already been signalled to the client. 7709 7710 // Deferred messages will be handled at LoadedState at the end of the 7711 // transition. 7712 mShutdownInProgress = true; 7713 // No shutdown complete callback at the end of the transition. 7714 mExplicitShutdown = false; 7715 mKeepComponentAllocated = true; 7716 7717 status_t err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle); 7718 if (err != OK) { 7719 // TODO: do some recovery here. 7720 } else { 7721 changeState(mExecutingToIdleState); 7722 } 7723} 7724 7725bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { 7726 mCodec->onFrameRendered(mediaTimeUs, systemNano); 7727 return true; 7728} 7729 7730bool ACodec::ExecutingState::onOMXEvent( 7731 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7732 switch (event) { 7733 case OMX_EventPortSettingsChanged: 7734 { 7735 CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 7736 7737 mCodec->onOutputFormatChanged(); 7738 7739 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 7740 mCodec->mMetadataBuffersToSubmit = 0; 7741 CHECK_EQ(mCodec->mOMXNode->sendCommand( 7742 OMX_CommandPortDisable, kPortIndexOutput), 7743 (status_t)OK); 7744 7745 mCodec->freeOutputBuffersNotOwnedByComponent(); 7746 7747 mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 7748 } else if (data2 != OMX_IndexConfigCommonOutputCrop 7749 && data2 != OMX_IndexConfigAndroidIntraRefresh) { 7750 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x", 7751 mCodec->mComponentName.c_str(), data2); 7752 } 7753 7754 return true; 7755 } 7756 7757 case OMX_EventBufferFlag: 7758 { 7759 return true; 7760 } 7761 7762 default: 7763 return BaseState::onOMXEvent(event, data1, data2); 7764 } 7765} 7766 7767//////////////////////////////////////////////////////////////////////////////// 7768 7769ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 7770 ACodec *codec) 7771 : BaseState(codec) { 7772} 7773 7774ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 7775 OMX_U32 portIndex) { 7776 if (portIndex == kPortIndexOutput) { 7777 return FREE_BUFFERS; 7778 } 7779 7780 CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 7781 7782 return RESUBMIT_BUFFERS; 7783} 7784 7785bool ACodec::OutputPortSettingsChangedState::onMessageReceived( 7786 const sp<AMessage> &msg) { 7787 bool handled = false; 7788 7789 switch (msg->what()) { 7790 case kWhatFlush: 7791 case kWhatShutdown: { 7792 if (mCodec->mFatalError) { 7793 sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec); 7794 msg->setInt32("generation", mCodec->mStateGeneration); 7795 msg->post(3000000); 7796 } 7797 // fall-through 7798 } 7799 case kWhatResume: 7800 case kWhatSetParameters: 7801 { 7802 if (msg->what() == kWhatResume) { 7803 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 7804 } 7805 7806 mCodec->deferMessage(msg); 7807 handled = true; 7808 break; 7809 } 7810 7811 case kWhatForceStateTransition: 7812 { 7813 int32_t generation = 0; 7814 CHECK(msg->findInt32("generation", &generation)); 7815 mCodec->forceStateTransition(generation); 7816 7817 handled = true; 7818 break; 7819 } 7820 7821 default: 7822 handled = BaseState::onMessageReceived(msg); 7823 break; 7824 } 7825 7826 return handled; 7827} 7828 7829void ACodec::OutputPortSettingsChangedState::stateEntered() { 7830 ALOGV("[%s] Now handling output port settings change", 7831 mCodec->mComponentName.c_str()); 7832} 7833 7834bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered( 7835 int64_t mediaTimeUs, nsecs_t systemNano) { 7836 mCodec->onFrameRendered(mediaTimeUs, systemNano); 7837 return true; 7838} 7839 7840bool ACodec::OutputPortSettingsChangedState::onOMXEvent( 7841 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7842 switch (event) { 7843 case OMX_EventCmdComplete: 7844 { 7845 if (data1 == (OMX_U32)OMX_CommandPortDisable) { 7846 if (data2 != (OMX_U32)kPortIndexOutput) { 7847 ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2); 7848 return false; 7849 } 7850 7851 ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str()); 7852 7853 status_t err = OK; 7854 if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) { 7855 ALOGE("disabled port should be empty, but has %zu buffers", 7856 mCodec->mBuffers[kPortIndexOutput].size()); 7857 err = FAILED_TRANSACTION; 7858 } else { 7859 if (mCodec->getTrebleFlag()) { 7860 mCodec->mAllocator[kPortIndexOutput].clear(); 7861 } else { 7862 mCodec->mDealer[kPortIndexOutput].clear(); 7863 } 7864 } 7865 7866 if (err == OK) { 7867 err = mCodec->mOMXNode->sendCommand( 7868 OMX_CommandPortEnable, kPortIndexOutput); 7869 } 7870 7871 if (err == OK) { 7872 err = mCodec->allocateBuffersOnPort(kPortIndexOutput); 7873 ALOGE_IF(err != OK, "Failed to allocate output port buffers after port " 7874 "reconfiguration: (%d)", err); 7875 mCodec->mCallback->onOutputBuffersChanged(); 7876 } 7877 7878 if (err != OK) { 7879 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 7880 ALOGE("Error occurred while disabling the output port"); 7881 } 7882 7883 return true; 7884 } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 7885 if (data2 != (OMX_U32)kPortIndexOutput) { 7886 ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2); 7887 return false; 7888 } 7889 7890 ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str()); 7891 7892 if (mCodec->mExecutingState->active()) { 7893 mCodec->mExecutingState->submitOutputBuffers(); 7894 } 7895 7896 mCodec->changeState(mCodec->mExecutingState); 7897 7898 return true; 7899 } 7900 7901 return false; 7902 } 7903 7904 default: 7905 return BaseState::onOMXEvent(event, data1, data2); 7906 } 7907} 7908 7909//////////////////////////////////////////////////////////////////////////////// 7910 7911ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 7912 : BaseState(codec), 7913 mComponentNowIdle(false) { 7914} 7915 7916bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 7917 bool handled = false; 7918 7919 switch (msg->what()) { 7920 case kWhatFlush: 7921 { 7922 // Don't send me a flush request if you previously wanted me 7923 // to shutdown. 7924 ALOGW("Ignoring flush request in ExecutingToIdleState"); 7925 break; 7926 } 7927 7928 case kWhatShutdown: 7929 { 7930 mCodec->deferMessage(msg); 7931 handled = true; 7932 break; 7933 } 7934 7935 default: 7936 handled = BaseState::onMessageReceived(msg); 7937 break; 7938 } 7939 7940 return handled; 7941} 7942 7943void ACodec::ExecutingToIdleState::stateEntered() { 7944 ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 7945 7946 mComponentNowIdle = false; 7947 mCodec->mLastOutputFormat.clear(); 7948} 7949 7950bool ACodec::ExecutingToIdleState::onOMXEvent( 7951 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7952 switch (event) { 7953 case OMX_EventCmdComplete: 7954 { 7955 if (data1 != (OMX_U32)OMX_CommandStateSet 7956 || data2 != (OMX_U32)OMX_StateIdle) { 7957 ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)", 7958 asString((OMX_COMMANDTYPE)data1), data1, 7959 asString((OMX_STATETYPE)data2), data2); 7960 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7961 return true; 7962 } 7963 7964 mComponentNowIdle = true; 7965 7966 changeStateIfWeOwnAllBuffers(); 7967 7968 return true; 7969 } 7970 7971 case OMX_EventPortSettingsChanged: 7972 case OMX_EventBufferFlag: 7973 { 7974 // We're shutting down and don't care about this anymore. 7975 return true; 7976 } 7977 7978 default: 7979 return BaseState::onOMXEvent(event, data1, data2); 7980 } 7981} 7982 7983void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 7984 if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) { 7985 status_t err = mCodec->mOMXNode->sendCommand( 7986 OMX_CommandStateSet, OMX_StateLoaded); 7987 if (err == OK) { 7988 err = mCodec->freeBuffersOnPort(kPortIndexInput); 7989 status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput); 7990 if (err == OK) { 7991 err = err2; 7992 } 7993 } 7994 7995 if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) 7996 && mCodec->mNativeWindow != NULL) { 7997 // We push enough 1x1 blank buffers to ensure that one of 7998 // them has made it to the display. This allows the OMX 7999 // component teardown to zero out any protected buffers 8000 // without the risk of scanning out one of those buffers. 8001 pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get()); 8002 } 8003 8004 if (err != OK) { 8005 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 8006 return; 8007 } 8008 8009 mCodec->changeState(mCodec->mIdleToLoadedState); 8010 } 8011} 8012 8013void ACodec::ExecutingToIdleState::onInputBufferFilled( 8014 const sp<AMessage> &msg) { 8015 BaseState::onInputBufferFilled(msg); 8016 8017 changeStateIfWeOwnAllBuffers(); 8018} 8019 8020void ACodec::ExecutingToIdleState::onOutputBufferDrained( 8021 const sp<AMessage> &msg) { 8022 BaseState::onOutputBufferDrained(msg); 8023 8024 changeStateIfWeOwnAllBuffers(); 8025} 8026 8027//////////////////////////////////////////////////////////////////////////////// 8028 8029ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 8030 : BaseState(codec) { 8031} 8032 8033bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 8034 bool handled = false; 8035 8036 switch (msg->what()) { 8037 case kWhatShutdown: 8038 { 8039 mCodec->deferMessage(msg); 8040 handled = true; 8041 break; 8042 } 8043 8044 case kWhatFlush: 8045 { 8046 // Don't send me a flush request if you previously wanted me 8047 // to shutdown. 8048 ALOGE("Got flush request in IdleToLoadedState"); 8049 break; 8050 } 8051 8052 default: 8053 handled = BaseState::onMessageReceived(msg); 8054 break; 8055 } 8056 8057 return handled; 8058} 8059 8060void ACodec::IdleToLoadedState::stateEntered() { 8061 ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 8062} 8063 8064bool ACodec::IdleToLoadedState::onOMXEvent( 8065 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 8066 switch (event) { 8067 case OMX_EventCmdComplete: 8068 { 8069 if (data1 != (OMX_U32)OMX_CommandStateSet 8070 || data2 != (OMX_U32)OMX_StateLoaded) { 8071 ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)", 8072 asString((OMX_COMMANDTYPE)data1), data1, 8073 asString((OMX_STATETYPE)data2), data2); 8074 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 8075 return true; 8076 } 8077 8078 mCodec->changeState(mCodec->mLoadedState); 8079 8080 return true; 8081 } 8082 8083 default: 8084 return BaseState::onOMXEvent(event, data1, data2); 8085 } 8086} 8087 8088//////////////////////////////////////////////////////////////////////////////// 8089 8090ACodec::FlushingState::FlushingState(ACodec *codec) 8091 : BaseState(codec) { 8092} 8093 8094void ACodec::FlushingState::stateEntered() { 8095 ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 8096 8097 mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 8098} 8099 8100bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 8101 bool handled = false; 8102 8103 switch (msg->what()) { 8104 case kWhatShutdown: 8105 { 8106 mCodec->deferMessage(msg); 8107 if (mCodec->mFatalError) { 8108 sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec); 8109 msg->setInt32("generation", mCodec->mStateGeneration); 8110 msg->post(3000000); 8111 } 8112 break; 8113 } 8114 8115 case kWhatFlush: 8116 { 8117 // We're already doing this right now. 8118 handled = true; 8119 break; 8120 } 8121 8122 case kWhatForceStateTransition: 8123 { 8124 int32_t generation = 0; 8125 CHECK(msg->findInt32("generation", &generation)); 8126 mCodec->forceStateTransition(generation); 8127 8128 handled = true; 8129 break; 8130 } 8131 8132 default: 8133 handled = BaseState::onMessageReceived(msg); 8134 break; 8135 } 8136 8137 return handled; 8138} 8139 8140bool ACodec::FlushingState::onOMXEvent( 8141 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 8142 ALOGV("[%s] FlushingState onOMXEvent(%u,%d)", 8143 mCodec->mComponentName.c_str(), event, (OMX_S32)data1); 8144 8145 switch (event) { 8146 case OMX_EventCmdComplete: 8147 { 8148 if (data1 != (OMX_U32)OMX_CommandFlush) { 8149 ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState", 8150 asString((OMX_COMMANDTYPE)data1), data1, data2); 8151 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 8152 return true; 8153 } 8154 8155 if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 8156 if (mFlushComplete[data2]) { 8157 ALOGW("Flush already completed for %s port", 8158 data2 == kPortIndexInput ? "input" : "output"); 8159 return true; 8160 } 8161 mFlushComplete[data2] = true; 8162 8163 if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) { 8164 changeStateIfWeOwnAllBuffers(); 8165 } 8166 } else if (data2 == OMX_ALL) { 8167 if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) { 8168 ALOGW("received flush complete event for OMX_ALL before ports have been" 8169 "flushed (%d/%d)", 8170 mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]); 8171 return false; 8172 } 8173 8174 changeStateIfWeOwnAllBuffers(); 8175 } else { 8176 ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2); 8177 } 8178 8179 return true; 8180 } 8181 8182 case OMX_EventPortSettingsChanged: 8183 { 8184 sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec); 8185 msg->setInt32("type", omx_message::EVENT); 8186 msg->setInt32("generation", mCodec->mNodeGeneration); 8187 msg->setInt32("event", event); 8188 msg->setInt32("data1", data1); 8189 msg->setInt32("data2", data2); 8190 8191 ALOGV("[%s] Deferring OMX_EventPortSettingsChanged", 8192 mCodec->mComponentName.c_str()); 8193 8194 mCodec->deferMessage(msg); 8195 8196 return true; 8197 } 8198 8199 default: 8200 return BaseState::onOMXEvent(event, data1, data2); 8201 } 8202 8203 return true; 8204} 8205 8206void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 8207 BaseState::onOutputBufferDrained(msg); 8208 8209 changeStateIfWeOwnAllBuffers(); 8210} 8211 8212void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 8213 BaseState::onInputBufferFilled(msg); 8214 8215 changeStateIfWeOwnAllBuffers(); 8216} 8217 8218void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 8219 if (mFlushComplete[kPortIndexInput] 8220 && mFlushComplete[kPortIndexOutput] 8221 && mCodec->allYourBuffersAreBelongToUs()) { 8222 // We now own all buffers except possibly those still queued with 8223 // the native window for rendering. Let's get those back as well. 8224 mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs(); 8225 8226 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 8227 8228 mCodec->mCallback->onFlushCompleted(); 8229 8230 mCodec->mPortEOS[kPortIndexInput] = 8231 mCodec->mPortEOS[kPortIndexOutput] = false; 8232 8233 mCodec->mInputEOSResult = OK; 8234 8235 if (mCodec->mSkipCutBuffer != NULL) { 8236 mCodec->mSkipCutBuffer->clear(); 8237 } 8238 8239 mCodec->changeState(mCodec->mExecutingState); 8240 } 8241} 8242 8243status_t ACodec::queryCapabilities( 8244 const char* owner, const char* name, const char* mime, bool isEncoder, 8245 MediaCodecInfo::CapabilitiesWriter* caps) { 8246 const char *role = GetComponentRole(isEncoder, mime); 8247 if (role == NULL) { 8248 return BAD_VALUE; 8249 } 8250 8251 OMXClient client; 8252 status_t err = client.connect(owner); 8253 if (err != OK) { 8254 return err; 8255 } 8256 8257 sp<IOMX> omx = client.interface(); 8258 sp<CodecObserver> observer = new CodecObserver; 8259 sp<IOMXNode> omxNode; 8260 8261 err = omx->allocateNode(name, observer, &omxNode); 8262 if (err != OK) { 8263 client.disconnect(); 8264 return err; 8265 } 8266 8267 err = SetComponentRole(omxNode, role); 8268 if (err != OK) { 8269 omxNode->freeNode(); 8270 client.disconnect(); 8271 return err; 8272 } 8273 8274 bool isVideo = strncasecmp(mime, "video/", 6) == 0; 8275 8276 if (isVideo) { 8277 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 8278 InitOMXParams(¶m); 8279 param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput; 8280 8281 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 8282 param.nProfileIndex = index; 8283 status_t err = omxNode->getParameter( 8284 OMX_IndexParamVideoProfileLevelQuerySupported, 8285 ¶m, sizeof(param)); 8286 if (err != OK) { 8287 break; 8288 } 8289 caps->addProfileLevel(param.eProfile, param.eLevel); 8290 8291 // AVC components may not list the constrained profiles explicitly, but 8292 // decoders that support a profile also support its constrained version. 8293 // Encoders must explicitly support constrained profiles. 8294 if (!isEncoder && strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) == 0) { 8295 if (param.eProfile == OMX_VIDEO_AVCProfileHigh) { 8296 caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedHigh, param.eLevel); 8297 } else if (param.eProfile == OMX_VIDEO_AVCProfileBaseline) { 8298 caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedBaseline, param.eLevel); 8299 } 8300 } 8301 8302 if (index == kMaxIndicesToCheck) { 8303 ALOGW("[%s] stopping checking profiles after %u: %x/%x", 8304 name, index, 8305 param.eProfile, param.eLevel); 8306 } 8307 } 8308 8309 // Color format query 8310 // return colors in the order reported by the OMX component 8311 // prefix "flexible" standard ones with the flexible equivalent 8312 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 8313 InitOMXParams(&portFormat); 8314 portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput; 8315 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 8316 portFormat.nIndex = index; 8317 status_t err = omxNode->getParameter( 8318 OMX_IndexParamVideoPortFormat, 8319 &portFormat, sizeof(portFormat)); 8320 if (err != OK) { 8321 break; 8322 } 8323 8324 OMX_U32 flexibleEquivalent; 8325 if (IsFlexibleColorFormat( 8326 omxNode, portFormat.eColorFormat, false /* usingNativeWindow */, 8327 &flexibleEquivalent)) { 8328 caps->addColorFormat(flexibleEquivalent); 8329 } 8330 caps->addColorFormat(portFormat.eColorFormat); 8331 8332 if (index == kMaxIndicesToCheck) { 8333 ALOGW("[%s] stopping checking formats after %u: %s(%x)", 8334 name, index, 8335 asString(portFormat.eColorFormat), portFormat.eColorFormat); 8336 } 8337 } 8338 } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC) == 0) { 8339 // More audio codecs if they have profiles. 8340 OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param; 8341 InitOMXParams(¶m); 8342 param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput; 8343 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 8344 param.nProfileIndex = index; 8345 status_t err = omxNode->getParameter( 8346 (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported, 8347 ¶m, sizeof(param)); 8348 if (err != OK) { 8349 break; 8350 } 8351 // For audio, level is ignored. 8352 caps->addProfileLevel(param.eProfile, 0 /* level */); 8353 8354 if (index == kMaxIndicesToCheck) { 8355 ALOGW("[%s] stopping checking profiles after %u: %x", 8356 name, index, 8357 param.eProfile); 8358 } 8359 } 8360 8361 // NOTE: Without Android extensions, OMX does not provide a way to query 8362 // AAC profile support 8363 if (param.nProfileIndex == 0) { 8364 ALOGW("component %s doesn't support profile query.", name); 8365 } 8366 } 8367 8368 if (isVideo && !isEncoder) { 8369 native_handle_t *sidebandHandle = NULL; 8370 if (omxNode->configureVideoTunnelMode( 8371 kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) { 8372 // tunneled playback includes adaptive playback 8373 caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback 8374 | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback); 8375 } else if (omxNode->setPortMode( 8376 kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK || 8377 omxNode->prepareForAdaptivePlayback( 8378 kPortIndexOutput, OMX_TRUE, 8379 1280 /* width */, 720 /* height */) == OK) { 8380 caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback); 8381 } 8382 } 8383 8384 if (isVideo && isEncoder) { 8385 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params; 8386 InitOMXParams(¶ms); 8387 params.nPortIndex = kPortIndexOutput; 8388 // TODO: should we verify if fallback is supported? 8389 if (omxNode->getConfig( 8390 (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, 8391 ¶ms, sizeof(params)) == OK) { 8392 caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh); 8393 } 8394 } 8395 8396 omxNode->freeNode(); 8397 client.disconnect(); 8398 return OK; 8399} 8400 8401// These are supposed be equivalent to the logic in 8402// "audio_channel_out_mask_from_count". 8403//static 8404status_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) { 8405 switch (numChannels) { 8406 case 1: 8407 map[0] = OMX_AUDIO_ChannelCF; 8408 break; 8409 case 2: 8410 map[0] = OMX_AUDIO_ChannelLF; 8411 map[1] = OMX_AUDIO_ChannelRF; 8412 break; 8413 case 3: 8414 map[0] = OMX_AUDIO_ChannelLF; 8415 map[1] = OMX_AUDIO_ChannelRF; 8416 map[2] = OMX_AUDIO_ChannelCF; 8417 break; 8418 case 4: 8419 map[0] = OMX_AUDIO_ChannelLF; 8420 map[1] = OMX_AUDIO_ChannelRF; 8421 map[2] = OMX_AUDIO_ChannelLR; 8422 map[3] = OMX_AUDIO_ChannelRR; 8423 break; 8424 case 5: 8425 map[0] = OMX_AUDIO_ChannelLF; 8426 map[1] = OMX_AUDIO_ChannelRF; 8427 map[2] = OMX_AUDIO_ChannelCF; 8428 map[3] = OMX_AUDIO_ChannelLR; 8429 map[4] = OMX_AUDIO_ChannelRR; 8430 break; 8431 case 6: 8432 map[0] = OMX_AUDIO_ChannelLF; 8433 map[1] = OMX_AUDIO_ChannelRF; 8434 map[2] = OMX_AUDIO_ChannelCF; 8435 map[3] = OMX_AUDIO_ChannelLFE; 8436 map[4] = OMX_AUDIO_ChannelLR; 8437 map[5] = OMX_AUDIO_ChannelRR; 8438 break; 8439 case 7: 8440 map[0] = OMX_AUDIO_ChannelLF; 8441 map[1] = OMX_AUDIO_ChannelRF; 8442 map[2] = OMX_AUDIO_ChannelCF; 8443 map[3] = OMX_AUDIO_ChannelLFE; 8444 map[4] = OMX_AUDIO_ChannelLR; 8445 map[5] = OMX_AUDIO_ChannelRR; 8446 map[6] = OMX_AUDIO_ChannelCS; 8447 break; 8448 case 8: 8449 map[0] = OMX_AUDIO_ChannelLF; 8450 map[1] = OMX_AUDIO_ChannelRF; 8451 map[2] = OMX_AUDIO_ChannelCF; 8452 map[3] = OMX_AUDIO_ChannelLFE; 8453 map[4] = OMX_AUDIO_ChannelLR; 8454 map[5] = OMX_AUDIO_ChannelRR; 8455 map[6] = OMX_AUDIO_ChannelLS; 8456 map[7] = OMX_AUDIO_ChannelRS; 8457 break; 8458 default: 8459 return -EINVAL; 8460 } 8461 8462 return OK; 8463} 8464 8465void ACodec::setTrebleFlag(bool trebleFlag) { 8466 mTrebleFlag = trebleFlag; 8467} 8468 8469bool ACodec::getTrebleFlag() const { 8470 return mTrebleFlag; 8471} 8472 8473} // namespace android 8474