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