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