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