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