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