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