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