ACodec.cpp revision ba40190c5e8d9bfe5b814984c6861809fea064bd
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 // propagate framerate to the output so that the muxer has it 3785 outputFormat->setInt32("frame-rate", (int32_t)mFps); 3786 3787 video_def->xFramerate = (OMX_U32)(mFps * 65536); 3788 video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; 3789 // this is redundant as it was already set up in setVideoPortFormatType 3790 // FIXME for now skip this only for flexible YUV formats 3791 if (colorFormat != OMX_COLOR_FormatYUV420Flexible) { 3792 video_def->eColorFormat = colorFormat; 3793 } 3794 3795 err = mOMXNode->setParameter( 3796 OMX_IndexParamPortDefinition, &def, sizeof(def)); 3797 3798 if (err != OK) { 3799 ALOGE("[%s] failed to set input port definition parameters.", 3800 mComponentName.c_str()); 3801 3802 return err; 3803 } 3804 3805 /* Output port configuration */ 3806 3807 OMX_VIDEO_CODINGTYPE compressionFormat; 3808 err = GetVideoCodingTypeFromMime(mime, &compressionFormat); 3809 3810 if (err != OK) { 3811 return err; 3812 } 3813 3814 err = setVideoPortFormatType( 3815 kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused); 3816 3817 if (err != OK) { 3818 ALOGE("[%s] does not support compression format %d", 3819 mComponentName.c_str(), compressionFormat); 3820 3821 return err; 3822 } 3823 3824 def.nPortIndex = kPortIndexOutput; 3825 3826 err = mOMXNode->getParameter( 3827 OMX_IndexParamPortDefinition, &def, sizeof(def)); 3828 3829 if (err != OK) { 3830 return err; 3831 } 3832 3833 video_def->nFrameWidth = width; 3834 video_def->nFrameHeight = height; 3835 video_def->xFramerate = 0; 3836 video_def->nBitrate = bitrate; 3837 video_def->eCompressionFormat = compressionFormat; 3838 video_def->eColorFormat = OMX_COLOR_FormatUnused; 3839 3840 err = mOMXNode->setParameter( 3841 OMX_IndexParamPortDefinition, &def, sizeof(def)); 3842 3843 if (err != OK) { 3844 ALOGE("[%s] failed to set output port definition parameters.", 3845 mComponentName.c_str()); 3846 3847 return err; 3848 } 3849 3850 int32_t intraRefreshPeriod = 0; 3851 if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod) 3852 && intraRefreshPeriod >= 0) { 3853 err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true); 3854 if (err != OK) { 3855 ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional", 3856 mComponentName.c_str()); 3857 err = OK; 3858 } 3859 } 3860 3861 configureEncoderLatency(msg); 3862 3863 switch (compressionFormat) { 3864 case OMX_VIDEO_CodingMPEG4: 3865 err = setupMPEG4EncoderParameters(msg); 3866 break; 3867 3868 case OMX_VIDEO_CodingH263: 3869 err = setupH263EncoderParameters(msg); 3870 break; 3871 3872 case OMX_VIDEO_CodingAVC: 3873 err = setupAVCEncoderParameters(msg); 3874 break; 3875 3876 case OMX_VIDEO_CodingHEVC: 3877 err = setupHEVCEncoderParameters(msg); 3878 break; 3879 3880 case OMX_VIDEO_CodingVP8: 3881 case OMX_VIDEO_CodingVP9: 3882 err = setupVPXEncoderParameters(msg, outputFormat); 3883 break; 3884 3885 default: 3886 break; 3887 } 3888 3889 if (err != OK) { 3890 return err; 3891 } 3892 3893 // Set up color aspects on input, but propagate them to the output format, as they will 3894 // not be read back from encoder. 3895 err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat); 3896 if (err == ERROR_UNSUPPORTED) { 3897 ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str()); 3898 err = OK; 3899 } 3900 3901 if (err != OK) { 3902 return err; 3903 } 3904 3905 err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat); 3906 if (err == ERROR_UNSUPPORTED) { // support is optional 3907 ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str()); 3908 err = OK; 3909 } 3910 3911 if (err != OK) { 3912 return err; 3913 } 3914 3915 switch (compressionFormat) { 3916 case OMX_VIDEO_CodingAVC: 3917 case OMX_VIDEO_CodingHEVC: 3918 err = configureTemporalLayers(msg, true /* inConfigure */, outputFormat); 3919 if (err != OK) { 3920 err = OK; // ignore failure 3921 } 3922 break; 3923 3924 case OMX_VIDEO_CodingVP8: 3925 case OMX_VIDEO_CodingVP9: 3926 // TODO: do we need to support android.generic layering? webrtc layering is 3927 // already set up in setupVPXEncoderParameters. 3928 break; 3929 3930 default: 3931 break; 3932 } 3933 3934 if (err == OK) { 3935 ALOGI("setupVideoEncoder succeeded"); 3936 } 3937 3938 return err; 3939} 3940 3941status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) { 3942 OMX_VIDEO_PARAM_INTRAREFRESHTYPE params; 3943 InitOMXParams(¶ms); 3944 params.nPortIndex = kPortIndexOutput; 3945 3946 params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode); 3947 3948 if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic || 3949 params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 3950 int32_t mbs; 3951 if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) { 3952 return INVALID_OPERATION; 3953 } 3954 params.nCirMBs = mbs; 3955 } 3956 3957 if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive || 3958 params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 3959 int32_t mbs; 3960 if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) { 3961 return INVALID_OPERATION; 3962 } 3963 params.nAirMBs = mbs; 3964 3965 int32_t ref; 3966 if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) { 3967 return INVALID_OPERATION; 3968 } 3969 params.nAirRef = ref; 3970 } 3971 3972 status_t err = mOMXNode->setParameter( 3973 OMX_IndexParamVideoIntraRefresh, ¶ms, sizeof(params)); 3974 return err; 3975} 3976 3977static OMX_U32 setPFramesSpacing( 3978 float iFramesInterval /* seconds */, int32_t frameRate, uint32_t BFramesSpacing = 0) { 3979 // BFramesSpacing is the number of B frames between I/P frames 3980 // PFramesSpacing (the value to be returned) is the number of P frames between I frames 3981 // 3982 // keyFrameInterval = ((PFramesSpacing + 1) * BFramesSpacing) + PFramesSpacing + 1 3983 // ^^^ ^^^ ^^^ 3984 // number of B frames number of P I frame 3985 // 3986 // = (PFramesSpacing + 1) * (BFramesSpacing + 1) 3987 // 3988 // E.g. 3989 // I P I : I-interval: 8, nPFrames 1, nBFrames 3 3990 // BBB BBB 3991 3992 if (iFramesInterval < 0) { // just 1 key frame 3993 return 0xFFFFFFFE; // don't use maxint as key-frame-interval calculation will add 1 3994 } else if (iFramesInterval == 0) { // just key frames 3995 return 0; 3996 } 3997 3998 // round down as key-frame-interval is an upper limit 3999 uint32_t keyFrameInterval = uint32_t(frameRate * iFramesInterval); 4000 OMX_U32 ret = keyFrameInterval / (BFramesSpacing + 1); 4001 return ret > 0 ? ret - 1 : 0; 4002} 4003 4004static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) { 4005 int32_t tmp; 4006 if (!msg->findInt32("bitrate-mode", &tmp)) { 4007 return OMX_Video_ControlRateVariable; 4008 } 4009 4010 return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp); 4011} 4012 4013status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) { 4014 int32_t bitrate; 4015 float iFrameInterval; 4016 if (!msg->findInt32("bitrate", &bitrate) 4017 || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) { 4018 return INVALID_OPERATION; 4019 } 4020 4021 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 4022 4023 float frameRate; 4024 if (!msg->findFloat("frame-rate", &frameRate)) { 4025 int32_t tmp; 4026 if (!msg->findInt32("frame-rate", &tmp)) { 4027 return INVALID_OPERATION; 4028 } 4029 frameRate = (float)tmp; 4030 } 4031 4032 OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type; 4033 InitOMXParams(&mpeg4type); 4034 mpeg4type.nPortIndex = kPortIndexOutput; 4035 4036 status_t err = mOMXNode->getParameter( 4037 OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 4038 4039 if (err != OK) { 4040 return err; 4041 } 4042 4043 mpeg4type.nSliceHeaderSpacing = 0; 4044 mpeg4type.bSVH = OMX_FALSE; 4045 mpeg4type.bGov = OMX_FALSE; 4046 4047 mpeg4type.nAllowedPictureTypes = 4048 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 4049 4050 mpeg4type.nBFrames = 0; 4051 mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, mpeg4type.nBFrames); 4052 if (mpeg4type.nPFrames == 0) { 4053 mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 4054 } 4055 mpeg4type.nIDCVLCThreshold = 0; 4056 mpeg4type.bACPred = OMX_TRUE; 4057 mpeg4type.nMaxPacketSize = 256; 4058 mpeg4type.nTimeIncRes = 1000; 4059 mpeg4type.nHeaderExtension = 0; 4060 mpeg4type.bReversibleVLC = OMX_FALSE; 4061 4062 int32_t profile; 4063 if (msg->findInt32("profile", &profile)) { 4064 int32_t level; 4065 if (!msg->findInt32("level", &level)) { 4066 return INVALID_OPERATION; 4067 } 4068 4069 err = verifySupportForProfileAndLevel(profile, level); 4070 4071 if (err != OK) { 4072 return err; 4073 } 4074 4075 mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile); 4076 mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level); 4077 } 4078 4079 err = mOMXNode->setParameter( 4080 OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 4081 4082 if (err != OK) { 4083 return err; 4084 } 4085 4086 err = configureBitrate(bitrate, bitrateMode); 4087 4088 if (err != OK) { 4089 return err; 4090 } 4091 4092 return setupErrorCorrectionParameters(); 4093} 4094 4095status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) { 4096 int32_t bitrate; 4097 float iFrameInterval; 4098 if (!msg->findInt32("bitrate", &bitrate) 4099 || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) { 4100 return INVALID_OPERATION; 4101 } 4102 4103 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 4104 4105 float frameRate; 4106 if (!msg->findFloat("frame-rate", &frameRate)) { 4107 int32_t tmp; 4108 if (!msg->findInt32("frame-rate", &tmp)) { 4109 return INVALID_OPERATION; 4110 } 4111 frameRate = (float)tmp; 4112 } 4113 4114 OMX_VIDEO_PARAM_H263TYPE h263type; 4115 InitOMXParams(&h263type); 4116 h263type.nPortIndex = kPortIndexOutput; 4117 4118 status_t err = mOMXNode->getParameter( 4119 OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 4120 4121 if (err != OK) { 4122 return err; 4123 } 4124 4125 h263type.nAllowedPictureTypes = 4126 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 4127 4128 h263type.nBFrames = 0; 4129 h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h263type.nBFrames); 4130 if (h263type.nPFrames == 0) { 4131 h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 4132 } 4133 4134 int32_t profile; 4135 if (msg->findInt32("profile", &profile)) { 4136 int32_t level; 4137 if (!msg->findInt32("level", &level)) { 4138 return INVALID_OPERATION; 4139 } 4140 4141 err = verifySupportForProfileAndLevel(profile, level); 4142 4143 if (err != OK) { 4144 return err; 4145 } 4146 4147 h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile); 4148 h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level); 4149 } 4150 4151 h263type.bPLUSPTYPEAllowed = OMX_FALSE; 4152 h263type.bForceRoundingTypeToZero = OMX_FALSE; 4153 h263type.nPictureHeaderRepetition = 0; 4154 h263type.nGOBHeaderInterval = 0; 4155 4156 err = mOMXNode->setParameter( 4157 OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 4158 4159 if (err != OK) { 4160 return err; 4161 } 4162 4163 err = configureBitrate(bitrate, bitrateMode); 4164 4165 if (err != OK) { 4166 return err; 4167 } 4168 4169 return setupErrorCorrectionParameters(); 4170} 4171 4172// static 4173int /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor( 4174 int width, int height, int rate, int bitrate, 4175 OMX_VIDEO_AVCPROFILEEXTTYPE profile) { 4176 // convert bitrate to main/baseline profile kbps equivalent 4177 switch ((uint32_t)profile) { 4178 case OMX_VIDEO_AVCProfileHigh10: 4179 bitrate = divUp(bitrate, 3000); break; 4180 case OMX_VIDEO_AVCProfileConstrainedHigh: 4181 case OMX_VIDEO_AVCProfileHigh: 4182 bitrate = divUp(bitrate, 1250); break; 4183 default: 4184 bitrate = divUp(bitrate, 1000); break; 4185 } 4186 4187 // convert size and rate to MBs 4188 width = divUp(width, 16); 4189 height = divUp(height, 16); 4190 int mbs = width * height; 4191 rate *= mbs; 4192 int maxDimension = max(width, height); 4193 4194 static const int limits[][5] = { 4195 /* MBps MB dim bitrate level */ 4196 { 1485, 99, 28, 64, OMX_VIDEO_AVCLevel1 }, 4197 { 1485, 99, 28, 128, OMX_VIDEO_AVCLevel1b }, 4198 { 3000, 396, 56, 192, OMX_VIDEO_AVCLevel11 }, 4199 { 6000, 396, 56, 384, OMX_VIDEO_AVCLevel12 }, 4200 { 11880, 396, 56, 768, OMX_VIDEO_AVCLevel13 }, 4201 { 11880, 396, 56, 2000, OMX_VIDEO_AVCLevel2 }, 4202 { 19800, 792, 79, 4000, OMX_VIDEO_AVCLevel21 }, 4203 { 20250, 1620, 113, 4000, OMX_VIDEO_AVCLevel22 }, 4204 { 40500, 1620, 113, 10000, OMX_VIDEO_AVCLevel3 }, 4205 { 108000, 3600, 169, 14000, OMX_VIDEO_AVCLevel31 }, 4206 { 216000, 5120, 202, 20000, OMX_VIDEO_AVCLevel32 }, 4207 { 245760, 8192, 256, 20000, OMX_VIDEO_AVCLevel4 }, 4208 { 245760, 8192, 256, 50000, OMX_VIDEO_AVCLevel41 }, 4209 { 522240, 8704, 263, 50000, OMX_VIDEO_AVCLevel42 }, 4210 { 589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5 }, 4211 { 983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 }, 4212 { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 }, 4213 }; 4214 4215 for (size_t i = 0; i < ARRAY_SIZE(limits); i++) { 4216 const int (&limit)[5] = limits[i]; 4217 if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2] 4218 && bitrate <= limit[3]) { 4219 return limit[4]; 4220 } 4221 } 4222 return 0; 4223} 4224 4225status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) { 4226 int32_t bitrate; 4227 float iFrameInterval; 4228 if (!msg->findInt32("bitrate", &bitrate) 4229 || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) { 4230 return INVALID_OPERATION; 4231 } 4232 4233 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 4234 4235 float frameRate; 4236 if (!msg->findFloat("frame-rate", &frameRate)) { 4237 int32_t tmp; 4238 if (!msg->findInt32("frame-rate", &tmp)) { 4239 return INVALID_OPERATION; 4240 } 4241 frameRate = (float)tmp; 4242 } 4243 4244 status_t err = OK; 4245 int32_t intraRefreshMode = 0; 4246 if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) { 4247 err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode); 4248 if (err != OK) { 4249 ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x", 4250 err, intraRefreshMode); 4251 return err; 4252 } 4253 } 4254 4255 OMX_VIDEO_PARAM_AVCTYPE h264type; 4256 InitOMXParams(&h264type); 4257 h264type.nPortIndex = kPortIndexOutput; 4258 4259 err = mOMXNode->getParameter( 4260 OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 4261 4262 if (err != OK) { 4263 return err; 4264 } 4265 4266 h264type.nAllowedPictureTypes = 4267 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 4268 4269 int32_t profile; 4270 if (msg->findInt32("profile", &profile)) { 4271 int32_t level; 4272 if (!msg->findInt32("level", &level)) { 4273 return INVALID_OPERATION; 4274 } 4275 4276 err = verifySupportForProfileAndLevel(profile, level); 4277 4278 if (err != OK) { 4279 return err; 4280 } 4281 4282 h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile); 4283 h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level); 4284 } else { 4285 h264type.eProfile = OMX_VIDEO_AVCProfileBaseline; 4286#if 0 /* DON'T YET DEFAULT TO HIGHEST PROFILE */ 4287 // Use largest supported profile for AVC recording if profile is not specified. 4288 for (OMX_VIDEO_AVCPROFILETYPE profile : { 4289 OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCProfileMain }) { 4290 if (verifySupportForProfileAndLevel(profile, 0) == OK) { 4291 h264type.eProfile = profile; 4292 break; 4293 } 4294 } 4295#endif 4296 } 4297 4298 ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]", 4299 asString(h264type.eProfile), asString(h264type.eLevel)); 4300 4301 if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) { 4302 h264type.nSliceHeaderSpacing = 0; 4303 h264type.bUseHadamard = OMX_TRUE; 4304 h264type.nRefFrames = 1; 4305 h264type.nBFrames = 0; 4306 h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames); 4307 if (h264type.nPFrames == 0) { 4308 h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 4309 } 4310 h264type.nRefIdx10ActiveMinus1 = 0; 4311 h264type.nRefIdx11ActiveMinus1 = 0; 4312 h264type.bEntropyCodingCABAC = OMX_FALSE; 4313 h264type.bWeightedPPrediction = OMX_FALSE; 4314 h264type.bconstIpred = OMX_FALSE; 4315 h264type.bDirect8x8Inference = OMX_FALSE; 4316 h264type.bDirectSpatialTemporal = OMX_FALSE; 4317 h264type.nCabacInitIdc = 0; 4318 } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain || 4319 h264type.eProfile == OMX_VIDEO_AVCProfileHigh) { 4320 h264type.nSliceHeaderSpacing = 0; 4321 h264type.bUseHadamard = OMX_TRUE; 4322 h264type.nRefFrames = 2; 4323 h264type.nBFrames = mLatency == 0 ? 1 : std::min(1U, mLatency - 1); 4324 4325 // disable B-frames until MPEG4Writer can guarantee finalizing files with B-frames 4326 h264type.nRefFrames = 1; 4327 h264type.nBFrames = 0; 4328 4329 h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames); 4330 h264type.nAllowedPictureTypes = 4331 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 4332 h264type.nRefIdx10ActiveMinus1 = 0; 4333 h264type.nRefIdx11ActiveMinus1 = 0; 4334 h264type.bEntropyCodingCABAC = OMX_TRUE; 4335 h264type.bWeightedPPrediction = OMX_TRUE; 4336 h264type.bconstIpred = OMX_TRUE; 4337 h264type.bDirect8x8Inference = OMX_TRUE; 4338 h264type.bDirectSpatialTemporal = OMX_TRUE; 4339 h264type.nCabacInitIdc = 1; 4340 } 4341 4342 if (h264type.nBFrames != 0) { 4343 h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; 4344 } 4345 4346 h264type.bEnableUEP = OMX_FALSE; 4347 h264type.bEnableFMO = OMX_FALSE; 4348 h264type.bEnableASO = OMX_FALSE; 4349 h264type.bEnableRS = OMX_FALSE; 4350 h264type.bFrameMBsOnly = OMX_TRUE; 4351 h264type.bMBAFF = OMX_FALSE; 4352 h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; 4353 4354 err = mOMXNode->setParameter( 4355 OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 4356 4357 if (err != OK) { 4358 return err; 4359 } 4360 4361 // TRICKY: if we are enabling temporal layering as well, some codecs may not support layering 4362 // when B-frames are enabled. Detect this now so we can disable B frames if temporal layering 4363 // is preferred. 4364 AString tsSchema; 4365 int32_t preferBFrames = (int32_t)false; 4366 if (msg->findString("ts-schema", &tsSchema) 4367 && (!msg->findInt32("android._prefer-b-frames", &preferBFrames) || !preferBFrames)) { 4368 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layering; 4369 InitOMXParams(&layering); 4370 layering.nPortIndex = kPortIndexOutput; 4371 if (mOMXNode->getParameter( 4372 (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering, 4373 &layering, sizeof(layering)) == OK 4374 && layering.eSupportedPatterns 4375 && layering.nBLayerCountMax == 0) { 4376 h264type.nBFrames = 0; 4377 h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames); 4378 h264type.nAllowedPictureTypes &= ~OMX_VIDEO_PictureTypeB; 4379 ALOGI("disabling B-frames"); 4380 err = mOMXNode->setParameter( 4381 OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 4382 4383 if (err != OK) { 4384 return err; 4385 } 4386 } 4387 } 4388 4389 return configureBitrate(bitrate, bitrateMode); 4390} 4391 4392status_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) { 4393 int32_t bitrate; 4394 float iFrameInterval; 4395 if (!msg->findInt32("bitrate", &bitrate) 4396 || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) { 4397 return INVALID_OPERATION; 4398 } 4399 4400 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 4401 4402 float frameRate; 4403 if (!msg->findFloat("frame-rate", &frameRate)) { 4404 int32_t tmp; 4405 if (!msg->findInt32("frame-rate", &tmp)) { 4406 return INVALID_OPERATION; 4407 } 4408 frameRate = (float)tmp; 4409 } 4410 4411 OMX_VIDEO_PARAM_HEVCTYPE hevcType; 4412 InitOMXParams(&hevcType); 4413 hevcType.nPortIndex = kPortIndexOutput; 4414 4415 status_t err = OK; 4416 err = mOMXNode->getParameter( 4417 (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType)); 4418 if (err != OK) { 4419 return err; 4420 } 4421 4422 int32_t profile; 4423 if (msg->findInt32("profile", &profile)) { 4424 int32_t level; 4425 if (!msg->findInt32("level", &level)) { 4426 return INVALID_OPERATION; 4427 } 4428 4429 err = verifySupportForProfileAndLevel(profile, level); 4430 if (err != OK) { 4431 return err; 4432 } 4433 4434 hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile); 4435 hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level); 4436 } 4437 // TODO: finer control? 4438 hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1; 4439 4440 err = mOMXNode->setParameter( 4441 (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType)); 4442 if (err != OK) { 4443 return err; 4444 } 4445 4446 return configureBitrate(bitrate, bitrateMode); 4447} 4448 4449status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat) { 4450 int32_t bitrate; 4451 float iFrameInterval = 0; 4452 size_t tsLayers = 0; 4453 OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern = 4454 OMX_VIDEO_VPXTemporalLayerPatternNone; 4455 static const uint32_t kVp8LayerRateAlloction 4456 [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] 4457 [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = { 4458 {100, 100, 100}, // 1 layer 4459 { 60, 100, 100}, // 2 layers {60%, 40%} 4460 { 40, 60, 100}, // 3 layers {40%, 20%, 40%} 4461 }; 4462 if (!msg->findInt32("bitrate", &bitrate)) { 4463 return INVALID_OPERATION; 4464 } 4465 msg->findAsFloat("i-frame-interval", &iFrameInterval); 4466 4467 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 4468 4469 float frameRate; 4470 if (!msg->findFloat("frame-rate", &frameRate)) { 4471 int32_t tmp; 4472 if (!msg->findInt32("frame-rate", &tmp)) { 4473 return INVALID_OPERATION; 4474 } 4475 frameRate = (float)tmp; 4476 } 4477 4478 AString tsSchema; 4479 OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE tsType = 4480 OMX_VIDEO_AndroidTemporalLayeringPatternNone; 4481 4482 if (msg->findString("ts-schema", &tsSchema)) { 4483 unsigned int numLayers = 0; 4484 unsigned int numBLayers = 0; 4485 int tags; 4486 char dummy; 4487 if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1 4488 && numLayers > 0) { 4489 pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 4490 tsType = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC; 4491 tsLayers = numLayers; 4492 } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c", 4493 &numLayers, &dummy, &numBLayers, &dummy)) 4494 && (tags == 1 || (tags == 3 && dummy == '+')) 4495 && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) { 4496 pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 4497 // VPX does not have a concept of B-frames, so just count all layers 4498 tsType = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid; 4499 tsLayers = numLayers + numBLayers; 4500 } else { 4501 ALOGW("Ignoring unsupported ts-schema [%s]", tsSchema.c_str()); 4502 } 4503 tsLayers = min(tsLayers, (size_t)OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS); 4504 } 4505 4506 OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; 4507 InitOMXParams(&vp8type); 4508 vp8type.nPortIndex = kPortIndexOutput; 4509 status_t err = mOMXNode->getParameter( 4510 (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 4511 &vp8type, sizeof(vp8type)); 4512 4513 if (err == OK) { 4514 if (iFrameInterval > 0) { 4515 vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1; 4516 } 4517 vp8type.eTemporalPattern = pattern; 4518 vp8type.nTemporalLayerCount = tsLayers; 4519 if (tsLayers > 0) { 4520 for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) { 4521 vp8type.nTemporalLayerBitrateRatio[i] = 4522 kVp8LayerRateAlloction[tsLayers - 1][i]; 4523 } 4524 } 4525 if (bitrateMode == OMX_Video_ControlRateConstant) { 4526 vp8type.nMinQuantizer = 2; 4527 vp8type.nMaxQuantizer = 63; 4528 } 4529 4530 err = mOMXNode->setParameter( 4531 (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 4532 &vp8type, sizeof(vp8type)); 4533 if (err != OK) { 4534 ALOGW("Extended VP8 parameters set failed: %d", err); 4535 } else if (tsType == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) { 4536 // advertise even single layer WebRTC layering, as it is defined 4537 outputFormat->setString("ts-schema", AStringPrintf("webrtc.vp8.%u-layer", tsLayers)); 4538 } else if (tsLayers > 0) { 4539 // tsType == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid 4540 outputFormat->setString("ts-schema", AStringPrintf("android.generic.%u", tsLayers)); 4541 } 4542 } 4543 4544 return configureBitrate(bitrate, bitrateMode); 4545} 4546 4547status_t ACodec::verifySupportForProfileAndLevel( 4548 int32_t profile, int32_t level) { 4549 OMX_VIDEO_PARAM_PROFILELEVELTYPE params; 4550 InitOMXParams(¶ms); 4551 params.nPortIndex = kPortIndexOutput; 4552 4553 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 4554 params.nProfileIndex = index; 4555 status_t err = mOMXNode->getParameter( 4556 OMX_IndexParamVideoProfileLevelQuerySupported, 4557 ¶ms, sizeof(params)); 4558 4559 if (err != OK) { 4560 return err; 4561 } 4562 4563 int32_t supportedProfile = static_cast<int32_t>(params.eProfile); 4564 int32_t supportedLevel = static_cast<int32_t>(params.eLevel); 4565 4566 if (profile == supportedProfile && level <= supportedLevel) { 4567 return OK; 4568 } 4569 4570 if (index == kMaxIndicesToCheck) { 4571 ALOGW("[%s] stopping checking profiles after %u: %x/%x", 4572 mComponentName.c_str(), index, 4573 params.eProfile, params.eLevel); 4574 } 4575 } 4576 return ERROR_UNSUPPORTED; 4577} 4578 4579status_t ACodec::configureBitrate( 4580 int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) { 4581 OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 4582 InitOMXParams(&bitrateType); 4583 bitrateType.nPortIndex = kPortIndexOutput; 4584 4585 status_t err = mOMXNode->getParameter( 4586 OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType)); 4587 4588 if (err != OK) { 4589 return err; 4590 } 4591 4592 bitrateType.eControlRate = bitrateMode; 4593 bitrateType.nTargetBitrate = bitrate; 4594 4595 return mOMXNode->setParameter( 4596 OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType)); 4597} 4598 4599void ACodec::configureEncoderLatency(const sp<AMessage> &msg) { 4600 if (!mIsEncoder || !mIsVideo) { 4601 return; 4602 } 4603 4604 int32_t latency = 0, bitrateMode; 4605 if (msg->findInt32("latency", &latency) && latency > 0) { 4606 status_t err = setLatency(latency); 4607 if (err != OK) { 4608 ALOGW("[%s] failed setLatency. Failure is fine since this key is optional", 4609 mComponentName.c_str()); 4610 err = OK; 4611 } else { 4612 mLatency = latency; 4613 } 4614 } else if ((!msg->findInt32("bitrate-mode", &bitrateMode) && 4615 bitrateMode == OMX_Video_ControlRateConstant)) { 4616 // default the latency to be 1 if latency key is not specified or unsupported and bitrateMode 4617 // is CBR. 4618 mLatency = 1; 4619 } 4620} 4621 4622status_t ACodec::setupErrorCorrectionParameters() { 4623 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; 4624 InitOMXParams(&errorCorrectionType); 4625 errorCorrectionType.nPortIndex = kPortIndexOutput; 4626 4627 status_t err = mOMXNode->getParameter( 4628 OMX_IndexParamVideoErrorCorrection, 4629 &errorCorrectionType, sizeof(errorCorrectionType)); 4630 4631 if (err != OK) { 4632 return OK; // Optional feature. Ignore this failure 4633 } 4634 4635 errorCorrectionType.bEnableHEC = OMX_FALSE; 4636 errorCorrectionType.bEnableResync = OMX_TRUE; 4637 errorCorrectionType.nResynchMarkerSpacing = 256; 4638 errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; 4639 errorCorrectionType.bEnableRVLC = OMX_FALSE; 4640 4641 return mOMXNode->setParameter( 4642 OMX_IndexParamVideoErrorCorrection, 4643 &errorCorrectionType, sizeof(errorCorrectionType)); 4644} 4645 4646status_t ACodec::setVideoFormatOnPort( 4647 OMX_U32 portIndex, 4648 int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat, 4649 float frameRate) { 4650 OMX_PARAM_PORTDEFINITIONTYPE def; 4651 InitOMXParams(&def); 4652 def.nPortIndex = portIndex; 4653 4654 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 4655 4656 status_t err = mOMXNode->getParameter( 4657 OMX_IndexParamPortDefinition, &def, sizeof(def)); 4658 if (err != OK) { 4659 return err; 4660 } 4661 4662 if (portIndex == kPortIndexInput) { 4663 // XXX Need a (much) better heuristic to compute input buffer sizes. 4664 const size_t X = 64 * 1024; 4665 if (def.nBufferSize < X) { 4666 def.nBufferSize = X; 4667 } 4668 } 4669 4670 if (def.eDomain != OMX_PortDomainVideo) { 4671 ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain); 4672 return FAILED_TRANSACTION; 4673 } 4674 4675 video_def->nFrameWidth = width; 4676 video_def->nFrameHeight = height; 4677 4678 if (portIndex == kPortIndexInput) { 4679 video_def->eCompressionFormat = compressionFormat; 4680 video_def->eColorFormat = OMX_COLOR_FormatUnused; 4681 if (frameRate >= 0) { 4682 video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f); 4683 } 4684 } 4685 4686 err = mOMXNode->setParameter( 4687 OMX_IndexParamPortDefinition, &def, sizeof(def)); 4688 4689 return err; 4690} 4691 4692size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const { 4693 size_t n = 0; 4694 4695 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 4696 const BufferInfo &info = mBuffers[portIndex].itemAt(i); 4697 4698 if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) { 4699 ++n; 4700 } 4701 } 4702 4703 return n; 4704} 4705 4706size_t ACodec::countBuffersOwnedByNativeWindow() const { 4707 size_t n = 0; 4708 4709 for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) { 4710 const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i); 4711 4712 if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 4713 ++n; 4714 } 4715 } 4716 4717 return n; 4718} 4719 4720void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() { 4721 if (mNativeWindow == NULL) { 4722 return; 4723 } 4724 4725 while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers 4726 && dequeueBufferFromNativeWindow() != NULL) { 4727 // these buffers will be submitted as regular buffers; account for this 4728 if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) { 4729 --mMetadataBuffersToSubmit; 4730 } 4731 } 4732} 4733 4734bool ACodec::allYourBuffersAreBelongToUs( 4735 OMX_U32 portIndex) { 4736 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 4737 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 4738 4739 if (info->mStatus != BufferInfo::OWNED_BY_US 4740 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 4741 ALOGV("[%s] Buffer %u on port %u still has status %d", 4742 mComponentName.c_str(), 4743 info->mBufferID, portIndex, info->mStatus); 4744 return false; 4745 } 4746 } 4747 4748 return true; 4749} 4750 4751bool ACodec::allYourBuffersAreBelongToUs() { 4752 return allYourBuffersAreBelongToUs(kPortIndexInput) 4753 && allYourBuffersAreBelongToUs(kPortIndexOutput); 4754} 4755 4756void ACodec::deferMessage(const sp<AMessage> &msg) { 4757 mDeferredQueue.push_back(msg); 4758} 4759 4760void ACodec::processDeferredMessages() { 4761 List<sp<AMessage> > queue = mDeferredQueue; 4762 mDeferredQueue.clear(); 4763 4764 List<sp<AMessage> >::iterator it = queue.begin(); 4765 while (it != queue.end()) { 4766 onMessageReceived(*it++); 4767 } 4768} 4769 4770status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) { 4771 const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output"; 4772 OMX_PARAM_PORTDEFINITIONTYPE def; 4773 InitOMXParams(&def); 4774 def.nPortIndex = portIndex; 4775 4776 status_t err = mOMXNode->getParameter(OMX_IndexParamPortDefinition, &def, sizeof(def)); 4777 if (err != OK) { 4778 return err; 4779 } 4780 4781 if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) { 4782 ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex); 4783 return BAD_VALUE; 4784 } 4785 4786 switch (def.eDomain) { 4787 case OMX_PortDomainVideo: 4788 { 4789 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 4790 switch ((int)videoDef->eCompressionFormat) { 4791 case OMX_VIDEO_CodingUnused: 4792 { 4793 CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput)); 4794 notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW); 4795 4796 notify->setInt32("stride", videoDef->nStride); 4797 notify->setInt32("slice-height", videoDef->nSliceHeight); 4798 notify->setInt32("color-format", videoDef->eColorFormat); 4799 4800 if (mNativeWindow == NULL) { 4801 DescribeColorFormat2Params describeParams; 4802 InitOMXParams(&describeParams); 4803 describeParams.eColorFormat = videoDef->eColorFormat; 4804 describeParams.nFrameWidth = videoDef->nFrameWidth; 4805 describeParams.nFrameHeight = videoDef->nFrameHeight; 4806 describeParams.nStride = videoDef->nStride; 4807 describeParams.nSliceHeight = videoDef->nSliceHeight; 4808 describeParams.bUsingNativeBuffers = OMX_FALSE; 4809 4810 if (DescribeColorFormat(mOMXNode, describeParams)) { 4811 notify->setBuffer( 4812 "image-data", 4813 ABuffer::CreateAsCopy( 4814 &describeParams.sMediaImage, 4815 sizeof(describeParams.sMediaImage))); 4816 4817 MediaImage2 &img = describeParams.sMediaImage; 4818 MediaImage2::PlaneInfo *plane = img.mPlane; 4819 ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }", 4820 mComponentName.c_str(), img.mWidth, img.mHeight, 4821 plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc, 4822 plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc, 4823 plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc); 4824 } 4825 } 4826 4827 int32_t width = (int32_t)videoDef->nFrameWidth; 4828 int32_t height = (int32_t)videoDef->nFrameHeight; 4829 4830 if (portIndex == kPortIndexOutput) { 4831 OMX_CONFIG_RECTTYPE rect; 4832 InitOMXParams(&rect); 4833 rect.nPortIndex = portIndex; 4834 4835 if (mOMXNode->getConfig( 4836 (portIndex == kPortIndexOutput ? 4837 OMX_IndexConfigCommonOutputCrop : 4838 OMX_IndexConfigCommonInputCrop), 4839 &rect, sizeof(rect)) != OK) { 4840 rect.nLeft = 0; 4841 rect.nTop = 0; 4842 rect.nWidth = videoDef->nFrameWidth; 4843 rect.nHeight = videoDef->nFrameHeight; 4844 } 4845 4846 if (rect.nLeft < 0 || 4847 rect.nTop < 0 || 4848 rect.nLeft + rect.nWidth > videoDef->nFrameWidth || 4849 rect.nTop + rect.nHeight > videoDef->nFrameHeight) { 4850 ALOGE("Wrong cropped rect (%d, %d, %u, %u) vs. frame (%u, %u)", 4851 rect.nLeft, rect.nTop, 4852 rect.nWidth, rect.nHeight, 4853 videoDef->nFrameWidth, videoDef->nFrameHeight); 4854 return BAD_VALUE; 4855 } 4856 4857 notify->setRect( 4858 "crop", 4859 rect.nLeft, 4860 rect.nTop, 4861 rect.nLeft + rect.nWidth - 1, 4862 rect.nTop + rect.nHeight - 1); 4863 4864 width = rect.nWidth; 4865 height = rect.nHeight; 4866 4867 android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN; 4868 (void)getColorAspectsAndDataSpaceForVideoDecoder( 4869 width, height, mConfigFormat, notify, 4870 mUsingNativeWindow ? &dataSpace : NULL); 4871 if (mUsingNativeWindow) { 4872 notify->setInt32("android._dataspace", dataSpace); 4873 } 4874 (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify); 4875 } else { 4876 (void)getInputColorAspectsForVideoEncoder(notify); 4877 if (mConfigFormat->contains("hdr-static-info")) { 4878 (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify); 4879 } 4880 uint32_t latency = 0; 4881 if (mIsEncoder && getLatency(&latency) == OK && latency > 0) { 4882 notify->setInt32("latency", latency); 4883 } 4884 } 4885 4886 break; 4887 } 4888 4889 case OMX_VIDEO_CodingVP8: 4890 case OMX_VIDEO_CodingVP9: 4891 { 4892 OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; 4893 InitOMXParams(&vp8type); 4894 vp8type.nPortIndex = kPortIndexOutput; 4895 status_t err = mOMXNode->getParameter( 4896 (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 4897 &vp8type, 4898 sizeof(vp8type)); 4899 4900 if (err == OK) { 4901 if (vp8type.eTemporalPattern == OMX_VIDEO_VPXTemporalLayerPatternWebRTC 4902 && vp8type.nTemporalLayerCount > 0 4903 && vp8type.nTemporalLayerCount 4904 <= OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS) { 4905 // advertise as android.generic if we configured for android.generic 4906 AString origSchema; 4907 if (notify->findString("ts-schema", &origSchema) 4908 && origSchema.startsWith("android.generic")) { 4909 notify->setString("ts-schema", AStringPrintf( 4910 "android.generic.%u", vp8type.nTemporalLayerCount)); 4911 } else { 4912 notify->setString("ts-schema", AStringPrintf( 4913 "webrtc.vp8.%u-layer", vp8type.nTemporalLayerCount)); 4914 } 4915 } 4916 } 4917 // Fall through to set up mime. 4918 } 4919 4920 default: 4921 { 4922 if (mIsEncoder ^ (portIndex == kPortIndexOutput)) { 4923 // should be CodingUnused 4924 ALOGE("Raw port video compression format is %s(%d)", 4925 asString(videoDef->eCompressionFormat), 4926 videoDef->eCompressionFormat); 4927 return BAD_VALUE; 4928 } 4929 AString mime; 4930 if (GetMimeTypeForVideoCoding( 4931 videoDef->eCompressionFormat, &mime) != OK) { 4932 notify->setString("mime", "application/octet-stream"); 4933 } else { 4934 notify->setString("mime", mime.c_str()); 4935 } 4936 uint32_t intraRefreshPeriod = 0; 4937 if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK 4938 && intraRefreshPeriod > 0) { 4939 notify->setInt32("intra-refresh-period", intraRefreshPeriod); 4940 } 4941 break; 4942 } 4943 } 4944 notify->setInt32("width", videoDef->nFrameWidth); 4945 notify->setInt32("height", videoDef->nFrameHeight); 4946 ALOGV("[%s] %s format is %s", mComponentName.c_str(), 4947 portIndex == kPortIndexInput ? "input" : "output", 4948 notify->debugString().c_str()); 4949 4950 break; 4951 } 4952 4953 case OMX_PortDomainAudio: 4954 { 4955 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 4956 4957 switch ((int)audioDef->eEncoding) { 4958 case OMX_AUDIO_CodingPCM: 4959 { 4960 OMX_AUDIO_PARAM_PCMMODETYPE params; 4961 InitOMXParams(¶ms); 4962 params.nPortIndex = portIndex; 4963 4964 err = mOMXNode->getParameter( 4965 OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4966 if (err != OK) { 4967 return err; 4968 } 4969 4970 if (params.nChannels <= 0 4971 || (params.nChannels != 1 && !params.bInterleaved) 4972 || params.ePCMMode != OMX_AUDIO_PCMModeLinear) { 4973 ALOGE("unsupported PCM port: %u channels%s, %u-bit", 4974 params.nChannels, 4975 params.bInterleaved ? " interleaved" : "", 4976 params.nBitPerSample); 4977 return FAILED_TRANSACTION; 4978 } 4979 4980 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW); 4981 notify->setInt32("channel-count", params.nChannels); 4982 notify->setInt32("sample-rate", params.nSamplingRate); 4983 4984 AudioEncoding encoding = kAudioEncodingPcm16bit; 4985 if (params.eNumData == OMX_NumericalDataUnsigned 4986 && params.nBitPerSample == 8u) { 4987 encoding = kAudioEncodingPcm8bit; 4988 } else if (params.eNumData == OMX_NumericalDataFloat 4989 && params.nBitPerSample == 32u) { 4990 encoding = kAudioEncodingPcmFloat; 4991 } else if (params.nBitPerSample != 16u 4992 || params.eNumData != OMX_NumericalDataSigned) { 4993 ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ", 4994 asString(params.eNumData), params.eNumData, 4995 asString(params.ePCMMode), params.ePCMMode); 4996 return FAILED_TRANSACTION; 4997 } 4998 notify->setInt32("pcm-encoding", encoding); 4999 5000 if (mChannelMaskPresent) { 5001 notify->setInt32("channel-mask", mChannelMask); 5002 } 5003 break; 5004 } 5005 5006 case OMX_AUDIO_CodingAAC: 5007 { 5008 OMX_AUDIO_PARAM_AACPROFILETYPE params; 5009 InitOMXParams(¶ms); 5010 params.nPortIndex = portIndex; 5011 5012 err = mOMXNode->getParameter( 5013 OMX_IndexParamAudioAac, ¶ms, sizeof(params)); 5014 if (err != OK) { 5015 return err; 5016 } 5017 5018 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 5019 notify->setInt32("channel-count", params.nChannels); 5020 notify->setInt32("sample-rate", params.nSampleRate); 5021 break; 5022 } 5023 5024 case OMX_AUDIO_CodingAMR: 5025 { 5026 OMX_AUDIO_PARAM_AMRTYPE params; 5027 InitOMXParams(¶ms); 5028 params.nPortIndex = portIndex; 5029 5030 err = mOMXNode->getParameter( 5031 OMX_IndexParamAudioAmr, ¶ms, sizeof(params)); 5032 if (err != OK) { 5033 return err; 5034 } 5035 5036 notify->setInt32("channel-count", 1); 5037 if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) { 5038 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB); 5039 notify->setInt32("sample-rate", 16000); 5040 } else { 5041 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB); 5042 notify->setInt32("sample-rate", 8000); 5043 } 5044 break; 5045 } 5046 5047 case OMX_AUDIO_CodingFLAC: 5048 { 5049 OMX_AUDIO_PARAM_FLACTYPE params; 5050 InitOMXParams(¶ms); 5051 params.nPortIndex = portIndex; 5052 5053 err = mOMXNode->getParameter( 5054 OMX_IndexParamAudioFlac, ¶ms, sizeof(params)); 5055 if (err != OK) { 5056 return err; 5057 } 5058 5059 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC); 5060 notify->setInt32("channel-count", params.nChannels); 5061 notify->setInt32("sample-rate", params.nSampleRate); 5062 break; 5063 } 5064 5065 case OMX_AUDIO_CodingMP3: 5066 { 5067 OMX_AUDIO_PARAM_MP3TYPE params; 5068 InitOMXParams(¶ms); 5069 params.nPortIndex = portIndex; 5070 5071 err = mOMXNode->getParameter( 5072 OMX_IndexParamAudioMp3, ¶ms, sizeof(params)); 5073 if (err != OK) { 5074 return err; 5075 } 5076 5077 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG); 5078 notify->setInt32("channel-count", params.nChannels); 5079 notify->setInt32("sample-rate", params.nSampleRate); 5080 break; 5081 } 5082 5083 case OMX_AUDIO_CodingVORBIS: 5084 { 5085 OMX_AUDIO_PARAM_VORBISTYPE params; 5086 InitOMXParams(¶ms); 5087 params.nPortIndex = portIndex; 5088 5089 err = mOMXNode->getParameter( 5090 OMX_IndexParamAudioVorbis, ¶ms, sizeof(params)); 5091 if (err != OK) { 5092 return err; 5093 } 5094 5095 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS); 5096 notify->setInt32("channel-count", params.nChannels); 5097 notify->setInt32("sample-rate", params.nSampleRate); 5098 break; 5099 } 5100 5101 case OMX_AUDIO_CodingAndroidAC3: 5102 { 5103 OMX_AUDIO_PARAM_ANDROID_AC3TYPE params; 5104 InitOMXParams(¶ms); 5105 params.nPortIndex = portIndex; 5106 5107 err = mOMXNode->getParameter( 5108 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 5109 ¶ms, sizeof(params)); 5110 if (err != OK) { 5111 return err; 5112 } 5113 5114 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3); 5115 notify->setInt32("channel-count", params.nChannels); 5116 notify->setInt32("sample-rate", params.nSampleRate); 5117 break; 5118 } 5119 5120 case OMX_AUDIO_CodingAndroidEAC3: 5121 { 5122 OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params; 5123 InitOMXParams(¶ms); 5124 params.nPortIndex = portIndex; 5125 5126 err = mOMXNode->getParameter( 5127 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, 5128 ¶ms, sizeof(params)); 5129 if (err != OK) { 5130 return err; 5131 } 5132 5133 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3); 5134 notify->setInt32("channel-count", params.nChannels); 5135 notify->setInt32("sample-rate", params.nSampleRate); 5136 break; 5137 } 5138 5139 case OMX_AUDIO_CodingAndroidOPUS: 5140 { 5141 OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params; 5142 InitOMXParams(¶ms); 5143 params.nPortIndex = portIndex; 5144 5145 err = mOMXNode->getParameter( 5146 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, 5147 ¶ms, sizeof(params)); 5148 if (err != OK) { 5149 return err; 5150 } 5151 5152 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS); 5153 notify->setInt32("channel-count", params.nChannels); 5154 notify->setInt32("sample-rate", params.nSampleRate); 5155 break; 5156 } 5157 5158 case OMX_AUDIO_CodingG711: 5159 { 5160 OMX_AUDIO_PARAM_PCMMODETYPE params; 5161 InitOMXParams(¶ms); 5162 params.nPortIndex = portIndex; 5163 5164 err = mOMXNode->getParameter( 5165 (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 5166 if (err != OK) { 5167 return err; 5168 } 5169 5170 const char *mime = NULL; 5171 if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) { 5172 mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW; 5173 } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) { 5174 mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW; 5175 } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear 5176 mime = MEDIA_MIMETYPE_AUDIO_RAW; 5177 } 5178 notify->setString("mime", mime); 5179 notify->setInt32("channel-count", params.nChannels); 5180 notify->setInt32("sample-rate", params.nSamplingRate); 5181 notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit); 5182 break; 5183 } 5184 5185 case OMX_AUDIO_CodingGSMFR: 5186 { 5187 OMX_AUDIO_PARAM_PCMMODETYPE params; 5188 InitOMXParams(¶ms); 5189 params.nPortIndex = portIndex; 5190 5191 err = mOMXNode->getParameter( 5192 OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 5193 if (err != OK) { 5194 return err; 5195 } 5196 5197 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM); 5198 notify->setInt32("channel-count", params.nChannels); 5199 notify->setInt32("sample-rate", params.nSamplingRate); 5200 break; 5201 } 5202 5203 default: 5204 ALOGE("Unsupported audio coding: %s(%d)\n", 5205 asString(audioDef->eEncoding), audioDef->eEncoding); 5206 return BAD_TYPE; 5207 } 5208 break; 5209 } 5210 5211 default: 5212 ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain); 5213 return BAD_TYPE; 5214 } 5215 5216 return getVendorParameters(portIndex, notify); 5217} 5218 5219void ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) { 5220 // aspects are normally communicated in ColorAspects 5221 int32_t range, standard, transfer; 5222 convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer); 5223 5224 // if some aspects are unspecified, use dataspace fields 5225 if (range != 0) { 5226 range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT; 5227 } 5228 if (standard != 0) { 5229 standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT; 5230 } 5231 if (transfer != 0) { 5232 transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT; 5233 } 5234 5235 mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event 5236 if (range != 0) { 5237 mOutputFormat->setInt32("color-range", range); 5238 } 5239 if (standard != 0) { 5240 mOutputFormat->setInt32("color-standard", standard); 5241 } 5242 if (transfer != 0) { 5243 mOutputFormat->setInt32("color-transfer", transfer); 5244 } 5245 5246 ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) " 5247 "(R:%d(%s), S:%d(%s), T:%d(%s))", 5248 dataSpace, 5249 aspects.mRange, asString(aspects.mRange), 5250 aspects.mPrimaries, asString(aspects.mPrimaries), 5251 aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs), 5252 aspects.mTransfer, asString(aspects.mTransfer), 5253 range, asString((ColorRange)range), 5254 standard, asString((ColorStandard)standard), 5255 transfer, asString((ColorTransfer)transfer)); 5256} 5257 5258void ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) { 5259 // store new output format, at the same time mark that this is no longer the first frame 5260 mOutputFormat = mBaseOutputFormat->dup(); 5261 5262 if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) { 5263 ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str()); 5264 return; 5265 } 5266 5267 if (expectedFormat != NULL) { 5268 sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat); 5269 sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat); 5270 if (changes->countEntries() != 0 || to->countEntries() != 0) { 5271 ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s", 5272 mComponentName.c_str(), 5273 changes->debugString(4).c_str(), to->debugString(4).c_str()); 5274 } 5275 } 5276 5277 if (!mIsVideo && !mIsEncoder) { 5278 AudioEncoding pcmEncoding = kAudioEncodingPcm16bit; 5279 (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding); 5280 AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit; 5281 (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding); 5282 5283 mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding); 5284 if (mConverter[kPortIndexOutput] != NULL) { 5285 mOutputFormat->setInt32("pcm-encoding", pcmEncoding); 5286 } 5287 } 5288 5289 if (mTunneled) { 5290 sendFormatChange(); 5291 } 5292} 5293 5294void ACodec::sendFormatChange() { 5295 AString mime; 5296 CHECK(mOutputFormat->findString("mime", &mime)); 5297 5298 if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) { 5299 int32_t channelCount, sampleRate; 5300 CHECK(mOutputFormat->findInt32("channel-count", &channelCount)); 5301 CHECK(mOutputFormat->findInt32("sample-rate", &sampleRate)); 5302 if (mSampleRate != 0 && sampleRate != 0) { 5303 // avoiding 32-bit overflows in intermediate values 5304 mEncoderDelay = (int32_t)((((int64_t)mEncoderDelay) * sampleRate) / mSampleRate); 5305 mEncoderPadding = (int32_t)((((int64_t)mEncoderPadding) * sampleRate) / mSampleRate); 5306 mSampleRate = sampleRate; 5307 } 5308 if (mSkipCutBuffer != NULL) { 5309 size_t prevbufsize = mSkipCutBuffer->size(); 5310 if (prevbufsize != 0) { 5311 ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize); 5312 } 5313 } 5314 mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount); 5315 } 5316 5317 // mLastOutputFormat is not used when tunneled; doing this just to stay consistent 5318 mLastOutputFormat = mOutputFormat; 5319} 5320 5321void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) { 5322 ALOGE("signalError(omxError %#x, internalError %d)", error, internalError); 5323 5324 if (internalError == UNKNOWN_ERROR) { // find better error code 5325 const status_t omxStatus = statusFromOMXError(error); 5326 if (omxStatus != 0) { 5327 internalError = omxStatus; 5328 } else { 5329 ALOGW("Invalid OMX error %#x", error); 5330 } 5331 } 5332 5333 mFatalError = true; 5334 mCallback->onError(internalError, ACTION_CODE_FATAL); 5335} 5336 5337status_t ACodec::requestIDRFrame() { 5338 if (!mIsEncoder) { 5339 return ERROR_UNSUPPORTED; 5340 } 5341 5342 OMX_CONFIG_INTRAREFRESHVOPTYPE params; 5343 InitOMXParams(¶ms); 5344 5345 params.nPortIndex = kPortIndexOutput; 5346 params.IntraRefreshVOP = OMX_TRUE; 5347 5348 return mOMXNode->setConfig( 5349 OMX_IndexConfigVideoIntraVOPRefresh, 5350 ¶ms, 5351 sizeof(params)); 5352} 5353 5354//////////////////////////////////////////////////////////////////////////////// 5355 5356ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState) 5357 : AState(parentState), 5358 mCodec(codec) { 5359} 5360 5361ACodec::BaseState::PortMode ACodec::BaseState::getPortMode( 5362 OMX_U32 /* portIndex */) { 5363 return KEEP_BUFFERS; 5364} 5365 5366void ACodec::BaseState::stateExited() { 5367 ++mCodec->mStateGeneration; 5368} 5369 5370bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { 5371 switch (msg->what()) { 5372 case kWhatInputBufferFilled: 5373 { 5374 onInputBufferFilled(msg); 5375 break; 5376 } 5377 5378 case kWhatOutputBufferDrained: 5379 { 5380 onOutputBufferDrained(msg); 5381 break; 5382 } 5383 5384 case ACodec::kWhatOMXMessageList: 5385 { 5386 return checkOMXMessage(msg) ? onOMXMessageList(msg) : true; 5387 } 5388 5389 case ACodec::kWhatOMXMessageItem: 5390 { 5391 // no need to check as we already did it for kWhatOMXMessageList 5392 return onOMXMessage(msg); 5393 } 5394 5395 case ACodec::kWhatOMXMessage: 5396 { 5397 return checkOMXMessage(msg) ? onOMXMessage(msg) : true; 5398 } 5399 5400 case ACodec::kWhatSetSurface: 5401 { 5402 sp<AReplyToken> replyID; 5403 CHECK(msg->senderAwaitsResponse(&replyID)); 5404 5405 sp<RefBase> obj; 5406 CHECK(msg->findObject("surface", &obj)); 5407 5408 status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get())); 5409 5410 sp<AMessage> response = new AMessage; 5411 response->setInt32("err", err); 5412 response->postReply(replyID); 5413 break; 5414 } 5415 5416 case ACodec::kWhatCreateInputSurface: 5417 case ACodec::kWhatSetInputSurface: 5418 case ACodec::kWhatSignalEndOfInputStream: 5419 { 5420 // This may result in an app illegal state exception. 5421 ALOGE("Message 0x%x was not handled", msg->what()); 5422 mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION); 5423 return true; 5424 } 5425 5426 case ACodec::kWhatOMXDied: 5427 { 5428 // This will result in kFlagSawMediaServerDie handling in MediaCodec. 5429 ALOGE("OMX/mediaserver died, signalling error!"); 5430 mCodec->mGraphicBufferSource.clear(); 5431 mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT); 5432 break; 5433 } 5434 5435 case ACodec::kWhatReleaseCodecInstance: 5436 { 5437 ALOGI("[%s] forcing the release of codec", 5438 mCodec->mComponentName.c_str()); 5439 status_t err = mCodec->mOMXNode->freeNode(); 5440 ALOGE_IF("[%s] failed to release codec instance: err=%d", 5441 mCodec->mComponentName.c_str(), err); 5442 mCodec->mCallback->onReleaseCompleted(); 5443 5444 mCodec->changeState(mCodec->mUninitializedState); 5445 break; 5446 } 5447 5448 case ACodec::kWhatForceStateTransition: 5449 { 5450 ALOGV("Already transitioned --- ignore"); 5451 break; 5452 } 5453 5454 default: 5455 return false; 5456 } 5457 5458 return true; 5459} 5460 5461bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) { 5462 // there is a possibility that this is an outstanding message for a 5463 // codec that we have already destroyed 5464 if (mCodec->mOMXNode == NULL) { 5465 ALOGI("ignoring message as already freed component: %s", 5466 msg->debugString().c_str()); 5467 return false; 5468 } 5469 5470 int32_t generation; 5471 CHECK(msg->findInt32("generation", (int32_t*)&generation)); 5472 if (generation != mCodec->mNodeGeneration) { 5473 ALOGW("Unexpected message for component: %s, gen %u, cur %u", 5474 msg->debugString().c_str(), generation, mCodec->mNodeGeneration); 5475 return false; 5476 } 5477 return true; 5478} 5479 5480bool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) { 5481 sp<RefBase> obj; 5482 CHECK(msg->findObject("messages", &obj)); 5483 sp<MessageList> msgList = static_cast<MessageList *>(obj.get()); 5484 5485 bool receivedRenderedEvents = false; 5486 for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin(); 5487 it != msgList->getList().cend(); ++it) { 5488 (*it)->setWhat(ACodec::kWhatOMXMessageItem); 5489 mCodec->handleMessage(*it); 5490 int32_t type; 5491 CHECK((*it)->findInt32("type", &type)); 5492 if (type == omx_message::FRAME_RENDERED) { 5493 receivedRenderedEvents = true; 5494 } 5495 } 5496 5497 if (receivedRenderedEvents) { 5498 // NOTE: all buffers are rendered in this case 5499 mCodec->notifyOfRenderedFrames(); 5500 } 5501 return true; 5502} 5503 5504bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { 5505 int32_t type; 5506 CHECK(msg->findInt32("type", &type)); 5507 5508 switch (type) { 5509 case omx_message::EVENT: 5510 { 5511 int32_t event, data1, data2; 5512 CHECK(msg->findInt32("event", &event)); 5513 CHECK(msg->findInt32("data1", &data1)); 5514 CHECK(msg->findInt32("data2", &data2)); 5515 5516 if (event == OMX_EventCmdComplete 5517 && data1 == OMX_CommandFlush 5518 && data2 == (int32_t)OMX_ALL) { 5519 // Use of this notification is not consistent across 5520 // implementations. We'll drop this notification and rely 5521 // on flush-complete notifications on the individual port 5522 // indices instead. 5523 5524 return true; 5525 } 5526 5527 return onOMXEvent( 5528 static_cast<OMX_EVENTTYPE>(event), 5529 static_cast<OMX_U32>(data1), 5530 static_cast<OMX_U32>(data2)); 5531 } 5532 5533 case omx_message::EMPTY_BUFFER_DONE: 5534 { 5535 IOMX::buffer_id bufferID; 5536 int32_t fenceFd; 5537 5538 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 5539 CHECK(msg->findInt32("fence_fd", &fenceFd)); 5540 5541 return onOMXEmptyBufferDone(bufferID, fenceFd); 5542 } 5543 5544 case omx_message::FILL_BUFFER_DONE: 5545 { 5546 IOMX::buffer_id bufferID; 5547 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 5548 5549 int32_t rangeOffset, rangeLength, flags, fenceFd; 5550 int64_t timeUs; 5551 5552 CHECK(msg->findInt32("range_offset", &rangeOffset)); 5553 CHECK(msg->findInt32("range_length", &rangeLength)); 5554 CHECK(msg->findInt32("flags", &flags)); 5555 CHECK(msg->findInt64("timestamp", &timeUs)); 5556 CHECK(msg->findInt32("fence_fd", &fenceFd)); 5557 5558 return onOMXFillBufferDone( 5559 bufferID, 5560 (size_t)rangeOffset, (size_t)rangeLength, 5561 (OMX_U32)flags, 5562 timeUs, 5563 fenceFd); 5564 } 5565 5566 case omx_message::FRAME_RENDERED: 5567 { 5568 int64_t mediaTimeUs, systemNano; 5569 5570 CHECK(msg->findInt64("media_time_us", &mediaTimeUs)); 5571 CHECK(msg->findInt64("system_nano", &systemNano)); 5572 5573 return onOMXFrameRendered( 5574 mediaTimeUs, systemNano); 5575 } 5576 5577 default: 5578 ALOGE("Unexpected message type: %d", type); 5579 return false; 5580 } 5581} 5582 5583bool ACodec::BaseState::onOMXFrameRendered( 5584 int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) { 5585 // ignore outside of Executing and PortSettingsChanged states 5586 return true; 5587} 5588 5589bool ACodec::BaseState::onOMXEvent( 5590 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5591 if (event == OMX_EventDataSpaceChanged) { 5592 ColorAspects aspects = ColorUtils::unpackToColorAspects(data2); 5593 5594 mCodec->onDataSpaceChanged((android_dataspace)data1, aspects); 5595 return true; 5596 } 5597 5598 if (event != OMX_EventError) { 5599 ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)", 5600 mCodec->mComponentName.c_str(), event, data1, data2); 5601 5602 return false; 5603 } 5604 5605 ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1); 5606 5607 // verify OMX component sends back an error we expect. 5608 OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1; 5609 if (!isOMXError(omxError)) { 5610 ALOGW("Invalid OMX error %#x", omxError); 5611 omxError = OMX_ErrorUndefined; 5612 } 5613 mCodec->signalError(omxError); 5614 5615 return true; 5616} 5617 5618bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) { 5619 ALOGV("[%s] onOMXEmptyBufferDone %u", 5620 mCodec->mComponentName.c_str(), bufferID); 5621 5622 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 5623 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5624 if (status != BufferInfo::OWNED_BY_COMPONENT) { 5625 ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5626 mCodec->dumpBuffers(kPortIndexInput); 5627 if (fenceFd >= 0) { 5628 ::close(fenceFd); 5629 } 5630 return false; 5631 } 5632 info->mStatus = BufferInfo::OWNED_BY_US; 5633 5634 // input buffers cannot take fences, so wait for any fence now 5635 (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone"); 5636 fenceFd = -1; 5637 5638 // still save fence for completeness 5639 info->setWriteFence(fenceFd, "onOMXEmptyBufferDone"); 5640 5641 // We're in "store-metadata-in-buffers" mode, the underlying 5642 // OMX component had access to data that's implicitly refcounted 5643 // by this "MediaBuffer" object. Now that the OMX component has 5644 // told us that it's done with the input buffer, we can decrement 5645 // the mediaBuffer's reference count. 5646 info->mData->setMediaBufferBase(NULL); 5647 5648 PortMode mode = getPortMode(kPortIndexInput); 5649 5650 switch (mode) { 5651 case KEEP_BUFFERS: 5652 break; 5653 5654 case RESUBMIT_BUFFERS: 5655 postFillThisBuffer(info); 5656 break; 5657 5658 case FREE_BUFFERS: 5659 default: 5660 ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers"); 5661 return false; 5662 } 5663 5664 return true; 5665} 5666 5667void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) { 5668 if (mCodec->mPortEOS[kPortIndexInput]) { 5669 return; 5670 } 5671 5672 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 5673 5674 info->mData->setFormat(mCodec->mInputFormat); 5675 mCodec->mBufferChannel->fillThisBuffer(info->mBufferID); 5676 info->mData.clear(); 5677 info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 5678} 5679 5680void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { 5681 IOMX::buffer_id bufferID; 5682 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 5683 sp<MediaCodecBuffer> buffer; 5684 int32_t err = OK; 5685 bool eos = false; 5686 PortMode mode = getPortMode(kPortIndexInput); 5687 int32_t discarded = 0; 5688 if (msg->findInt32("discarded", &discarded) && discarded) { 5689 // these are unfilled buffers returned by client 5690 // buffers are returned on MediaCodec.flush 5691 mode = KEEP_BUFFERS; 5692 } 5693 sp<RefBase> obj; 5694 CHECK(msg->findObject("buffer", &obj)); 5695 buffer = static_cast<MediaCodecBuffer *>(obj.get()); 5696 5697 int32_t tmp; 5698 if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) { 5699 eos = true; 5700 err = ERROR_END_OF_STREAM; 5701 } 5702 5703 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 5704 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5705 if (status != BufferInfo::OWNED_BY_UPSTREAM) { 5706 ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID); 5707 mCodec->dumpBuffers(kPortIndexInput); 5708 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5709 return; 5710 } 5711 5712 info->mStatus = BufferInfo::OWNED_BY_US; 5713 info->mData = buffer; 5714 5715 switch (mode) { 5716 case KEEP_BUFFERS: 5717 { 5718 if (eos) { 5719 if (!mCodec->mPortEOS[kPortIndexInput]) { 5720 mCodec->mPortEOS[kPortIndexInput] = true; 5721 mCodec->mInputEOSResult = err; 5722 } 5723 } 5724 break; 5725 } 5726 5727 case RESUBMIT_BUFFERS: 5728 { 5729 if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) { 5730 // Do not send empty input buffer w/o EOS to the component. 5731 if (buffer->size() == 0 && !eos) { 5732 postFillThisBuffer(info); 5733 break; 5734 } 5735 5736 int64_t timeUs; 5737 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 5738 5739 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 5740 5741 int32_t isCSD = 0; 5742 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) { 5743 if (mCodec->mIsLegacyVP9Decoder) { 5744 ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data", 5745 mCodec->mComponentName.c_str(), bufferID); 5746 postFillThisBuffer(info); 5747 break; 5748 } 5749 flags |= OMX_BUFFERFLAG_CODECCONFIG; 5750 } 5751 5752 if (eos) { 5753 flags |= OMX_BUFFERFLAG_EOS; 5754 } 5755 5756 size_t size = buffer->size(); 5757 size_t offset = buffer->offset(); 5758 if (buffer->base() != info->mCodecData->base()) { 5759 ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)", 5760 mCodec->mComponentName.c_str(), 5761 bufferID, 5762 buffer->base(), info->mCodecData->base()); 5763 5764 sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput]; 5765 if (converter == NULL || isCSD) { 5766 converter = getCopyConverter(); 5767 } 5768 status_t err = converter->convert(buffer, info->mCodecData); 5769 if (err != OK) { 5770 mCodec->signalError(OMX_ErrorUndefined, err); 5771 return; 5772 } 5773 size = info->mCodecData->size(); 5774 } else { 5775 info->mCodecData->setRange(offset, size); 5776 } 5777 5778 if (flags & OMX_BUFFERFLAG_CODECCONFIG) { 5779 ALOGV("[%s] calling emptyBuffer %u w/ codec specific data", 5780 mCodec->mComponentName.c_str(), bufferID); 5781 } else if (flags & OMX_BUFFERFLAG_EOS) { 5782 ALOGV("[%s] calling emptyBuffer %u w/ EOS", 5783 mCodec->mComponentName.c_str(), bufferID); 5784 } else { 5785#if TRACK_BUFFER_TIMING 5786 ALOGI("[%s] calling emptyBuffer %u w/ time %lld us", 5787 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 5788#else 5789 ALOGV("[%s] calling emptyBuffer %u w/ time %lld us", 5790 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 5791#endif 5792 } 5793 5794#if TRACK_BUFFER_TIMING 5795 ACodec::BufferStats stats; 5796 stats.mEmptyBufferTimeUs = ALooper::GetNowUs(); 5797 stats.mFillBufferDoneTimeUs = -1ll; 5798 mCodec->mBufferStats.add(timeUs, stats); 5799#endif 5800 5801 if (mCodec->storingMetadataInDecodedBuffers()) { 5802 // try to submit an output buffer for each input buffer 5803 PortMode outputMode = getPortMode(kPortIndexOutput); 5804 5805 ALOGV("MetadataBuffersToSubmit=%u portMode=%s", 5806 mCodec->mMetadataBuffersToSubmit, 5807 (outputMode == FREE_BUFFERS ? "FREE" : 5808 outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT")); 5809 if (outputMode == RESUBMIT_BUFFERS) { 5810 mCodec->submitOutputMetadataBuffer(); 5811 } 5812 } 5813 info->checkReadFence("onInputBufferFilled"); 5814 5815 status_t err2 = OK; 5816 switch (mCodec->mPortMode[kPortIndexInput]) { 5817 case IOMX::kPortModePresetByteBuffer: 5818 case IOMX::kPortModePresetANWBuffer: 5819 case IOMX::kPortModePresetSecureBuffer: 5820 { 5821 err2 = mCodec->mOMXNode->emptyBuffer( 5822 bufferID, info->mCodecData, flags, timeUs, info->mFenceFd); 5823 } 5824 break; 5825#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 5826 case IOMX::kPortModeDynamicNativeHandle: 5827 if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) { 5828 VideoNativeHandleMetadata *vnhmd = 5829 (VideoNativeHandleMetadata*)info->mCodecData->base(); 5830 sp<NativeHandle> handle = NativeHandle::create( 5831 vnhmd->pHandle, false /* ownsHandle */); 5832 err2 = mCodec->mOMXNode->emptyBuffer( 5833 bufferID, handle, flags, timeUs, info->mFenceFd); 5834 } 5835 break; 5836 case IOMX::kPortModeDynamicANWBuffer: 5837 if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) { 5838 VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base(); 5839 sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(vnmd->pBuffer); 5840 err2 = mCodec->mOMXNode->emptyBuffer( 5841 bufferID, graphicBuffer, flags, timeUs, info->mFenceFd); 5842 } 5843 break; 5844#endif 5845 default: 5846 ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode", 5847 asString(mCodec->mPortMode[kPortIndexInput]), 5848 info->mCodecData->size(), 5849 sizeof(buffer_handle_t) * 8); 5850 err2 = ERROR_UNSUPPORTED; 5851 break; 5852 } 5853 5854 info->mFenceFd = -1; 5855 if (err2 != OK) { 5856 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 5857 return; 5858 } 5859 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5860 // Hold the reference while component is using the buffer. 5861 info->mData = buffer; 5862 5863 if (!eos && err == OK) { 5864 getMoreInputDataIfPossible(); 5865 } else { 5866 ALOGV("[%s] Signalled EOS (%d) on the input port", 5867 mCodec->mComponentName.c_str(), err); 5868 5869 mCodec->mPortEOS[kPortIndexInput] = true; 5870 mCodec->mInputEOSResult = err; 5871 } 5872 } else if (!mCodec->mPortEOS[kPortIndexInput]) { 5873 if (err != OK && err != ERROR_END_OF_STREAM) { 5874 ALOGV("[%s] Signalling EOS on the input port due to error %d", 5875 mCodec->mComponentName.c_str(), err); 5876 } else { 5877 ALOGV("[%s] Signalling EOS on the input port", 5878 mCodec->mComponentName.c_str()); 5879 } 5880 5881 ALOGV("[%s] calling emptyBuffer %u signalling EOS", 5882 mCodec->mComponentName.c_str(), bufferID); 5883 5884 info->checkReadFence("onInputBufferFilled"); 5885 status_t err2 = mCodec->mOMXNode->emptyBuffer( 5886 bufferID, OMXBuffer::sPreset, OMX_BUFFERFLAG_EOS, 0, info->mFenceFd); 5887 info->mFenceFd = -1; 5888 if (err2 != OK) { 5889 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 5890 return; 5891 } 5892 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5893 5894 mCodec->mPortEOS[kPortIndexInput] = true; 5895 mCodec->mInputEOSResult = err; 5896 } 5897 break; 5898 } 5899 5900 case FREE_BUFFERS: 5901 break; 5902 5903 default: 5904 ALOGE("invalid port mode: %d", mode); 5905 break; 5906 } 5907} 5908 5909void ACodec::BaseState::getMoreInputDataIfPossible() { 5910 if (mCodec->mPortEOS[kPortIndexInput]) { 5911 return; 5912 } 5913 5914 BufferInfo *eligible = NULL; 5915 5916 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 5917 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 5918 5919#if 0 5920 if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 5921 // There's already a "read" pending. 5922 return; 5923 } 5924#endif 5925 5926 if (info->mStatus == BufferInfo::OWNED_BY_US) { 5927 eligible = info; 5928 } 5929 } 5930 5931 if (eligible == NULL) { 5932 return; 5933 } 5934 5935 postFillThisBuffer(eligible); 5936} 5937 5938bool ACodec::BaseState::onOMXFillBufferDone( 5939 IOMX::buffer_id bufferID, 5940 size_t rangeOffset, size_t rangeLength, 5941 OMX_U32 flags, 5942 int64_t timeUs, 5943 int fenceFd) { 5944 ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x", 5945 mCodec->mComponentName.c_str(), bufferID, timeUs, flags); 5946 5947 ssize_t index; 5948 status_t err= OK; 5949 5950#if TRACK_BUFFER_TIMING 5951 index = mCodec->mBufferStats.indexOfKey(timeUs); 5952 if (index >= 0) { 5953 ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index); 5954 stats->mFillBufferDoneTimeUs = ALooper::GetNowUs(); 5955 5956 ALOGI("frame PTS %lld: %lld", 5957 timeUs, 5958 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs); 5959 5960 mCodec->mBufferStats.removeItemsAt(index); 5961 stats = NULL; 5962 } 5963#endif 5964 5965 BufferInfo *info = 5966 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 5967 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5968 if (status != BufferInfo::OWNED_BY_COMPONENT) { 5969 ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5970 mCodec->dumpBuffers(kPortIndexOutput); 5971 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5972 if (fenceFd >= 0) { 5973 ::close(fenceFd); 5974 } 5975 return true; 5976 } 5977 5978 info->mDequeuedAt = ++mCodec->mDequeueCounter; 5979 info->mStatus = BufferInfo::OWNED_BY_US; 5980 5981 if (info->mRenderInfo != NULL) { 5982 // The fence for an emptied buffer must have signaled, but there still could be queued 5983 // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these, 5984 // as we will soon requeue this buffer to the surface. While in theory we could still keep 5985 // track of buffers that are requeued to the surface, it is better to add support to the 5986 // buffer-queue to notify us of released buffers and their fences (in the future). 5987 mCodec->notifyOfRenderedFrames(true /* dropIncomplete */); 5988 } 5989 5990 // byte buffers cannot take fences, so wait for any fence now 5991 if (mCodec->mNativeWindow == NULL) { 5992 (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone"); 5993 fenceFd = -1; 5994 } 5995 info->setReadFence(fenceFd, "onOMXFillBufferDone"); 5996 5997 PortMode mode = getPortMode(kPortIndexOutput); 5998 5999 switch (mode) { 6000 case KEEP_BUFFERS: 6001 break; 6002 6003 case RESUBMIT_BUFFERS: 6004 { 6005 if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS) 6006 || mCodec->mPortEOS[kPortIndexOutput])) { 6007 ALOGV("[%s] calling fillBuffer %u", 6008 mCodec->mComponentName.c_str(), info->mBufferID); 6009 6010 err = mCodec->fillBuffer(info); 6011 if (err != OK) { 6012 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6013 return true; 6014 } 6015 break; 6016 } 6017 6018 sp<MediaCodecBuffer> buffer = info->mData; 6019 6020 if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) { 6021 // pretend that output format has changed on the first frame (we used to do this) 6022 if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) { 6023 mCodec->onOutputFormatChanged(mCodec->mOutputFormat); 6024 } 6025 mCodec->sendFormatChange(); 6026 } 6027 buffer->setFormat(mCodec->mOutputFormat); 6028 6029 if (mCodec->usingSecureBufferOnEncoderOutput()) { 6030 native_handle_t *handle = NULL; 6031 sp<SecureBuffer> secureBuffer = static_cast<SecureBuffer *>(buffer.get()); 6032 if (secureBuffer != NULL) { 6033#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 6034 // handle is only valid on 32-bit/mediaserver process 6035 handle = NULL; 6036#else 6037 handle = (native_handle_t *)secureBuffer->getDestinationPointer(); 6038#endif 6039 } 6040 buffer->meta()->setPointer("handle", handle); 6041 buffer->meta()->setInt32("rangeOffset", rangeOffset); 6042 buffer->meta()->setInt32("rangeLength", rangeLength); 6043 } else if (buffer->base() == info->mCodecData->base()) { 6044 buffer->setRange(rangeOffset, rangeLength); 6045 } else { 6046 info->mCodecData->setRange(rangeOffset, rangeLength); 6047 // in this case we know that mConverter is not null 6048 status_t err = mCodec->mConverter[kPortIndexOutput]->convert( 6049 info->mCodecData, buffer); 6050 if (err != OK) { 6051 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6052 return true; 6053 } 6054 } 6055#if 0 6056 if (mCodec->mNativeWindow == NULL) { 6057 if (IsIDR(info->mData->data(), info->mData->size())) { 6058 ALOGI("IDR frame"); 6059 } 6060 } 6061#endif 6062 6063 if (mCodec->mSkipCutBuffer != NULL) { 6064 mCodec->mSkipCutBuffer->submit(buffer); 6065 } 6066 buffer->meta()->setInt64("timeUs", timeUs); 6067 6068 info->mData.clear(); 6069 6070 mCodec->mBufferChannel->drainThisBuffer(info->mBufferID, flags); 6071 6072 info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 6073 6074 if (flags & OMX_BUFFERFLAG_EOS) { 6075 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str()); 6076 6077 mCodec->mCallback->onEos(mCodec->mInputEOSResult); 6078 mCodec->mPortEOS[kPortIndexOutput] = true; 6079 } 6080 break; 6081 } 6082 6083 case FREE_BUFFERS: 6084 err = mCodec->freeBuffer(kPortIndexOutput, index); 6085 if (err != OK) { 6086 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6087 return true; 6088 } 6089 break; 6090 6091 default: 6092 ALOGE("Invalid port mode: %d", mode); 6093 return false; 6094 } 6095 6096 return true; 6097} 6098 6099void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 6100 IOMX::buffer_id bufferID; 6101 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 6102 sp<RefBase> obj; 6103 CHECK(msg->findObject("buffer", &obj)); 6104 sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get()); 6105 int32_t discarded = 0; 6106 msg->findInt32("discarded", &discarded); 6107 6108 ssize_t index; 6109 BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 6110 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 6111 if (status != BufferInfo::OWNED_BY_DOWNSTREAM) { 6112 ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 6113 mCodec->dumpBuffers(kPortIndexOutput); 6114 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6115 return; 6116 } 6117 info->mData = buffer; 6118 int32_t render; 6119 if (mCodec->mNativeWindow != NULL 6120 && msg->findInt32("render", &render) && render != 0 6121 && !discarded && buffer->size() != 0) { 6122 ATRACE_NAME("render"); 6123 // The client wants this buffer to be rendered. 6124 6125 android_native_rect_t crop; 6126 if (buffer->format()->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) { 6127 // NOTE: native window uses extended right-bottom coordinate 6128 ++crop.right; 6129 ++crop.bottom; 6130 if (memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) { 6131 mCodec->mLastNativeWindowCrop = crop; 6132 status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop); 6133 ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err); 6134 } 6135 } 6136 6137 int32_t dataSpace; 6138 if (buffer->format()->findInt32("android._dataspace", &dataSpace) 6139 && dataSpace != mCodec->mLastNativeWindowDataSpace) { 6140 status_t err = native_window_set_buffers_data_space( 6141 mCodec->mNativeWindow.get(), (android_dataspace)dataSpace); 6142 mCodec->mLastNativeWindowDataSpace = dataSpace; 6143 ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err); 6144 } 6145 6146 // save buffers sent to the surface so we can get render time when they return 6147 int64_t mediaTimeUs = -1; 6148 buffer->meta()->findInt64("timeUs", &mediaTimeUs); 6149 if (mediaTimeUs >= 0) { 6150 mCodec->mRenderTracker.onFrameQueued( 6151 mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd))); 6152 } 6153 6154 int64_t timestampNs = 0; 6155 if (!msg->findInt64("timestampNs", ×tampNs)) { 6156 // use media timestamp if client did not request a specific render timestamp 6157 if (buffer->meta()->findInt64("timeUs", ×tampNs)) { 6158 ALOGV("using buffer PTS of %lld", (long long)timestampNs); 6159 timestampNs *= 1000; 6160 } 6161 } 6162 6163 status_t err; 6164 err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs); 6165 ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err); 6166 6167 info->checkReadFence("onOutputBufferDrained before queueBuffer"); 6168 err = mCodec->mNativeWindow->queueBuffer( 6169 mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd); 6170 info->mFenceFd = -1; 6171 if (err == OK) { 6172 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 6173 } else { 6174 ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err); 6175 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6176 info->mStatus = BufferInfo::OWNED_BY_US; 6177 // keeping read fence as write fence to avoid clobbering 6178 info->mIsReadFence = false; 6179 } 6180 } else { 6181 if (mCodec->mNativeWindow != NULL && (discarded || buffer->size() != 0)) { 6182 // move read fence into write fence to avoid clobbering 6183 info->mIsReadFence = false; 6184 ATRACE_NAME("frame-drop"); 6185 } 6186 info->mStatus = BufferInfo::OWNED_BY_US; 6187 } 6188 6189 PortMode mode = getPortMode(kPortIndexOutput); 6190 6191 switch (mode) { 6192 case KEEP_BUFFERS: 6193 { 6194 // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 6195 6196 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6197 // We cannot resubmit the buffer we just rendered, dequeue 6198 // the spare instead. 6199 6200 info = mCodec->dequeueBufferFromNativeWindow(); 6201 } 6202 break; 6203 } 6204 6205 case RESUBMIT_BUFFERS: 6206 { 6207 if (!mCodec->mPortEOS[kPortIndexOutput]) { 6208 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6209 // We cannot resubmit the buffer we just rendered, dequeue 6210 // the spare instead. 6211 6212 info = mCodec->dequeueBufferFromNativeWindow(); 6213 } 6214 6215 if (info != NULL) { 6216 ALOGV("[%s] calling fillBuffer %u", 6217 mCodec->mComponentName.c_str(), info->mBufferID); 6218 info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS"); 6219 status_t err = mCodec->fillBuffer(info); 6220 if (err != OK) { 6221 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6222 } 6223 } 6224 } 6225 break; 6226 } 6227 6228 case FREE_BUFFERS: 6229 { 6230 status_t err = mCodec->freeBuffer(kPortIndexOutput, index); 6231 if (err != OK) { 6232 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6233 } 6234 break; 6235 } 6236 6237 default: 6238 ALOGE("Invalid port mode: %d", mode); 6239 return; 6240 } 6241} 6242 6243//////////////////////////////////////////////////////////////////////////////// 6244 6245ACodec::UninitializedState::UninitializedState(ACodec *codec) 6246 : BaseState(codec) { 6247} 6248 6249void ACodec::UninitializedState::stateEntered() { 6250 ALOGV("Now uninitialized"); 6251 6252 if (mDeathNotifier != NULL) { 6253 if (mCodec->mOMXNode != NULL) { 6254 if (mCodec->getTrebleFlag()) { 6255 auto tOmxNode = mCodec->mOMXNode->getHalInterface(); 6256 tOmxNode->unlinkToDeath(mDeathNotifier); 6257 } else { 6258 sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode); 6259 binder->unlinkToDeath(mDeathNotifier); 6260 } 6261 } 6262 mDeathNotifier.clear(); 6263 } 6264 6265 mCodec->mUsingNativeWindow = false; 6266 mCodec->mNativeWindow.clear(); 6267 mCodec->mNativeWindowUsageBits = 0; 6268 mCodec->mOMX.clear(); 6269 mCodec->mOMXNode.clear(); 6270 mCodec->mFlags = 0; 6271 mCodec->mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer; 6272 mCodec->mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer; 6273 mCodec->mConverter[0].clear(); 6274 mCodec->mConverter[1].clear(); 6275 mCodec->mComponentName.clear(); 6276} 6277 6278bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 6279 bool handled = false; 6280 6281 switch (msg->what()) { 6282 case ACodec::kWhatSetup: 6283 { 6284 onSetup(msg); 6285 6286 handled = true; 6287 break; 6288 } 6289 6290 case ACodec::kWhatAllocateComponent: 6291 { 6292 onAllocateComponent(msg); 6293 handled = true; 6294 break; 6295 } 6296 6297 case ACodec::kWhatShutdown: 6298 { 6299 int32_t keepComponentAllocated; 6300 CHECK(msg->findInt32( 6301 "keepComponentAllocated", &keepComponentAllocated)); 6302 ALOGW_IF(keepComponentAllocated, 6303 "cannot keep component allocated on shutdown in Uninitialized state"); 6304 if (keepComponentAllocated) { 6305 mCodec->mCallback->onStopCompleted(); 6306 } else { 6307 mCodec->mCallback->onReleaseCompleted(); 6308 } 6309 handled = true; 6310 break; 6311 } 6312 6313 case ACodec::kWhatFlush: 6314 { 6315 mCodec->mCallback->onFlushCompleted(); 6316 handled = true; 6317 break; 6318 } 6319 6320 case ACodec::kWhatReleaseCodecInstance: 6321 { 6322 // nothing to do, as we have already signaled shutdown 6323 handled = true; 6324 break; 6325 } 6326 6327 default: 6328 return BaseState::onMessageReceived(msg); 6329 } 6330 6331 return handled; 6332} 6333 6334void ACodec::UninitializedState::onSetup( 6335 const sp<AMessage> &msg) { 6336 if (onAllocateComponent(msg) 6337 && mCodec->mLoadedState->onConfigureComponent(msg)) { 6338 mCodec->mLoadedState->onStart(); 6339 } 6340} 6341 6342bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { 6343 ALOGV("onAllocateComponent"); 6344 6345 CHECK(mCodec->mOMXNode == NULL); 6346 6347 sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec); 6348 6349 Vector<AString> matchingCodecs; 6350 Vector<AString> owners; 6351 6352 AString mime; 6353 6354 AString componentName; 6355 int32_t encoder = false; 6356 if (msg->findString("componentName", &componentName)) { 6357 sp<IMediaCodecList> list = MediaCodecList::getInstance(); 6358 if (list == nullptr) { 6359 ALOGE("Unable to obtain MediaCodecList while " 6360 "attempting to create codec \"%s\"", 6361 componentName.c_str()); 6362 mCodec->signalError(OMX_ErrorUndefined, NO_INIT); 6363 return false; 6364 } 6365 ssize_t index = list->findCodecByName(componentName.c_str()); 6366 if (index < 0) { 6367 ALOGE("Unable to find codec \"%s\"", 6368 componentName.c_str()); 6369 mCodec->signalError(OMX_ErrorInvalidComponent, NAME_NOT_FOUND); 6370 return false; 6371 } 6372 sp<MediaCodecInfo> info = list->getCodecInfo(index); 6373 if (info == nullptr) { 6374 ALOGE("Unexpected error (index out-of-bound) while " 6375 "retrieving information for codec \"%s\"", 6376 componentName.c_str()); 6377 mCodec->signalError(OMX_ErrorUndefined, UNKNOWN_ERROR); 6378 return false; 6379 } 6380 matchingCodecs.add(info->getCodecName()); 6381 owners.add(info->getOwnerName() == nullptr ? 6382 "default" : info->getOwnerName()); 6383 } else { 6384 CHECK(msg->findString("mime", &mime)); 6385 6386 if (!msg->findInt32("encoder", &encoder)) { 6387 encoder = false; 6388 } 6389 6390 MediaCodecList::findMatchingCodecs( 6391 mime.c_str(), 6392 encoder, // createEncoder 6393 0, // flags 6394 &matchingCodecs, 6395 &owners); 6396 } 6397 6398 sp<CodecObserver> observer = new CodecObserver; 6399 sp<IOMX> omx; 6400 sp<IOMXNode> omxNode; 6401 6402 status_t err = NAME_NOT_FOUND; 6403 for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); 6404 ++matchIndex) { 6405 componentName = matchingCodecs[matchIndex]; 6406 6407 OMXClient client; 6408 bool trebleFlag; 6409 if (client.connect(owners[matchIndex].c_str(), &trebleFlag) != OK) { 6410 mCodec->signalError(OMX_ErrorUndefined, NO_INIT); 6411 return false; 6412 } 6413 omx = client.interface(); 6414 6415 pid_t tid = gettid(); 6416 int prevPriority = androidGetThreadPriority(tid); 6417 androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); 6418 err = omx->allocateNode(componentName.c_str(), observer, &omxNode); 6419 androidSetThreadPriority(tid, prevPriority); 6420 6421 if (err == OK) { 6422 mCodec->setTrebleFlag(trebleFlag); 6423 break; 6424 } else { 6425 ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str()); 6426 } 6427 6428 omxNode = NULL; 6429 } 6430 6431 if (omxNode == NULL) { 6432 if (!mime.empty()) { 6433 ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.", 6434 encoder ? "en" : "de", mime.c_str(), err); 6435 } else { 6436 ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err); 6437 } 6438 6439 mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err)); 6440 return false; 6441 } 6442 6443 mDeathNotifier = new DeathNotifier(notify); 6444 if (mCodec->getTrebleFlag()) { 6445 auto tOmxNode = omxNode->getHalInterface(); 6446 if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) { 6447 mDeathNotifier.clear(); 6448 } 6449 } else { 6450 if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) { 6451 // This was a local binder, if it dies so do we, we won't care 6452 // about any notifications in the afterlife. 6453 mDeathNotifier.clear(); 6454 } 6455 } 6456 6457 notify = new AMessage(kWhatOMXMessageList, mCodec); 6458 notify->setInt32("generation", ++mCodec->mNodeGeneration); 6459 observer->setNotificationMessage(notify); 6460 6461 mCodec->mComponentName = componentName; 6462 mCodec->mRenderTracker.setComponentName(componentName); 6463 mCodec->mFlags = 0; 6464 6465 if (componentName.endsWith(".secure")) { 6466 mCodec->mFlags |= kFlagIsSecure; 6467 mCodec->mFlags |= kFlagIsGrallocUsageProtected; 6468 mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 6469 } 6470 6471 mCodec->mOMX = omx; 6472 mCodec->mOMXNode = omxNode; 6473 mCodec->mCallback->onComponentAllocated(mCodec->mComponentName.c_str()); 6474 mCodec->changeState(mCodec->mLoadedState); 6475 6476 return true; 6477} 6478 6479//////////////////////////////////////////////////////////////////////////////// 6480 6481ACodec::LoadedState::LoadedState(ACodec *codec) 6482 : BaseState(codec) { 6483} 6484 6485void ACodec::LoadedState::stateEntered() { 6486 ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 6487 6488 mCodec->mPortEOS[kPortIndexInput] = 6489 mCodec->mPortEOS[kPortIndexOutput] = false; 6490 6491 mCodec->mInputEOSResult = OK; 6492 6493 mCodec->mDequeueCounter = 0; 6494 mCodec->mMetadataBuffersToSubmit = 0; 6495 mCodec->mRepeatFrameDelayUs = -1ll; 6496 mCodec->mInputFormat.clear(); 6497 mCodec->mOutputFormat.clear(); 6498 mCodec->mBaseOutputFormat.clear(); 6499 mCodec->mGraphicBufferSource.clear(); 6500 6501 if (mCodec->mShutdownInProgress) { 6502 bool keepComponentAllocated = mCodec->mKeepComponentAllocated; 6503 6504 mCodec->mShutdownInProgress = false; 6505 mCodec->mKeepComponentAllocated = false; 6506 6507 onShutdown(keepComponentAllocated); 6508 } 6509 mCodec->mExplicitShutdown = false; 6510 6511 mCodec->processDeferredMessages(); 6512} 6513 6514void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) { 6515 if (!keepComponentAllocated) { 6516 (void)mCodec->mOMXNode->freeNode(); 6517 6518 mCodec->changeState(mCodec->mUninitializedState); 6519 } 6520 6521 if (mCodec->mExplicitShutdown) { 6522 if (keepComponentAllocated) { 6523 mCodec->mCallback->onStopCompleted(); 6524 } else { 6525 mCodec->mCallback->onReleaseCompleted(); 6526 } 6527 mCodec->mExplicitShutdown = false; 6528 } 6529} 6530 6531bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) { 6532 bool handled = false; 6533 6534 switch (msg->what()) { 6535 case ACodec::kWhatConfigureComponent: 6536 { 6537 onConfigureComponent(msg); 6538 handled = true; 6539 break; 6540 } 6541 6542 case ACodec::kWhatCreateInputSurface: 6543 { 6544 onCreateInputSurface(msg); 6545 handled = true; 6546 break; 6547 } 6548 6549 case ACodec::kWhatSetInputSurface: 6550 { 6551 onSetInputSurface(msg); 6552 handled = true; 6553 break; 6554 } 6555 6556 case ACodec::kWhatStart: 6557 { 6558 onStart(); 6559 handled = true; 6560 break; 6561 } 6562 6563 case ACodec::kWhatShutdown: 6564 { 6565 int32_t keepComponentAllocated; 6566 CHECK(msg->findInt32( 6567 "keepComponentAllocated", &keepComponentAllocated)); 6568 6569 mCodec->mExplicitShutdown = true; 6570 onShutdown(keepComponentAllocated); 6571 6572 handled = true; 6573 break; 6574 } 6575 6576 case ACodec::kWhatFlush: 6577 { 6578 mCodec->mCallback->onFlushCompleted(); 6579 handled = true; 6580 break; 6581 } 6582 6583 default: 6584 return BaseState::onMessageReceived(msg); 6585 } 6586 6587 return handled; 6588} 6589 6590bool ACodec::LoadedState::onConfigureComponent( 6591 const sp<AMessage> &msg) { 6592 ALOGV("onConfigureComponent"); 6593 6594 CHECK(mCodec->mOMXNode != NULL); 6595 6596 status_t err = OK; 6597 AString mime; 6598 if (!msg->findString("mime", &mime)) { 6599 err = BAD_VALUE; 6600 } else { 6601 err = mCodec->configureCodec(mime.c_str(), msg); 6602 } 6603 if (err != OK) { 6604 ALOGE("[%s] configureCodec returning error %d", 6605 mCodec->mComponentName.c_str(), err); 6606 6607 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6608 return false; 6609 } 6610 6611 mCodec->mCallback->onComponentConfigured(mCodec->mInputFormat, mCodec->mOutputFormat); 6612 6613 return true; 6614} 6615 6616status_t ACodec::LoadedState::setupInputSurface() { 6617 if (mCodec->mGraphicBufferSource == NULL) { 6618 return BAD_VALUE; 6619 } 6620 6621 android_dataspace dataSpace; 6622 status_t err = 6623 mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace); 6624 if (err != OK) { 6625 ALOGE("Failed to get default data space"); 6626 return err; 6627 } 6628 6629 err = statusFromBinderStatus( 6630 mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace)); 6631 if (err != OK) { 6632 ALOGE("[%s] Unable to configure for node (err %d)", 6633 mCodec->mComponentName.c_str(), err); 6634 return err; 6635 } 6636 6637 if (mCodec->mRepeatFrameDelayUs > 0ll) { 6638 err = statusFromBinderStatus( 6639 mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs( 6640 mCodec->mRepeatFrameDelayUs)); 6641 6642 if (err != OK) { 6643 ALOGE("[%s] Unable to configure option to repeat previous " 6644 "frames (err %d)", 6645 mCodec->mComponentName.c_str(), err); 6646 return err; 6647 } 6648 } 6649 6650 if (mCodec->mMaxPtsGapUs > 0ll) { 6651 OMX_PARAM_U32TYPE maxPtsGapParams; 6652 InitOMXParams(&maxPtsGapParams); 6653 maxPtsGapParams.nPortIndex = kPortIndexInput; 6654 maxPtsGapParams.nU32 = (uint32_t) mCodec->mMaxPtsGapUs; 6655 6656 err = mCodec->mOMXNode->setParameter( 6657 (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl, 6658 &maxPtsGapParams, sizeof(maxPtsGapParams)); 6659 6660 if (err != OK) { 6661 ALOGE("[%s] Unable to configure max timestamp gap (err %d)", 6662 mCodec->mComponentName.c_str(), err); 6663 return err; 6664 } 6665 } 6666 6667 if (mCodec->mMaxFps > 0) { 6668 err = statusFromBinderStatus( 6669 mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps)); 6670 6671 if (err != OK) { 6672 ALOGE("[%s] Unable to configure max fps (err %d)", 6673 mCodec->mComponentName.c_str(), err); 6674 return err; 6675 } 6676 } 6677 6678 if (mCodec->mCaptureFps > 0. && mCodec->mFps > 0.) { 6679 err = statusFromBinderStatus( 6680 mCodec->mGraphicBufferSource->setTimeLapseConfig( 6681 mCodec->mFps, mCodec->mCaptureFps)); 6682 6683 if (err != OK) { 6684 ALOGE("[%s] Unable to configure time lapse (err %d)", 6685 mCodec->mComponentName.c_str(), err); 6686 return err; 6687 } 6688 } 6689 6690 if (mCodec->mCreateInputBuffersSuspended) { 6691 err = statusFromBinderStatus( 6692 mCodec->mGraphicBufferSource->setSuspend(true, -1)); 6693 6694 if (err != OK) { 6695 ALOGE("[%s] Unable to configure option to suspend (err %d)", 6696 mCodec->mComponentName.c_str(), err); 6697 return err; 6698 } 6699 } 6700 6701 uint32_t usageBits; 6702 if (mCodec->mOMXNode->getParameter( 6703 (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, 6704 &usageBits, sizeof(usageBits)) == OK) { 6705 mCodec->mInputFormat->setInt32( 6706 "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN)); 6707 } 6708 6709 sp<ABuffer> colorAspectsBuffer; 6710 if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) { 6711 if (colorAspectsBuffer->size() != sizeof(ColorAspects)) { 6712 return INVALID_OPERATION; 6713 } 6714 6715 err = statusFromBinderStatus( 6716 mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32( 6717 *(ColorAspects *)colorAspectsBuffer->base()))); 6718 6719 if (err != OK) { 6720 ALOGE("[%s] Unable to configure color aspects (err %d)", 6721 mCodec->mComponentName.c_str(), err); 6722 return err; 6723 } 6724 } 6725 return OK; 6726} 6727 6728void ACodec::LoadedState::onCreateInputSurface( 6729 const sp<AMessage> & /* msg */) { 6730 ALOGV("onCreateInputSurface"); 6731 6732 sp<IGraphicBufferProducer> bufferProducer; 6733 status_t err = mCodec->mOMX->createInputSurface( 6734 &bufferProducer, &mCodec->mGraphicBufferSource); 6735 6736 if (err == OK) { 6737 err = setupInputSurface(); 6738 } 6739 6740 if (err == OK) { 6741 mCodec->mCallback->onInputSurfaceCreated( 6742 mCodec->mInputFormat, 6743 mCodec->mOutputFormat, 6744 new BufferProducerWrapper(bufferProducer)); 6745 } else { 6746 // Can't use mCodec->signalError() here -- MediaCodec won't forward 6747 // the error through because it's in the "configured" state. We 6748 // send a kWhatInputSurfaceCreated with an error value instead. 6749 ALOGE("[%s] onCreateInputSurface returning error %d", 6750 mCodec->mComponentName.c_str(), err); 6751 mCodec->mCallback->onInputSurfaceCreationFailed(err); 6752 } 6753} 6754 6755void ACodec::LoadedState::onSetInputSurface(const sp<AMessage> &msg) { 6756 ALOGV("onSetInputSurface"); 6757 6758 sp<RefBase> obj; 6759 CHECK(msg->findObject("input-surface", &obj)); 6760 sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get()); 6761 mCodec->mGraphicBufferSource = surface->getBufferSource(); 6762 6763 status_t err = setupInputSurface(); 6764 6765 if (err == OK) { 6766 mCodec->mCallback->onInputSurfaceAccepted( 6767 mCodec->mInputFormat, mCodec->mOutputFormat); 6768 } else { 6769 // Can't use mCodec->signalError() here -- MediaCodec won't forward 6770 // the error through because it's in the "configured" state. We 6771 // send a kWhatInputSurfaceAccepted with an error value instead. 6772 ALOGE("[%s] onSetInputSurface returning error %d", 6773 mCodec->mComponentName.c_str(), err); 6774 mCodec->mCallback->onInputSurfaceDeclined(err); 6775 } 6776} 6777 6778void ACodec::LoadedState::onStart() { 6779 ALOGV("onStart"); 6780 6781 status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle); 6782 if (err != OK) { 6783 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6784 } else { 6785 mCodec->changeState(mCodec->mLoadedToIdleState); 6786 } 6787} 6788 6789//////////////////////////////////////////////////////////////////////////////// 6790 6791ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 6792 : BaseState(codec) { 6793} 6794 6795void ACodec::LoadedToIdleState::stateEntered() { 6796 ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 6797 6798 status_t err; 6799 if ((err = allocateBuffers()) != OK) { 6800 ALOGE("Failed to allocate buffers after transitioning to IDLE state " 6801 "(error 0x%08x)", 6802 err); 6803 6804 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6805 6806 mCodec->mOMXNode->sendCommand( 6807 OMX_CommandStateSet, OMX_StateLoaded); 6808 if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) { 6809 mCodec->freeBuffersOnPort(kPortIndexInput); 6810 } 6811 if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) { 6812 mCodec->freeBuffersOnPort(kPortIndexOutput); 6813 } 6814 6815 mCodec->changeState(mCodec->mLoadedState); 6816 } 6817} 6818 6819status_t ACodec::LoadedToIdleState::allocateBuffers() { 6820 status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 6821 if (err != OK) { 6822 return err; 6823 } 6824 6825 err = mCodec->allocateBuffersOnPort(kPortIndexOutput); 6826 if (err != OK) { 6827 return err; 6828 } 6829 6830 mCodec->mCallback->onStartCompleted(); 6831 6832 return OK; 6833} 6834 6835bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 6836 switch (msg->what()) { 6837 case kWhatSetParameters: 6838 case kWhatShutdown: 6839 { 6840 mCodec->deferMessage(msg); 6841 return true; 6842 } 6843 6844 case kWhatSignalEndOfInputStream: 6845 { 6846 mCodec->onSignalEndOfInputStream(); 6847 return true; 6848 } 6849 6850 case kWhatResume: 6851 { 6852 // We'll be active soon enough. 6853 return true; 6854 } 6855 6856 case kWhatFlush: 6857 { 6858 // We haven't even started yet, so we're flushed alright... 6859 mCodec->mCallback->onFlushCompleted(); 6860 return true; 6861 } 6862 6863 default: 6864 return BaseState::onMessageReceived(msg); 6865 } 6866} 6867 6868bool ACodec::LoadedToIdleState::onOMXEvent( 6869 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6870 switch (event) { 6871 case OMX_EventCmdComplete: 6872 { 6873 status_t err = OK; 6874 if (data1 != (OMX_U32)OMX_CommandStateSet 6875 || data2 != (OMX_U32)OMX_StateIdle) { 6876 ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)", 6877 asString((OMX_COMMANDTYPE)data1), data1, 6878 asString((OMX_STATETYPE)data2), data2); 6879 err = FAILED_TRANSACTION; 6880 } 6881 6882 if (err == OK) { 6883 err = mCodec->mOMXNode->sendCommand( 6884 OMX_CommandStateSet, OMX_StateExecuting); 6885 } 6886 6887 if (err != OK) { 6888 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6889 } else { 6890 mCodec->changeState(mCodec->mIdleToExecutingState); 6891 } 6892 6893 return true; 6894 } 6895 6896 default: 6897 return BaseState::onOMXEvent(event, data1, data2); 6898 } 6899} 6900 6901//////////////////////////////////////////////////////////////////////////////// 6902 6903ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 6904 : BaseState(codec) { 6905} 6906 6907void ACodec::IdleToExecutingState::stateEntered() { 6908 ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 6909} 6910 6911bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 6912 switch (msg->what()) { 6913 case kWhatSetParameters: 6914 case kWhatShutdown: 6915 { 6916 mCodec->deferMessage(msg); 6917 return true; 6918 } 6919 6920 case kWhatResume: 6921 { 6922 // We'll be active soon enough. 6923 return true; 6924 } 6925 6926 case kWhatFlush: 6927 { 6928 // We haven't even started yet, so we're flushed alright... 6929 mCodec->mCallback->onFlushCompleted(); 6930 return true; 6931 } 6932 6933 case kWhatSignalEndOfInputStream: 6934 { 6935 mCodec->onSignalEndOfInputStream(); 6936 return true; 6937 } 6938 6939 default: 6940 return BaseState::onMessageReceived(msg); 6941 } 6942} 6943 6944bool ACodec::IdleToExecutingState::onOMXEvent( 6945 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6946 switch (event) { 6947 case OMX_EventCmdComplete: 6948 { 6949 if (data1 != (OMX_U32)OMX_CommandStateSet 6950 || data2 != (OMX_U32)OMX_StateExecuting) { 6951 ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)", 6952 asString((OMX_COMMANDTYPE)data1), data1, 6953 asString((OMX_STATETYPE)data2), data2); 6954 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6955 return true; 6956 } 6957 6958 mCodec->mExecutingState->resume(); 6959 mCodec->changeState(mCodec->mExecutingState); 6960 6961 return true; 6962 } 6963 6964 default: 6965 return BaseState::onOMXEvent(event, data1, data2); 6966 } 6967} 6968 6969//////////////////////////////////////////////////////////////////////////////// 6970 6971ACodec::ExecutingState::ExecutingState(ACodec *codec) 6972 : BaseState(codec), 6973 mActive(false) { 6974} 6975 6976ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 6977 OMX_U32 /* portIndex */) { 6978 return RESUBMIT_BUFFERS; 6979} 6980 6981void ACodec::ExecutingState::submitOutputMetaBuffers() { 6982 // submit as many buffers as there are input buffers with the codec 6983 // in case we are in port reconfiguring 6984 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 6985 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 6986 6987 if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) { 6988 if (mCodec->submitOutputMetadataBuffer() != OK) 6989 break; 6990 } 6991 } 6992 6993 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 6994 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 6995} 6996 6997void ACodec::ExecutingState::submitRegularOutputBuffers() { 6998 bool failed = false; 6999 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 7000 BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 7001 7002 if (mCodec->mNativeWindow != NULL) { 7003 if (info->mStatus != BufferInfo::OWNED_BY_US 7004 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 7005 ALOGE("buffers should be owned by us or the surface"); 7006 failed = true; 7007 break; 7008 } 7009 7010 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 7011 continue; 7012 } 7013 } else { 7014 if (info->mStatus != BufferInfo::OWNED_BY_US) { 7015 ALOGE("buffers should be owned by us"); 7016 failed = true; 7017 break; 7018 } 7019 } 7020 7021 ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID); 7022 7023 info->checkWriteFence("submitRegularOutputBuffers"); 7024 status_t err = mCodec->fillBuffer(info); 7025 if (err != OK) { 7026 failed = true; 7027 break; 7028 } 7029 } 7030 7031 if (failed) { 7032 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7033 } 7034} 7035 7036void ACodec::ExecutingState::submitOutputBuffers() { 7037 submitRegularOutputBuffers(); 7038 if (mCodec->storingMetadataInDecodedBuffers()) { 7039 submitOutputMetaBuffers(); 7040 } 7041} 7042 7043void ACodec::ExecutingState::resume() { 7044 if (mActive) { 7045 ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str()); 7046 return; 7047 } 7048 7049 submitOutputBuffers(); 7050 7051 // Post all available input buffers 7052 if (mCodec->mBuffers[kPortIndexInput].size() == 0u) { 7053 ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str()); 7054 } 7055 7056 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) { 7057 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 7058 if (info->mStatus == BufferInfo::OWNED_BY_US) { 7059 postFillThisBuffer(info); 7060 } 7061 } 7062 7063 mActive = true; 7064} 7065 7066void ACodec::ExecutingState::stateEntered() { 7067 ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 7068 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 7069 mCodec->processDeferredMessages(); 7070} 7071 7072bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 7073 bool handled = false; 7074 7075 switch (msg->what()) { 7076 case kWhatShutdown: 7077 { 7078 int32_t keepComponentAllocated; 7079 CHECK(msg->findInt32( 7080 "keepComponentAllocated", &keepComponentAllocated)); 7081 7082 mCodec->mShutdownInProgress = true; 7083 mCodec->mExplicitShutdown = true; 7084 mCodec->mKeepComponentAllocated = keepComponentAllocated; 7085 7086 mActive = false; 7087 7088 status_t err = mCodec->mOMXNode->sendCommand( 7089 OMX_CommandStateSet, OMX_StateIdle); 7090 if (err != OK) { 7091 if (keepComponentAllocated) { 7092 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7093 } 7094 // TODO: do some recovery here. 7095 } else { 7096 mCodec->changeState(mCodec->mExecutingToIdleState); 7097 } 7098 7099 handled = true; 7100 break; 7101 } 7102 7103 case kWhatFlush: 7104 { 7105 ALOGV("[%s] ExecutingState flushing now " 7106 "(codec owns %zu/%zu input, %zu/%zu output).", 7107 mCodec->mComponentName.c_str(), 7108 mCodec->countBuffersOwnedByComponent(kPortIndexInput), 7109 mCodec->mBuffers[kPortIndexInput].size(), 7110 mCodec->countBuffersOwnedByComponent(kPortIndexOutput), 7111 mCodec->mBuffers[kPortIndexOutput].size()); 7112 7113 mActive = false; 7114 7115 status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL); 7116 if (err != OK) { 7117 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7118 } else { 7119 mCodec->changeState(mCodec->mFlushingState); 7120 } 7121 7122 handled = true; 7123 break; 7124 } 7125 7126 case kWhatResume: 7127 { 7128 resume(); 7129 7130 handled = true; 7131 break; 7132 } 7133 7134 case kWhatRequestIDRFrame: 7135 { 7136 status_t err = mCodec->requestIDRFrame(); 7137 if (err != OK) { 7138 ALOGW("Requesting an IDR frame failed."); 7139 } 7140 7141 handled = true; 7142 break; 7143 } 7144 7145 case kWhatSetParameters: 7146 { 7147 sp<AMessage> params; 7148 CHECK(msg->findMessage("params", ¶ms)); 7149 7150 status_t err = mCodec->setParameters(params); 7151 7152 sp<AMessage> reply; 7153 if (msg->findMessage("reply", &reply)) { 7154 reply->setInt32("err", err); 7155 reply->post(); 7156 } 7157 7158 handled = true; 7159 break; 7160 } 7161 7162 case ACodec::kWhatSignalEndOfInputStream: 7163 { 7164 mCodec->onSignalEndOfInputStream(); 7165 handled = true; 7166 break; 7167 } 7168 7169 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 7170 case kWhatSubmitOutputMetadataBufferIfEOS: 7171 { 7172 if (mCodec->mPortEOS[kPortIndexInput] && 7173 !mCodec->mPortEOS[kPortIndexOutput]) { 7174 status_t err = mCodec->submitOutputMetadataBuffer(); 7175 if (err == OK) { 7176 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 7177 } 7178 } 7179 return true; 7180 } 7181 7182 default: 7183 handled = BaseState::onMessageReceived(msg); 7184 break; 7185 } 7186 7187 return handled; 7188} 7189 7190status_t ACodec::setParameters(const sp<AMessage> ¶ms) { 7191 int32_t videoBitrate; 7192 if (params->findInt32("video-bitrate", &videoBitrate)) { 7193 OMX_VIDEO_CONFIG_BITRATETYPE configParams; 7194 InitOMXParams(&configParams); 7195 configParams.nPortIndex = kPortIndexOutput; 7196 configParams.nEncodeBitrate = videoBitrate; 7197 7198 status_t err = mOMXNode->setConfig( 7199 OMX_IndexConfigVideoBitrate, 7200 &configParams, 7201 sizeof(configParams)); 7202 7203 if (err != OK) { 7204 ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d", 7205 videoBitrate, err); 7206 7207 return err; 7208 } 7209 } 7210 7211 int64_t timeOffsetUs; 7212 if (params->findInt64("time-offset-us", &timeOffsetUs)) { 7213 if (mGraphicBufferSource == NULL) { 7214 ALOGE("[%s] Invalid to set input buffer time offset without surface", 7215 mComponentName.c_str()); 7216 return INVALID_OPERATION; 7217 } 7218 7219 status_t err = statusFromBinderStatus( 7220 mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs)); 7221 7222 if (err != OK) { 7223 ALOGE("[%s] Unable to set input buffer time offset (err %d)", 7224 mComponentName.c_str(), 7225 err); 7226 return err; 7227 } 7228 } 7229 7230 int64_t skipFramesBeforeUs; 7231 if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) { 7232 if (mGraphicBufferSource == NULL) { 7233 ALOGE("[%s] Invalid to set start time without surface", 7234 mComponentName.c_str()); 7235 return INVALID_OPERATION; 7236 } 7237 7238 status_t err = statusFromBinderStatus( 7239 mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs)); 7240 7241 if (err != OK) { 7242 ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err); 7243 return err; 7244 } 7245 } 7246 7247 int32_t dropInputFrames; 7248 if (params->findInt32("drop-input-frames", &dropInputFrames)) { 7249 if (mGraphicBufferSource == NULL) { 7250 ALOGE("[%s] Invalid to set suspend without surface", 7251 mComponentName.c_str()); 7252 return INVALID_OPERATION; 7253 } 7254 7255 int64_t suspendStartTimeUs = -1; 7256 (void) params->findInt64("drop-start-time-us", &suspendStartTimeUs); 7257 status_t err = statusFromBinderStatus( 7258 mGraphicBufferSource->setSuspend(dropInputFrames != 0, suspendStartTimeUs)); 7259 7260 if (err != OK) { 7261 ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err); 7262 return err; 7263 } 7264 } 7265 7266 int64_t stopTimeUs; 7267 if (params->findInt64("stop-time-us", &stopTimeUs)) { 7268 if (mGraphicBufferSource == NULL) { 7269 ALOGE("[%s] Invalid to set stop time without surface", 7270 mComponentName.c_str()); 7271 return INVALID_OPERATION; 7272 } 7273 status_t err = statusFromBinderStatus( 7274 mGraphicBufferSource->setStopTimeUs(stopTimeUs)); 7275 7276 if (err != OK) { 7277 ALOGE("Failed to set parameter 'stop-time-us' (err %d)", err); 7278 return err; 7279 } 7280 7281 int64_t stopTimeOffsetUs; 7282 err = statusFromBinderStatus( 7283 mGraphicBufferSource->getStopTimeOffsetUs(&stopTimeOffsetUs)); 7284 7285 if (err != OK) { 7286 ALOGE("Failed to get stop time offset (err %d)", err); 7287 return err; 7288 } 7289 mInputFormat->setInt64("android._stop-time-offset-us", stopTimeOffsetUs); 7290 } 7291 7292 int32_t dummy; 7293 if (params->findInt32("request-sync", &dummy)) { 7294 status_t err = requestIDRFrame(); 7295 7296 if (err != OK) { 7297 ALOGE("Requesting a sync frame failed w/ err %d", err); 7298 return err; 7299 } 7300 } 7301 7302 float rate; 7303 if (params->findFloat("operating-rate", &rate) && rate > 0) { 7304 status_t err = setOperatingRate(rate, mIsVideo); 7305 if (err != OK) { 7306 ALOGE("Failed to set parameter 'operating-rate' (err %d)", err); 7307 return err; 7308 } 7309 } 7310 7311 int32_t intraRefreshPeriod = 0; 7312 if (params->findInt32("intra-refresh-period", &intraRefreshPeriod) 7313 && intraRefreshPeriod > 0) { 7314 status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false); 7315 if (err != OK) { 7316 ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional", 7317 mComponentName.c_str()); 7318 err = OK; 7319 } 7320 } 7321 7322 int32_t latency = 0; 7323 if (params->findInt32("latency", &latency) && latency > 0) { 7324 status_t err = setLatency(latency); 7325 if (err != OK) { 7326 ALOGI("[%s] failed setLatency. Failure is fine since this key is optional", 7327 mComponentName.c_str()); 7328 err = OK; 7329 } 7330 } 7331 7332 status_t err = configureTemporalLayers(params, false /* inConfigure */, mOutputFormat); 7333 if (err != OK) { 7334 err = OK; // ignore failure 7335 } 7336 7337 return setVendorParameters(params); 7338} 7339 7340// Removes trailing tags matching |tag| from |key| (e.g. a settings name). |minLength| specifies 7341// the minimum number of characters to keep in |key| (even if it has trailing tags). 7342// (Used to remove trailing 'value' tags in settings names, e.g. to normalize 7343// 'vendor.settingsX.value' to 'vendor.settingsX') 7344static void removeTrailingTags(char *key, size_t minLength, const char *tag) { 7345 size_t length = strlen(key); 7346 size_t tagLength = strlen(tag); 7347 while (length > minLength + tagLength 7348 && !strcmp(key + length - tagLength, tag) 7349 && key[length - tagLength - 1] == '.') { 7350 length -= tagLength + 1; 7351 key[length] = '\0'; 7352 } 7353} 7354 7355/** 7356 * Struct encompassing a vendor extension config structure and a potential error status (in case 7357 * the structure is null). Used to iterate through vendor extensions. 7358 */ 7359struct VendorExtension { 7360 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config; // structure does not own config 7361 status_t status; 7362 7363 // create based on an error status 7364 VendorExtension(status_t s_ = NO_INIT) : config(nullptr), status(s_) { } 7365 7366 // create based on a successfully retrieved config structure 7367 VendorExtension(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *c_) : config(c_), status(OK) { } 7368}; 7369 7370// class VendorExtensions; 7371/** 7372 * Forward iterator to enumerate vendor extensions supported by an OMX component. 7373 */ 7374class VendorExtensionIterator { 7375//private: 7376 static constexpr size_t kLastIndex = ~(size_t)0; // last index marker 7377 7378 sp<IOMXNode> mNode; // component 7379 size_t mIndex; // current android extension index 7380 std::unique_ptr<uint8_t[]> mBacking; // current extension's backing 7381 VendorExtension mCurrent; // current extension 7382 7383 VendorExtensionIterator(const sp<IOMXNode> &node, size_t index) 7384 : mNode(node), 7385 mIndex(index) { 7386 mCurrent = retrieve(); 7387 } 7388 7389 friend class VendorExtensions; 7390 7391public: 7392 // copy constructor 7393 VendorExtensionIterator(const VendorExtensionIterator &it) 7394 : VendorExtensionIterator(it.mNode, it.mIndex) { } 7395 7396 // retrieves the current extension pointed to by this iterator 7397 VendorExtension retrieve() { 7398 if (mIndex == kLastIndex) { 7399 return NO_INIT; 7400 } 7401 7402 // try with one param first, then retry if extension needs more than 1 param 7403 for (size_t paramSizeUsed = 1;; ) { 7404 if (paramSizeUsed > OMX_MAX_ANDROID_VENDOR_PARAMCOUNT) { 7405 return BAD_VALUE; // this prevents overflow in the following formula 7406 } 7407 7408 size_t size = sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE) + 7409 (paramSizeUsed - 1) * sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::param); 7410 mBacking.reset(new uint8_t[size]); 7411 if (!mBacking) { 7412 return NO_MEMORY; 7413 } 7414 7415 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = 7416 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(mBacking.get()); 7417 7418 InitOMXParams(config); 7419 config->nSize = size; 7420 config->nIndex = mIndex; 7421 config->nParamSizeUsed = paramSizeUsed; 7422 status_t err = mNode->getConfig( 7423 (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension, config, size); 7424 if (err == OK && config->nParamCount > paramSizeUsed && paramSizeUsed == 1) { 7425 // reallocate if we need a bigger config 7426 paramSizeUsed = config->nParamCount; 7427 continue; 7428 } else if (err == NOT_ENOUGH_DATA 7429 || (err != OK && mIndex == 0)) { 7430 // stop iterator on no-more signal, or if index is not at all supported 7431 mIndex = kLastIndex; 7432 return NO_INIT; 7433 } else if (err != OK) { 7434 return err; 7435 } else if (paramSizeUsed != config->nParamSizeUsed) { 7436 return BAD_VALUE; // component shall not modify size of nParam 7437 } 7438 7439 return config; 7440 } 7441 } 7442 7443 // returns extension pointed to by this iterator 7444 VendorExtension operator*() { 7445 return mCurrent; 7446 } 7447 7448 // prefix increment: move to next extension 7449 VendorExtensionIterator &operator++() { // prefix 7450 if (mIndex != kLastIndex) { 7451 ++mIndex; 7452 mCurrent = retrieve(); 7453 } 7454 return *this; 7455 } 7456 7457 // iterator equality operators 7458 bool operator==(const VendorExtensionIterator &o) { 7459 return mNode == o.mNode && mIndex == o.mIndex; 7460 } 7461 7462 bool operator!=(const VendorExtensionIterator &o) { 7463 return !(*this == o); 7464 } 7465}; 7466 7467/** 7468 * Iterable container for vendor extensions provided by a component 7469 */ 7470class VendorExtensions { 7471//private: 7472 sp<IOMXNode> mNode; 7473 7474public: 7475 VendorExtensions(const sp<IOMXNode> &node) 7476 : mNode(node) { 7477 } 7478 7479 VendorExtensionIterator begin() { 7480 return VendorExtensionIterator(mNode, 0); 7481 } 7482 7483 VendorExtensionIterator end() { 7484 return VendorExtensionIterator(mNode, VendorExtensionIterator::kLastIndex); 7485 } 7486}; 7487 7488status_t ACodec::setVendorParameters(const sp<AMessage> ¶ms) { 7489 std::map<std::string, std::string> vendorKeys; // maps reduced name to actual name 7490 constexpr char prefix[] = "vendor."; 7491 constexpr size_t prefixLength = sizeof(prefix) - 1; 7492 // longest possible vendor param name 7493 char reducedKey[OMX_MAX_STRINGNAME_SIZE + OMX_MAX_STRINGVALUE_SIZE]; 7494 7495 // identify all vendor keys to speed up search later and to detect vendor keys 7496 for (size_t i = params->countEntries(); i; --i) { 7497 AMessage::Type keyType; 7498 const char* key = params->getEntryNameAt(i - 1, &keyType); 7499 if (key != nullptr && !strncmp(key, prefix, prefixLength) 7500 // it is safe to limit format keys to the max vendor param size as we only 7501 // shorten parameter names by removing any trailing 'value' tags, and we 7502 // already remove the vendor prefix. 7503 && strlen(key + prefixLength) < sizeof(reducedKey) 7504 && (keyType == AMessage::kTypeInt32 7505 || keyType == AMessage::kTypeInt64 7506 || keyType == AMessage::kTypeString)) { 7507 strcpy(reducedKey, key + prefixLength); 7508 removeTrailingTags(reducedKey, 0, "value"); 7509 auto existingKey = vendorKeys.find(reducedKey); 7510 if (existingKey != vendorKeys.end()) { 7511 ALOGW("[%s] vendor parameter '%s' aliases parameter '%s'", 7512 mComponentName.c_str(), key, existingKey->second.c_str()); 7513 // ignore for now 7514 } 7515 vendorKeys.emplace(reducedKey, key); 7516 } 7517 } 7518 7519 // don't bother component if we don't have vendor extensions as they may not have implemented 7520 // the android vendor extension support, which will lead to unnecessary OMX failure logs. 7521 if (vendorKeys.empty()) { 7522 return OK; 7523 } 7524 7525 char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) + 7526 sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey)]; 7527 7528 status_t finalError = OK; 7529 7530 // don't try again if component does not have vendor extensions 7531 if (mVendorExtensionsStatus == kExtensionsNone) { 7532 return OK; 7533 } 7534 7535 for (VendorExtension ext : VendorExtensions(mOMXNode)) { 7536 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config; 7537 if (config == nullptr) { 7538 return ext.status; 7539 } 7540 7541 mVendorExtensionsStatus = kExtensionsExist; 7542 7543 config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name 7544 strcpy(key, (const char *)config->cName); 7545 size_t nameLength = strlen(key); 7546 key[nameLength] = '.'; 7547 7548 // don't set vendor extension if client has not provided any of its parameters 7549 // or if client simply unsets parameters that are already unset 7550 bool needToSet = false; 7551 for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) { 7552 // null-terminate param key 7553 config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0'; 7554 strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey); 7555 removeTrailingTags(key, nameLength, "value"); 7556 auto existingKey = vendorKeys.find(key); 7557 7558 // don't touch (e.g. change) parameters that are not specified by client 7559 if (existingKey == vendorKeys.end()) { 7560 continue; 7561 } 7562 7563 bool wasSet = config->param[paramIndex].bSet; 7564 switch (config->param[paramIndex].eValueType) { 7565 case OMX_AndroidVendorValueInt32: 7566 { 7567 int32_t value; 7568 config->param[paramIndex].bSet = 7569 (OMX_BOOL)params->findInt32(existingKey->second.c_str(), &value); 7570 if (config->param[paramIndex].bSet) { 7571 config->param[paramIndex].nInt32 = value; 7572 } 7573 break; 7574 } 7575 case OMX_AndroidVendorValueInt64: 7576 { 7577 int64_t value; 7578 config->param[paramIndex].bSet = 7579 (OMX_BOOL)params->findAsInt64(existingKey->second.c_str(), &value); 7580 if (config->param[paramIndex].bSet) { 7581 config->param[paramIndex].nInt64 = value; 7582 } 7583 break; 7584 } 7585 case OMX_AndroidVendorValueString: 7586 { 7587 AString value; 7588 config->param[paramIndex].bSet = 7589 (OMX_BOOL)params->findString(existingKey->second.c_str(), &value); 7590 if (config->param[paramIndex].bSet) { 7591 strncpy((char *)config->param[paramIndex].cString, value.c_str(), 7592 sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cString)); 7593 } 7594 break; 7595 } 7596 default: 7597 ALOGW("[%s] vendor parameter '%s' is not a supported value", 7598 mComponentName.c_str(), key); 7599 continue; 7600 } 7601 if (config->param[paramIndex].bSet || wasSet) { 7602 needToSet = true; 7603 } 7604 } 7605 7606 if (needToSet) { 7607 status_t err = mOMXNode->setConfig( 7608 (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension, 7609 config, config->nSize); 7610 if (err != OK) { 7611 key[nameLength] = '\0'; 7612 ALOGW("[%s] failed to set vendor extension '%s'", mComponentName.c_str(), key); 7613 // try to set each extension, and return first failure 7614 if (finalError == OK) { 7615 finalError = err; 7616 } 7617 } 7618 } 7619 } 7620 7621 if (mVendorExtensionsStatus == kExtensionsUnchecked) { 7622 mVendorExtensionsStatus = kExtensionsNone; 7623 } 7624 7625 return finalError; 7626} 7627 7628status_t ACodec::getVendorParameters(OMX_U32 portIndex, sp<AMessage> &format) { 7629 constexpr char prefix[] = "vendor."; 7630 constexpr size_t prefixLength = sizeof(prefix) - 1; 7631 char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) + 7632 sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey) + prefixLength]; 7633 strcpy(key, prefix); 7634 7635 // don't try again if component does not have vendor extensions 7636 if (mVendorExtensionsStatus == kExtensionsNone) { 7637 return OK; 7638 } 7639 7640 for (VendorExtension ext : VendorExtensions(mOMXNode)) { 7641 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config; 7642 if (config == nullptr) { 7643 return ext.status; 7644 } 7645 7646 mVendorExtensionsStatus = kExtensionsExist; 7647 7648 if (config->eDir != (portIndex == kPortIndexInput ? OMX_DirInput : OMX_DirOutput)) { 7649 continue; 7650 } 7651 7652 config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name 7653 strcpy(key + prefixLength, (const char *)config->cName); 7654 size_t nameLength = strlen(key); 7655 key[nameLength] = '.'; 7656 7657 for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) { 7658 // null-terminate param key 7659 config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0'; 7660 strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey); 7661 removeTrailingTags(key, nameLength, "value"); 7662 if (config->param[paramIndex].bSet) { 7663 switch (config->param[paramIndex].eValueType) { 7664 case OMX_AndroidVendorValueInt32: 7665 { 7666 format->setInt32(key, config->param[paramIndex].nInt32); 7667 break; 7668 } 7669 case OMX_AndroidVendorValueInt64: 7670 { 7671 format->setInt64(key, config->param[paramIndex].nInt64); 7672 break; 7673 } 7674 case OMX_AndroidVendorValueString: 7675 { 7676 config->param[paramIndex].cString[OMX_MAX_STRINGVALUE_SIZE - 1] = '\0'; 7677 format->setString(key, (const char *)config->param[paramIndex].cString); 7678 break; 7679 } 7680 default: 7681 ALOGW("vendor parameter %s is not a supported value", key); 7682 continue; 7683 } 7684 } 7685 } 7686 } 7687 7688 if (mVendorExtensionsStatus == kExtensionsUnchecked) { 7689 mVendorExtensionsStatus = kExtensionsNone; 7690 } 7691 7692 return OK; 7693} 7694 7695void ACodec::onSignalEndOfInputStream() { 7696 status_t err = INVALID_OPERATION; 7697 if (mGraphicBufferSource != NULL) { 7698 err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream()); 7699 } 7700 mCallback->onSignaledInputEOS(err); 7701} 7702 7703void ACodec::forceStateTransition(int generation) { 7704 if (generation != mStateGeneration) { 7705 ALOGV("Ignoring stale force state transition message: #%d (now #%d)", 7706 generation, mStateGeneration); 7707 return; 7708 } 7709 ALOGE("State machine stuck"); 7710 // Error must have already been signalled to the client. 7711 7712 // Deferred messages will be handled at LoadedState at the end of the 7713 // transition. 7714 mShutdownInProgress = true; 7715 // No shutdown complete callback at the end of the transition. 7716 mExplicitShutdown = false; 7717 mKeepComponentAllocated = true; 7718 7719 status_t err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle); 7720 if (err != OK) { 7721 // TODO: do some recovery here. 7722 } else { 7723 changeState(mExecutingToIdleState); 7724 } 7725} 7726 7727bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { 7728 mCodec->onFrameRendered(mediaTimeUs, systemNano); 7729 return true; 7730} 7731 7732bool ACodec::ExecutingState::onOMXEvent( 7733 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7734 switch (event) { 7735 case OMX_EventPortSettingsChanged: 7736 { 7737 CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 7738 7739 mCodec->onOutputFormatChanged(); 7740 7741 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 7742 mCodec->mMetadataBuffersToSubmit = 0; 7743 CHECK_EQ(mCodec->mOMXNode->sendCommand( 7744 OMX_CommandPortDisable, kPortIndexOutput), 7745 (status_t)OK); 7746 7747 mCodec->freeOutputBuffersNotOwnedByComponent(); 7748 7749 mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 7750 } else if (data2 != OMX_IndexConfigCommonOutputCrop 7751 && data2 != OMX_IndexConfigAndroidIntraRefresh) { 7752 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x", 7753 mCodec->mComponentName.c_str(), data2); 7754 } 7755 7756 return true; 7757 } 7758 7759 case OMX_EventBufferFlag: 7760 { 7761 return true; 7762 } 7763 7764 default: 7765 return BaseState::onOMXEvent(event, data1, data2); 7766 } 7767} 7768 7769//////////////////////////////////////////////////////////////////////////////// 7770 7771ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 7772 ACodec *codec) 7773 : BaseState(codec) { 7774} 7775 7776ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 7777 OMX_U32 portIndex) { 7778 if (portIndex == kPortIndexOutput) { 7779 return FREE_BUFFERS; 7780 } 7781 7782 CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 7783 7784 return RESUBMIT_BUFFERS; 7785} 7786 7787bool ACodec::OutputPortSettingsChangedState::onMessageReceived( 7788 const sp<AMessage> &msg) { 7789 bool handled = false; 7790 7791 switch (msg->what()) { 7792 case kWhatFlush: 7793 case kWhatShutdown: { 7794 if (mCodec->mFatalError) { 7795 sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec); 7796 msg->setInt32("generation", mCodec->mStateGeneration); 7797 msg->post(3000000); 7798 } 7799 // fall-through 7800 } 7801 case kWhatResume: 7802 case kWhatSetParameters: 7803 { 7804 if (msg->what() == kWhatResume) { 7805 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 7806 } 7807 7808 mCodec->deferMessage(msg); 7809 handled = true; 7810 break; 7811 } 7812 7813 case kWhatForceStateTransition: 7814 { 7815 int32_t generation = 0; 7816 CHECK(msg->findInt32("generation", &generation)); 7817 mCodec->forceStateTransition(generation); 7818 7819 handled = true; 7820 break; 7821 } 7822 7823 default: 7824 handled = BaseState::onMessageReceived(msg); 7825 break; 7826 } 7827 7828 return handled; 7829} 7830 7831void ACodec::OutputPortSettingsChangedState::stateEntered() { 7832 ALOGV("[%s] Now handling output port settings change", 7833 mCodec->mComponentName.c_str()); 7834} 7835 7836bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered( 7837 int64_t mediaTimeUs, nsecs_t systemNano) { 7838 mCodec->onFrameRendered(mediaTimeUs, systemNano); 7839 return true; 7840} 7841 7842bool ACodec::OutputPortSettingsChangedState::onOMXEvent( 7843 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7844 switch (event) { 7845 case OMX_EventCmdComplete: 7846 { 7847 if (data1 == (OMX_U32)OMX_CommandPortDisable) { 7848 if (data2 != (OMX_U32)kPortIndexOutput) { 7849 ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2); 7850 return false; 7851 } 7852 7853 ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str()); 7854 7855 status_t err = OK; 7856 if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) { 7857 ALOGE("disabled port should be empty, but has %zu buffers", 7858 mCodec->mBuffers[kPortIndexOutput].size()); 7859 err = FAILED_TRANSACTION; 7860 } else { 7861 if (mCodec->getTrebleFlag()) { 7862 mCodec->mAllocator[kPortIndexOutput].clear(); 7863 } else { 7864 mCodec->mDealer[kPortIndexOutput].clear(); 7865 } 7866 } 7867 7868 if (err == OK) { 7869 err = mCodec->mOMXNode->sendCommand( 7870 OMX_CommandPortEnable, kPortIndexOutput); 7871 } 7872 7873 if (err == OK) { 7874 err = mCodec->allocateBuffersOnPort(kPortIndexOutput); 7875 ALOGE_IF(err != OK, "Failed to allocate output port buffers after port " 7876 "reconfiguration: (%d)", err); 7877 mCodec->mCallback->onOutputBuffersChanged(); 7878 } 7879 7880 if (err != OK) { 7881 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 7882 ALOGE("Error occurred while disabling the output port"); 7883 } 7884 7885 return true; 7886 } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 7887 if (data2 != (OMX_U32)kPortIndexOutput) { 7888 ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2); 7889 return false; 7890 } 7891 7892 ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str()); 7893 7894 if (mCodec->mExecutingState->active()) { 7895 mCodec->mExecutingState->submitOutputBuffers(); 7896 } 7897 7898 mCodec->changeState(mCodec->mExecutingState); 7899 7900 return true; 7901 } 7902 7903 return false; 7904 } 7905 7906 default: 7907 return BaseState::onOMXEvent(event, data1, data2); 7908 } 7909} 7910 7911//////////////////////////////////////////////////////////////////////////////// 7912 7913ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 7914 : BaseState(codec), 7915 mComponentNowIdle(false) { 7916} 7917 7918bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 7919 bool handled = false; 7920 7921 switch (msg->what()) { 7922 case kWhatFlush: 7923 { 7924 // Don't send me a flush request if you previously wanted me 7925 // to shutdown. 7926 ALOGW("Ignoring flush request in ExecutingToIdleState"); 7927 break; 7928 } 7929 7930 case kWhatShutdown: 7931 { 7932 mCodec->deferMessage(msg); 7933 handled = true; 7934 break; 7935 } 7936 7937 default: 7938 handled = BaseState::onMessageReceived(msg); 7939 break; 7940 } 7941 7942 return handled; 7943} 7944 7945void ACodec::ExecutingToIdleState::stateEntered() { 7946 ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 7947 7948 mComponentNowIdle = false; 7949 mCodec->mLastOutputFormat.clear(); 7950} 7951 7952bool ACodec::ExecutingToIdleState::onOMXEvent( 7953 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7954 switch (event) { 7955 case OMX_EventCmdComplete: 7956 { 7957 if (data1 != (OMX_U32)OMX_CommandStateSet 7958 || data2 != (OMX_U32)OMX_StateIdle) { 7959 ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)", 7960 asString((OMX_COMMANDTYPE)data1), data1, 7961 asString((OMX_STATETYPE)data2), data2); 7962 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7963 return true; 7964 } 7965 7966 mComponentNowIdle = true; 7967 7968 changeStateIfWeOwnAllBuffers(); 7969 7970 return true; 7971 } 7972 7973 case OMX_EventPortSettingsChanged: 7974 case OMX_EventBufferFlag: 7975 { 7976 // We're shutting down and don't care about this anymore. 7977 return true; 7978 } 7979 7980 default: 7981 return BaseState::onOMXEvent(event, data1, data2); 7982 } 7983} 7984 7985void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 7986 if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) { 7987 status_t err = mCodec->mOMXNode->sendCommand( 7988 OMX_CommandStateSet, OMX_StateLoaded); 7989 if (err == OK) { 7990 err = mCodec->freeBuffersOnPort(kPortIndexInput); 7991 status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput); 7992 if (err == OK) { 7993 err = err2; 7994 } 7995 } 7996 7997 if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) 7998 && mCodec->mNativeWindow != NULL) { 7999 // We push enough 1x1 blank buffers to ensure that one of 8000 // them has made it to the display. This allows the OMX 8001 // component teardown to zero out any protected buffers 8002 // without the risk of scanning out one of those buffers. 8003 pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get()); 8004 } 8005 8006 if (err != OK) { 8007 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 8008 return; 8009 } 8010 8011 mCodec->changeState(mCodec->mIdleToLoadedState); 8012 } 8013} 8014 8015void ACodec::ExecutingToIdleState::onInputBufferFilled( 8016 const sp<AMessage> &msg) { 8017 BaseState::onInputBufferFilled(msg); 8018 8019 changeStateIfWeOwnAllBuffers(); 8020} 8021 8022void ACodec::ExecutingToIdleState::onOutputBufferDrained( 8023 const sp<AMessage> &msg) { 8024 BaseState::onOutputBufferDrained(msg); 8025 8026 changeStateIfWeOwnAllBuffers(); 8027} 8028 8029//////////////////////////////////////////////////////////////////////////////// 8030 8031ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 8032 : BaseState(codec) { 8033} 8034 8035bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 8036 bool handled = false; 8037 8038 switch (msg->what()) { 8039 case kWhatShutdown: 8040 { 8041 mCodec->deferMessage(msg); 8042 handled = true; 8043 break; 8044 } 8045 8046 case kWhatFlush: 8047 { 8048 // Don't send me a flush request if you previously wanted me 8049 // to shutdown. 8050 ALOGE("Got flush request in IdleToLoadedState"); 8051 break; 8052 } 8053 8054 default: 8055 handled = BaseState::onMessageReceived(msg); 8056 break; 8057 } 8058 8059 return handled; 8060} 8061 8062void ACodec::IdleToLoadedState::stateEntered() { 8063 ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 8064} 8065 8066bool ACodec::IdleToLoadedState::onOMXEvent( 8067 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 8068 switch (event) { 8069 case OMX_EventCmdComplete: 8070 { 8071 if (data1 != (OMX_U32)OMX_CommandStateSet 8072 || data2 != (OMX_U32)OMX_StateLoaded) { 8073 ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)", 8074 asString((OMX_COMMANDTYPE)data1), data1, 8075 asString((OMX_STATETYPE)data2), data2); 8076 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 8077 return true; 8078 } 8079 8080 mCodec->changeState(mCodec->mLoadedState); 8081 8082 return true; 8083 } 8084 8085 default: 8086 return BaseState::onOMXEvent(event, data1, data2); 8087 } 8088} 8089 8090//////////////////////////////////////////////////////////////////////////////// 8091 8092ACodec::FlushingState::FlushingState(ACodec *codec) 8093 : BaseState(codec) { 8094} 8095 8096void ACodec::FlushingState::stateEntered() { 8097 ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 8098 8099 mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 8100} 8101 8102bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 8103 bool handled = false; 8104 8105 switch (msg->what()) { 8106 case kWhatShutdown: 8107 { 8108 mCodec->deferMessage(msg); 8109 if (mCodec->mFatalError) { 8110 sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec); 8111 msg->setInt32("generation", mCodec->mStateGeneration); 8112 msg->post(3000000); 8113 } 8114 break; 8115 } 8116 8117 case kWhatFlush: 8118 { 8119 // We're already doing this right now. 8120 handled = true; 8121 break; 8122 } 8123 8124 case kWhatForceStateTransition: 8125 { 8126 int32_t generation = 0; 8127 CHECK(msg->findInt32("generation", &generation)); 8128 mCodec->forceStateTransition(generation); 8129 8130 handled = true; 8131 break; 8132 } 8133 8134 default: 8135 handled = BaseState::onMessageReceived(msg); 8136 break; 8137 } 8138 8139 return handled; 8140} 8141 8142bool ACodec::FlushingState::onOMXEvent( 8143 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 8144 ALOGV("[%s] FlushingState onOMXEvent(%u,%d)", 8145 mCodec->mComponentName.c_str(), event, (OMX_S32)data1); 8146 8147 switch (event) { 8148 case OMX_EventCmdComplete: 8149 { 8150 if (data1 != (OMX_U32)OMX_CommandFlush) { 8151 ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState", 8152 asString((OMX_COMMANDTYPE)data1), data1, data2); 8153 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 8154 return true; 8155 } 8156 8157 if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 8158 if (mFlushComplete[data2]) { 8159 ALOGW("Flush already completed for %s port", 8160 data2 == kPortIndexInput ? "input" : "output"); 8161 return true; 8162 } 8163 mFlushComplete[data2] = true; 8164 8165 if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) { 8166 changeStateIfWeOwnAllBuffers(); 8167 } 8168 } else if (data2 == OMX_ALL) { 8169 if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) { 8170 ALOGW("received flush complete event for OMX_ALL before ports have been" 8171 "flushed (%d/%d)", 8172 mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]); 8173 return false; 8174 } 8175 8176 changeStateIfWeOwnAllBuffers(); 8177 } else { 8178 ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2); 8179 } 8180 8181 return true; 8182 } 8183 8184 case OMX_EventPortSettingsChanged: 8185 { 8186 sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec); 8187 msg->setInt32("type", omx_message::EVENT); 8188 msg->setInt32("generation", mCodec->mNodeGeneration); 8189 msg->setInt32("event", event); 8190 msg->setInt32("data1", data1); 8191 msg->setInt32("data2", data2); 8192 8193 ALOGV("[%s] Deferring OMX_EventPortSettingsChanged", 8194 mCodec->mComponentName.c_str()); 8195 8196 mCodec->deferMessage(msg); 8197 8198 return true; 8199 } 8200 8201 default: 8202 return BaseState::onOMXEvent(event, data1, data2); 8203 } 8204 8205 return true; 8206} 8207 8208void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 8209 BaseState::onOutputBufferDrained(msg); 8210 8211 changeStateIfWeOwnAllBuffers(); 8212} 8213 8214void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 8215 BaseState::onInputBufferFilled(msg); 8216 8217 changeStateIfWeOwnAllBuffers(); 8218} 8219 8220void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 8221 if (mFlushComplete[kPortIndexInput] 8222 && mFlushComplete[kPortIndexOutput] 8223 && mCodec->allYourBuffersAreBelongToUs()) { 8224 // We now own all buffers except possibly those still queued with 8225 // the native window for rendering. Let's get those back as well. 8226 mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs(); 8227 8228 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 8229 8230 mCodec->mCallback->onFlushCompleted(); 8231 8232 mCodec->mPortEOS[kPortIndexInput] = 8233 mCodec->mPortEOS[kPortIndexOutput] = false; 8234 8235 mCodec->mInputEOSResult = OK; 8236 8237 if (mCodec->mSkipCutBuffer != NULL) { 8238 mCodec->mSkipCutBuffer->clear(); 8239 } 8240 8241 mCodec->changeState(mCodec->mExecutingState); 8242 } 8243} 8244 8245status_t ACodec::queryCapabilities( 8246 const char* owner, const char* name, const char* mime, bool isEncoder, 8247 MediaCodecInfo::CapabilitiesWriter* caps) { 8248 const char *role = GetComponentRole(isEncoder, mime); 8249 if (role == NULL) { 8250 return BAD_VALUE; 8251 } 8252 8253 OMXClient client; 8254 status_t err = client.connect(owner); 8255 if (err != OK) { 8256 return err; 8257 } 8258 8259 sp<IOMX> omx = client.interface(); 8260 sp<CodecObserver> observer = new CodecObserver; 8261 sp<IOMXNode> omxNode; 8262 8263 err = omx->allocateNode(name, observer, &omxNode); 8264 if (err != OK) { 8265 client.disconnect(); 8266 return err; 8267 } 8268 8269 err = SetComponentRole(omxNode, role); 8270 if (err != OK) { 8271 omxNode->freeNode(); 8272 client.disconnect(); 8273 return err; 8274 } 8275 8276 bool isVideo = strncasecmp(mime, "video/", 6) == 0; 8277 8278 if (isVideo) { 8279 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 8280 InitOMXParams(¶m); 8281 param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput; 8282 8283 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 8284 param.nProfileIndex = index; 8285 status_t err = omxNode->getParameter( 8286 OMX_IndexParamVideoProfileLevelQuerySupported, 8287 ¶m, sizeof(param)); 8288 if (err != OK) { 8289 break; 8290 } 8291 caps->addProfileLevel(param.eProfile, param.eLevel); 8292 8293 // AVC components may not list the constrained profiles explicitly, but 8294 // decoders that support a profile also support its constrained version. 8295 // Encoders must explicitly support constrained profiles. 8296 if (!isEncoder && strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) == 0) { 8297 if (param.eProfile == OMX_VIDEO_AVCProfileHigh) { 8298 caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedHigh, param.eLevel); 8299 } else if (param.eProfile == OMX_VIDEO_AVCProfileBaseline) { 8300 caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedBaseline, param.eLevel); 8301 } 8302 } 8303 8304 if (index == kMaxIndicesToCheck) { 8305 ALOGW("[%s] stopping checking profiles after %u: %x/%x", 8306 name, index, 8307 param.eProfile, param.eLevel); 8308 } 8309 } 8310 8311 // Color format query 8312 // return colors in the order reported by the OMX component 8313 // prefix "flexible" standard ones with the flexible equivalent 8314 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 8315 InitOMXParams(&portFormat); 8316 portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput; 8317 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 8318 portFormat.nIndex = index; 8319 status_t err = omxNode->getParameter( 8320 OMX_IndexParamVideoPortFormat, 8321 &portFormat, sizeof(portFormat)); 8322 if (err != OK) { 8323 break; 8324 } 8325 8326 OMX_U32 flexibleEquivalent; 8327 if (IsFlexibleColorFormat( 8328 omxNode, portFormat.eColorFormat, false /* usingNativeWindow */, 8329 &flexibleEquivalent)) { 8330 caps->addColorFormat(flexibleEquivalent); 8331 } 8332 caps->addColorFormat(portFormat.eColorFormat); 8333 8334 if (index == kMaxIndicesToCheck) { 8335 ALOGW("[%s] stopping checking formats after %u: %s(%x)", 8336 name, index, 8337 asString(portFormat.eColorFormat), portFormat.eColorFormat); 8338 } 8339 } 8340 } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC) == 0) { 8341 // More audio codecs if they have profiles. 8342 OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param; 8343 InitOMXParams(¶m); 8344 param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput; 8345 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 8346 param.nProfileIndex = index; 8347 status_t err = omxNode->getParameter( 8348 (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported, 8349 ¶m, sizeof(param)); 8350 if (err != OK) { 8351 break; 8352 } 8353 // For audio, level is ignored. 8354 caps->addProfileLevel(param.eProfile, 0 /* level */); 8355 8356 if (index == kMaxIndicesToCheck) { 8357 ALOGW("[%s] stopping checking profiles after %u: %x", 8358 name, index, 8359 param.eProfile); 8360 } 8361 } 8362 8363 // NOTE: Without Android extensions, OMX does not provide a way to query 8364 // AAC profile support 8365 if (param.nProfileIndex == 0) { 8366 ALOGW("component %s doesn't support profile query.", name); 8367 } 8368 } 8369 8370 if (isVideo && !isEncoder) { 8371 native_handle_t *sidebandHandle = NULL; 8372 if (omxNode->configureVideoTunnelMode( 8373 kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) { 8374 // tunneled playback includes adaptive playback 8375 caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback 8376 | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback); 8377 } else if (omxNode->setPortMode( 8378 kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK || 8379 omxNode->prepareForAdaptivePlayback( 8380 kPortIndexOutput, OMX_TRUE, 8381 1280 /* width */, 720 /* height */) == OK) { 8382 caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback); 8383 } 8384 } 8385 8386 if (isVideo && isEncoder) { 8387 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params; 8388 InitOMXParams(¶ms); 8389 params.nPortIndex = kPortIndexOutput; 8390 // TODO: should we verify if fallback is supported? 8391 if (omxNode->getConfig( 8392 (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, 8393 ¶ms, sizeof(params)) == OK) { 8394 caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh); 8395 } 8396 } 8397 8398 omxNode->freeNode(); 8399 client.disconnect(); 8400 return OK; 8401} 8402 8403// These are supposed be equivalent to the logic in 8404// "audio_channel_out_mask_from_count". 8405//static 8406status_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) { 8407 switch (numChannels) { 8408 case 1: 8409 map[0] = OMX_AUDIO_ChannelCF; 8410 break; 8411 case 2: 8412 map[0] = OMX_AUDIO_ChannelLF; 8413 map[1] = OMX_AUDIO_ChannelRF; 8414 break; 8415 case 3: 8416 map[0] = OMX_AUDIO_ChannelLF; 8417 map[1] = OMX_AUDIO_ChannelRF; 8418 map[2] = OMX_AUDIO_ChannelCF; 8419 break; 8420 case 4: 8421 map[0] = OMX_AUDIO_ChannelLF; 8422 map[1] = OMX_AUDIO_ChannelRF; 8423 map[2] = OMX_AUDIO_ChannelLR; 8424 map[3] = OMX_AUDIO_ChannelRR; 8425 break; 8426 case 5: 8427 map[0] = OMX_AUDIO_ChannelLF; 8428 map[1] = OMX_AUDIO_ChannelRF; 8429 map[2] = OMX_AUDIO_ChannelCF; 8430 map[3] = OMX_AUDIO_ChannelLR; 8431 map[4] = OMX_AUDIO_ChannelRR; 8432 break; 8433 case 6: 8434 map[0] = OMX_AUDIO_ChannelLF; 8435 map[1] = OMX_AUDIO_ChannelRF; 8436 map[2] = OMX_AUDIO_ChannelCF; 8437 map[3] = OMX_AUDIO_ChannelLFE; 8438 map[4] = OMX_AUDIO_ChannelLR; 8439 map[5] = OMX_AUDIO_ChannelRR; 8440 break; 8441 case 7: 8442 map[0] = OMX_AUDIO_ChannelLF; 8443 map[1] = OMX_AUDIO_ChannelRF; 8444 map[2] = OMX_AUDIO_ChannelCF; 8445 map[3] = OMX_AUDIO_ChannelLFE; 8446 map[4] = OMX_AUDIO_ChannelLR; 8447 map[5] = OMX_AUDIO_ChannelRR; 8448 map[6] = OMX_AUDIO_ChannelCS; 8449 break; 8450 case 8: 8451 map[0] = OMX_AUDIO_ChannelLF; 8452 map[1] = OMX_AUDIO_ChannelRF; 8453 map[2] = OMX_AUDIO_ChannelCF; 8454 map[3] = OMX_AUDIO_ChannelLFE; 8455 map[4] = OMX_AUDIO_ChannelLR; 8456 map[5] = OMX_AUDIO_ChannelRR; 8457 map[6] = OMX_AUDIO_ChannelLS; 8458 map[7] = OMX_AUDIO_ChannelRS; 8459 break; 8460 default: 8461 return -EINVAL; 8462 } 8463 8464 return OK; 8465} 8466 8467void ACodec::setTrebleFlag(bool trebleFlag) { 8468 mTrebleFlag = trebleFlag; 8469} 8470 8471bool ACodec::getTrebleFlag() const { 8472 return mTrebleFlag; 8473} 8474 8475} // namespace android 8476