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