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