ACodec.cpp revision 49b2b4d30a0f74314630a5ea5f0e59697d90443e
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 size_t offset = buffer->offset(); 5547 if (buffer->base() != info->mCodecData->base()) { 5548 ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)", 5549 mCodec->mComponentName.c_str(), 5550 bufferID, 5551 buffer->base(), info->mCodecData->base()); 5552 5553 sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput]; 5554 if (converter == NULL || isCSD) { 5555 converter = getCopyConverter(); 5556 } 5557 status_t err = converter->convert(buffer, info->mCodecData); 5558 if (err != OK) { 5559 mCodec->signalError(OMX_ErrorUndefined, err); 5560 return; 5561 } 5562 size = info->mCodecData->size(); 5563 } else { 5564 info->mCodecData->setRange(offset, size); 5565 } 5566 5567 if (flags & OMX_BUFFERFLAG_CODECCONFIG) { 5568 ALOGV("[%s] calling emptyBuffer %u w/ codec specific data", 5569 mCodec->mComponentName.c_str(), bufferID); 5570 } else if (flags & OMX_BUFFERFLAG_EOS) { 5571 ALOGV("[%s] calling emptyBuffer %u w/ EOS", 5572 mCodec->mComponentName.c_str(), bufferID); 5573 } else { 5574#if TRACK_BUFFER_TIMING 5575 ALOGI("[%s] calling emptyBuffer %u w/ time %lld us", 5576 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 5577#else 5578 ALOGV("[%s] calling emptyBuffer %u w/ time %lld us", 5579 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 5580#endif 5581 } 5582 5583#if TRACK_BUFFER_TIMING 5584 ACodec::BufferStats stats; 5585 stats.mEmptyBufferTimeUs = ALooper::GetNowUs(); 5586 stats.mFillBufferDoneTimeUs = -1ll; 5587 mCodec->mBufferStats.add(timeUs, stats); 5588#endif 5589 5590 if (mCodec->storingMetadataInDecodedBuffers()) { 5591 // try to submit an output buffer for each input buffer 5592 PortMode outputMode = getPortMode(kPortIndexOutput); 5593 5594 ALOGV("MetadataBuffersToSubmit=%u portMode=%s", 5595 mCodec->mMetadataBuffersToSubmit, 5596 (outputMode == FREE_BUFFERS ? "FREE" : 5597 outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT")); 5598 if (outputMode == RESUBMIT_BUFFERS) { 5599 mCodec->submitOutputMetadataBuffer(); 5600 } 5601 } 5602 info->checkReadFence("onInputBufferFilled"); 5603 5604 status_t err2 = OK; 5605 switch (mCodec->mPortMode[kPortIndexInput]) { 5606 case IOMX::kPortModePresetByteBuffer: 5607 case IOMX::kPortModePresetANWBuffer: 5608 case IOMX::kPortModePresetSecureBuffer: 5609 { 5610 err2 = mCodec->mOMXNode->emptyBuffer( 5611 bufferID, info->mCodecData, flags, timeUs, info->mFenceFd); 5612 } 5613 break; 5614#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 5615 case IOMX::kPortModeDynamicNativeHandle: 5616 if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) { 5617 VideoNativeHandleMetadata *vnhmd = 5618 (VideoNativeHandleMetadata*)info->mCodecData->base(); 5619 sp<NativeHandle> handle = NativeHandle::create( 5620 vnhmd->pHandle, false /* ownsHandle */); 5621 err2 = mCodec->mOMXNode->emptyBuffer( 5622 bufferID, handle, flags, timeUs, info->mFenceFd); 5623 } 5624 break; 5625 case IOMX::kPortModeDynamicANWBuffer: 5626 if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) { 5627 VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base(); 5628 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer( 5629 vnmd->pBuffer, false /* keepOwnership */); 5630 err2 = mCodec->mOMXNode->emptyBuffer( 5631 bufferID, graphicBuffer, flags, timeUs, info->mFenceFd); 5632 } 5633 break; 5634#endif 5635 default: 5636 ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode", 5637 asString(mCodec->mPortMode[kPortIndexInput]), 5638 info->mCodecData->size(), 5639 sizeof(buffer_handle_t) * 8); 5640 err2 = ERROR_UNSUPPORTED; 5641 break; 5642 } 5643 5644 info->mFenceFd = -1; 5645 if (err2 != OK) { 5646 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 5647 return; 5648 } 5649 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5650 // Hold the reference while component is using the buffer. 5651 info->mData = buffer; 5652 5653 if (!eos && err == OK) { 5654 getMoreInputDataIfPossible(); 5655 } else { 5656 ALOGV("[%s] Signalled EOS (%d) on the input port", 5657 mCodec->mComponentName.c_str(), err); 5658 5659 mCodec->mPortEOS[kPortIndexInput] = true; 5660 mCodec->mInputEOSResult = err; 5661 } 5662 } else if (!mCodec->mPortEOS[kPortIndexInput]) { 5663 if (err != OK && err != ERROR_END_OF_STREAM) { 5664 ALOGV("[%s] Signalling EOS on the input port due to error %d", 5665 mCodec->mComponentName.c_str(), err); 5666 } else { 5667 ALOGV("[%s] Signalling EOS on the input port", 5668 mCodec->mComponentName.c_str()); 5669 } 5670 5671 ALOGV("[%s] calling emptyBuffer %u signalling EOS", 5672 mCodec->mComponentName.c_str(), bufferID); 5673 5674 info->checkReadFence("onInputBufferFilled"); 5675 status_t err2 = mCodec->mOMXNode->emptyBuffer( 5676 bufferID, OMXBuffer::sPreset, OMX_BUFFERFLAG_EOS, 0, info->mFenceFd); 5677 info->mFenceFd = -1; 5678 if (err2 != OK) { 5679 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 5680 return; 5681 } 5682 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5683 5684 mCodec->mPortEOS[kPortIndexInput] = true; 5685 mCodec->mInputEOSResult = err; 5686 } 5687 break; 5688 } 5689 5690 case FREE_BUFFERS: 5691 break; 5692 5693 default: 5694 ALOGE("invalid port mode: %d", mode); 5695 break; 5696 } 5697} 5698 5699void ACodec::BaseState::getMoreInputDataIfPossible() { 5700 if (mCodec->mPortEOS[kPortIndexInput]) { 5701 return; 5702 } 5703 5704 BufferInfo *eligible = NULL; 5705 5706 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 5707 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 5708 5709#if 0 5710 if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 5711 // There's already a "read" pending. 5712 return; 5713 } 5714#endif 5715 5716 if (info->mStatus == BufferInfo::OWNED_BY_US) { 5717 eligible = info; 5718 } 5719 } 5720 5721 if (eligible == NULL) { 5722 return; 5723 } 5724 5725 postFillThisBuffer(eligible); 5726} 5727 5728bool ACodec::BaseState::onOMXFillBufferDone( 5729 IOMX::buffer_id bufferID, 5730 size_t rangeOffset, size_t rangeLength, 5731 OMX_U32 flags, 5732 int64_t timeUs, 5733 int fenceFd) { 5734 ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x", 5735 mCodec->mComponentName.c_str(), bufferID, timeUs, flags); 5736 5737 ssize_t index; 5738 status_t err= OK; 5739 5740#if TRACK_BUFFER_TIMING 5741 index = mCodec->mBufferStats.indexOfKey(timeUs); 5742 if (index >= 0) { 5743 ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index); 5744 stats->mFillBufferDoneTimeUs = ALooper::GetNowUs(); 5745 5746 ALOGI("frame PTS %lld: %lld", 5747 timeUs, 5748 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs); 5749 5750 mCodec->mBufferStats.removeItemsAt(index); 5751 stats = NULL; 5752 } 5753#endif 5754 5755 BufferInfo *info = 5756 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 5757 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5758 if (status != BufferInfo::OWNED_BY_COMPONENT) { 5759 ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5760 mCodec->dumpBuffers(kPortIndexOutput); 5761 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5762 if (fenceFd >= 0) { 5763 ::close(fenceFd); 5764 } 5765 return true; 5766 } 5767 5768 info->mDequeuedAt = ++mCodec->mDequeueCounter; 5769 info->mStatus = BufferInfo::OWNED_BY_US; 5770 5771 if (info->mRenderInfo != NULL) { 5772 // The fence for an emptied buffer must have signaled, but there still could be queued 5773 // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these, 5774 // as we will soon requeue this buffer to the surface. While in theory we could still keep 5775 // track of buffers that are requeued to the surface, it is better to add support to the 5776 // buffer-queue to notify us of released buffers and their fences (in the future). 5777 mCodec->notifyOfRenderedFrames(true /* dropIncomplete */); 5778 } 5779 5780 // byte buffers cannot take fences, so wait for any fence now 5781 if (mCodec->mNativeWindow == NULL) { 5782 (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone"); 5783 fenceFd = -1; 5784 } 5785 info->setReadFence(fenceFd, "onOMXFillBufferDone"); 5786 5787 PortMode mode = getPortMode(kPortIndexOutput); 5788 5789 switch (mode) { 5790 case KEEP_BUFFERS: 5791 break; 5792 5793 case RESUBMIT_BUFFERS: 5794 { 5795 if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS) 5796 || mCodec->mPortEOS[kPortIndexOutput])) { 5797 ALOGV("[%s] calling fillBuffer %u", 5798 mCodec->mComponentName.c_str(), info->mBufferID); 5799 5800 err = mCodec->fillBuffer(info); 5801 if (err != OK) { 5802 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5803 return true; 5804 } 5805 break; 5806 } 5807 5808 sp<MediaCodecBuffer> buffer = info->mData; 5809 5810 if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) { 5811 // pretend that output format has changed on the first frame (we used to do this) 5812 if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) { 5813 mCodec->onOutputFormatChanged(mCodec->mOutputFormat); 5814 } 5815 mCodec->sendFormatChange(); 5816 } 5817 buffer->setFormat(mCodec->mOutputFormat); 5818 5819 if (mCodec->usingSecureBufferOnEncoderOutput()) { 5820 native_handle_t *handle = NULL; 5821 sp<SecureBuffer> secureBuffer = static_cast<SecureBuffer *>(buffer.get()); 5822 if (secureBuffer != NULL) { 5823#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 5824 // handle is only valid on 32-bit/mediaserver process 5825 handle = NULL; 5826#else 5827 handle = (native_handle_t *)secureBuffer->getDestinationPointer(); 5828#endif 5829 } 5830 buffer->meta()->setPointer("handle", handle); 5831 buffer->meta()->setInt32("rangeOffset", rangeOffset); 5832 buffer->meta()->setInt32("rangeLength", rangeLength); 5833 } else if (buffer->base() == info->mCodecData->base()) { 5834 buffer->setRange(rangeOffset, rangeLength); 5835 } else { 5836 info->mCodecData->setRange(rangeOffset, rangeLength); 5837 // in this case we know that mConverter is not null 5838 status_t err = mCodec->mConverter[kPortIndexOutput]->convert( 5839 info->mCodecData, buffer); 5840 if (err != OK) { 5841 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5842 return true; 5843 } 5844 } 5845#if 0 5846 if (mCodec->mNativeWindow == NULL) { 5847 if (IsIDR(info->mData)) { 5848 ALOGI("IDR frame"); 5849 } 5850 } 5851#endif 5852 5853 if (mCodec->mSkipCutBuffer != NULL) { 5854 mCodec->mSkipCutBuffer->submit(buffer); 5855 } 5856 buffer->meta()->setInt64("timeUs", timeUs); 5857 5858 info->mData.clear(); 5859 5860 mCodec->mBufferChannel->drainThisBuffer(info->mBufferID, flags); 5861 5862 info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 5863 5864 if (flags & OMX_BUFFERFLAG_EOS) { 5865 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str()); 5866 5867 mCodec->mCallback->onEos(mCodec->mInputEOSResult); 5868 mCodec->mPortEOS[kPortIndexOutput] = true; 5869 } 5870 break; 5871 } 5872 5873 case FREE_BUFFERS: 5874 err = mCodec->freeBuffer(kPortIndexOutput, index); 5875 if (err != OK) { 5876 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5877 return true; 5878 } 5879 break; 5880 5881 default: 5882 ALOGE("Invalid port mode: %d", mode); 5883 return false; 5884 } 5885 5886 return true; 5887} 5888 5889void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 5890 IOMX::buffer_id bufferID; 5891 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 5892 sp<RefBase> obj; 5893 CHECK(msg->findObject("buffer", &obj)); 5894 sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get()); 5895 int32_t discarded = 0; 5896 msg->findInt32("discarded", &discarded); 5897 5898 ssize_t index; 5899 BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 5900 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5901 if (status != BufferInfo::OWNED_BY_DOWNSTREAM) { 5902 ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5903 mCodec->dumpBuffers(kPortIndexOutput); 5904 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5905 return; 5906 } 5907 info->mData = buffer; 5908 int32_t render; 5909 if (mCodec->mNativeWindow != NULL 5910 && msg->findInt32("render", &render) && render != 0 5911 && !discarded && buffer->size() != 0) { 5912 ATRACE_NAME("render"); 5913 // The client wants this buffer to be rendered. 5914 5915 android_native_rect_t crop; 5916 if (buffer->format()->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) { 5917 // NOTE: native window uses extended right-bottom coordinate 5918 ++crop.right; 5919 ++crop.bottom; 5920 if (memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) { 5921 mCodec->mLastNativeWindowCrop = crop; 5922 status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop); 5923 ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err); 5924 } 5925 } 5926 5927 int32_t dataSpace; 5928 if (buffer->format()->findInt32("android._dataspace", &dataSpace) 5929 && dataSpace != mCodec->mLastNativeWindowDataSpace) { 5930 status_t err = native_window_set_buffers_data_space( 5931 mCodec->mNativeWindow.get(), (android_dataspace)dataSpace); 5932 mCodec->mLastNativeWindowDataSpace = dataSpace; 5933 ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err); 5934 } 5935 5936 // save buffers sent to the surface so we can get render time when they return 5937 int64_t mediaTimeUs = -1; 5938 buffer->meta()->findInt64("timeUs", &mediaTimeUs); 5939 if (mediaTimeUs >= 0) { 5940 mCodec->mRenderTracker.onFrameQueued( 5941 mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd))); 5942 } 5943 5944 int64_t timestampNs = 0; 5945 if (!msg->findInt64("timestampNs", ×tampNs)) { 5946 // use media timestamp if client did not request a specific render timestamp 5947 if (buffer->meta()->findInt64("timeUs", ×tampNs)) { 5948 ALOGV("using buffer PTS of %lld", (long long)timestampNs); 5949 timestampNs *= 1000; 5950 } 5951 } 5952 5953 status_t err; 5954 err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs); 5955 ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err); 5956 5957 info->checkReadFence("onOutputBufferDrained before queueBuffer"); 5958 err = mCodec->mNativeWindow->queueBuffer( 5959 mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd); 5960 info->mFenceFd = -1; 5961 if (err == OK) { 5962 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 5963 } else { 5964 ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err); 5965 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5966 info->mStatus = BufferInfo::OWNED_BY_US; 5967 // keeping read fence as write fence to avoid clobbering 5968 info->mIsReadFence = false; 5969 } 5970 } else { 5971 if (mCodec->mNativeWindow != NULL && (discarded || buffer->size() != 0)) { 5972 // move read fence into write fence to avoid clobbering 5973 info->mIsReadFence = false; 5974 ATRACE_NAME("frame-drop"); 5975 } 5976 info->mStatus = BufferInfo::OWNED_BY_US; 5977 } 5978 5979 PortMode mode = getPortMode(kPortIndexOutput); 5980 5981 switch (mode) { 5982 case KEEP_BUFFERS: 5983 { 5984 // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 5985 5986 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 5987 // We cannot resubmit the buffer we just rendered, dequeue 5988 // the spare instead. 5989 5990 info = mCodec->dequeueBufferFromNativeWindow(); 5991 } 5992 break; 5993 } 5994 5995 case RESUBMIT_BUFFERS: 5996 { 5997 if (!mCodec->mPortEOS[kPortIndexOutput]) { 5998 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 5999 // We cannot resubmit the buffer we just rendered, dequeue 6000 // the spare instead. 6001 6002 info = mCodec->dequeueBufferFromNativeWindow(); 6003 } 6004 6005 if (info != NULL) { 6006 ALOGV("[%s] calling fillBuffer %u", 6007 mCodec->mComponentName.c_str(), info->mBufferID); 6008 info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS"); 6009 status_t err = mCodec->fillBuffer(info); 6010 if (err != OK) { 6011 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6012 } 6013 } 6014 } 6015 break; 6016 } 6017 6018 case FREE_BUFFERS: 6019 { 6020 status_t err = mCodec->freeBuffer(kPortIndexOutput, index); 6021 if (err != OK) { 6022 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6023 } 6024 break; 6025 } 6026 6027 default: 6028 ALOGE("Invalid port mode: %d", mode); 6029 return; 6030 } 6031} 6032 6033//////////////////////////////////////////////////////////////////////////////// 6034 6035ACodec::UninitializedState::UninitializedState(ACodec *codec) 6036 : BaseState(codec) { 6037} 6038 6039void ACodec::UninitializedState::stateEntered() { 6040 ALOGV("Now uninitialized"); 6041 6042 if (mDeathNotifier != NULL) { 6043 if (mCodec->mOMXNode != NULL) { 6044 sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode); 6045 binder->unlinkToDeath(mDeathNotifier); 6046 } 6047 mDeathNotifier.clear(); 6048 } 6049 6050 mCodec->mUsingNativeWindow = false; 6051 mCodec->mNativeWindow.clear(); 6052 mCodec->mNativeWindowUsageBits = 0; 6053 mCodec->mOMX.clear(); 6054 mCodec->mOMXNode.clear(); 6055 mCodec->mFlags = 0; 6056 mCodec->mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer; 6057 mCodec->mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer; 6058 mCodec->mConverter[0].clear(); 6059 mCodec->mConverter[1].clear(); 6060 mCodec->mComponentName.clear(); 6061} 6062 6063bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 6064 bool handled = false; 6065 6066 switch (msg->what()) { 6067 case ACodec::kWhatSetup: 6068 { 6069 onSetup(msg); 6070 6071 handled = true; 6072 break; 6073 } 6074 6075 case ACodec::kWhatAllocateComponent: 6076 { 6077 onAllocateComponent(msg); 6078 handled = true; 6079 break; 6080 } 6081 6082 case ACodec::kWhatShutdown: 6083 { 6084 int32_t keepComponentAllocated; 6085 CHECK(msg->findInt32( 6086 "keepComponentAllocated", &keepComponentAllocated)); 6087 ALOGW_IF(keepComponentAllocated, 6088 "cannot keep component allocated on shutdown in Uninitialized state"); 6089 if (keepComponentAllocated) { 6090 mCodec->mCallback->onStopCompleted(); 6091 } else { 6092 mCodec->mCallback->onReleaseCompleted(); 6093 } 6094 handled = true; 6095 break; 6096 } 6097 6098 case ACodec::kWhatFlush: 6099 { 6100 mCodec->mCallback->onFlushCompleted(); 6101 handled = true; 6102 break; 6103 } 6104 6105 case ACodec::kWhatReleaseCodecInstance: 6106 { 6107 // nothing to do, as we have already signaled shutdown 6108 handled = true; 6109 break; 6110 } 6111 6112 default: 6113 return BaseState::onMessageReceived(msg); 6114 } 6115 6116 return handled; 6117} 6118 6119void ACodec::UninitializedState::onSetup( 6120 const sp<AMessage> &msg) { 6121 if (onAllocateComponent(msg) 6122 && mCodec->mLoadedState->onConfigureComponent(msg)) { 6123 mCodec->mLoadedState->onStart(); 6124 } 6125} 6126 6127bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { 6128 ALOGV("onAllocateComponent"); 6129 6130 CHECK(mCodec->mOMXNode == NULL); 6131 6132 OMXClient client; 6133 if (client.connect() != OK) { 6134 mCodec->signalError(OMX_ErrorUndefined, NO_INIT); 6135 return false; 6136 } 6137 6138 sp<IOMX> omx = client.interface(); 6139 6140 sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec); 6141 6142 Vector<AString> matchingCodecs; 6143 6144 AString mime; 6145 6146 AString componentName; 6147 uint32_t quirks = 0; 6148 int32_t encoder = false; 6149 if (msg->findString("componentName", &componentName)) { 6150 sp<IMediaCodecList> list = MediaCodecList::getInstance(); 6151 if (list != NULL && list->findCodecByName(componentName.c_str()) >= 0) { 6152 matchingCodecs.add(componentName); 6153 } 6154 } else { 6155 CHECK(msg->findString("mime", &mime)); 6156 6157 if (!msg->findInt32("encoder", &encoder)) { 6158 encoder = false; 6159 } 6160 6161 MediaCodecList::findMatchingCodecs( 6162 mime.c_str(), 6163 encoder, // createEncoder 6164 0, // flags 6165 &matchingCodecs); 6166 } 6167 6168 sp<CodecObserver> observer = new CodecObserver; 6169 sp<IOMXNode> omxNode; 6170 6171 status_t err = NAME_NOT_FOUND; 6172 for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); 6173 ++matchIndex) { 6174 componentName = matchingCodecs[matchIndex]; 6175 quirks = MediaCodecList::getQuirksFor(componentName.c_str()); 6176 6177 pid_t tid = gettid(); 6178 int prevPriority = androidGetThreadPriority(tid); 6179 androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); 6180 err = omx->allocateNode(componentName.c_str(), observer, &omxNode); 6181 androidSetThreadPriority(tid, prevPriority); 6182 6183 if (err == OK) { 6184 break; 6185 } else { 6186 ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str()); 6187 } 6188 6189 omxNode = NULL; 6190 } 6191 6192 if (omxNode == NULL) { 6193 if (!mime.empty()) { 6194 ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.", 6195 encoder ? "en" : "de", mime.c_str(), err); 6196 } else { 6197 ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err); 6198 } 6199 6200 mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err)); 6201 return false; 6202 } 6203 6204 mDeathNotifier = new DeathNotifier(notify); 6205 if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) { 6206 // This was a local binder, if it dies so do we, we won't care 6207 // about any notifications in the afterlife. 6208 mDeathNotifier.clear(); 6209 } 6210 6211 notify = new AMessage(kWhatOMXMessageList, mCodec); 6212 notify->setInt32("generation", ++mCodec->mNodeGeneration); 6213 observer->setNotificationMessage(notify); 6214 6215 mCodec->mComponentName = componentName; 6216 mCodec->mRenderTracker.setComponentName(componentName); 6217 mCodec->mFlags = 0; 6218 6219 if (componentName.endsWith(".secure")) { 6220 mCodec->mFlags |= kFlagIsSecure; 6221 mCodec->mFlags |= kFlagIsGrallocUsageProtected; 6222 mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 6223 } 6224 6225 omxNode->setQuirks(quirks); 6226 mCodec->mOMX = omx; 6227 mCodec->mOMXNode = omxNode; 6228 mCodec->mCallback->onComponentAllocated(mCodec->mComponentName.c_str()); 6229 mCodec->changeState(mCodec->mLoadedState); 6230 6231 return true; 6232} 6233 6234//////////////////////////////////////////////////////////////////////////////// 6235 6236ACodec::LoadedState::LoadedState(ACodec *codec) 6237 : BaseState(codec) { 6238} 6239 6240void ACodec::LoadedState::stateEntered() { 6241 ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 6242 6243 mCodec->mPortEOS[kPortIndexInput] = 6244 mCodec->mPortEOS[kPortIndexOutput] = false; 6245 6246 mCodec->mInputEOSResult = OK; 6247 6248 mCodec->mDequeueCounter = 0; 6249 mCodec->mMetadataBuffersToSubmit = 0; 6250 mCodec->mRepeatFrameDelayUs = -1ll; 6251 mCodec->mInputFormat.clear(); 6252 mCodec->mOutputFormat.clear(); 6253 mCodec->mBaseOutputFormat.clear(); 6254 mCodec->mGraphicBufferSource.clear(); 6255 6256 if (mCodec->mShutdownInProgress) { 6257 bool keepComponentAllocated = mCodec->mKeepComponentAllocated; 6258 6259 mCodec->mShutdownInProgress = false; 6260 mCodec->mKeepComponentAllocated = false; 6261 6262 onShutdown(keepComponentAllocated); 6263 } 6264 mCodec->mExplicitShutdown = false; 6265 6266 mCodec->processDeferredMessages(); 6267} 6268 6269void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) { 6270 if (!keepComponentAllocated) { 6271 (void)mCodec->mOMXNode->freeNode(); 6272 6273 mCodec->changeState(mCodec->mUninitializedState); 6274 } 6275 6276 if (mCodec->mExplicitShutdown) { 6277 if (keepComponentAllocated) { 6278 mCodec->mCallback->onStopCompleted(); 6279 } else { 6280 mCodec->mCallback->onReleaseCompleted(); 6281 } 6282 mCodec->mExplicitShutdown = false; 6283 } 6284} 6285 6286bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) { 6287 bool handled = false; 6288 6289 switch (msg->what()) { 6290 case ACodec::kWhatConfigureComponent: 6291 { 6292 onConfigureComponent(msg); 6293 handled = true; 6294 break; 6295 } 6296 6297 case ACodec::kWhatCreateInputSurface: 6298 { 6299 onCreateInputSurface(msg); 6300 handled = true; 6301 break; 6302 } 6303 6304 case ACodec::kWhatSetInputSurface: 6305 { 6306 onSetInputSurface(msg); 6307 handled = true; 6308 break; 6309 } 6310 6311 case ACodec::kWhatStart: 6312 { 6313 onStart(); 6314 handled = true; 6315 break; 6316 } 6317 6318 case ACodec::kWhatShutdown: 6319 { 6320 int32_t keepComponentAllocated; 6321 CHECK(msg->findInt32( 6322 "keepComponentAllocated", &keepComponentAllocated)); 6323 6324 mCodec->mExplicitShutdown = true; 6325 onShutdown(keepComponentAllocated); 6326 6327 handled = true; 6328 break; 6329 } 6330 6331 case ACodec::kWhatFlush: 6332 { 6333 mCodec->mCallback->onFlushCompleted(); 6334 handled = true; 6335 break; 6336 } 6337 6338 default: 6339 return BaseState::onMessageReceived(msg); 6340 } 6341 6342 return handled; 6343} 6344 6345bool ACodec::LoadedState::onConfigureComponent( 6346 const sp<AMessage> &msg) { 6347 ALOGV("onConfigureComponent"); 6348 6349 CHECK(mCodec->mOMXNode != NULL); 6350 6351 status_t err = OK; 6352 AString mime; 6353 if (!msg->findString("mime", &mime)) { 6354 err = BAD_VALUE; 6355 } else { 6356 err = mCodec->configureCodec(mime.c_str(), msg); 6357 } 6358 if (err != OK) { 6359 ALOGE("[%s] configureCodec returning error %d", 6360 mCodec->mComponentName.c_str(), err); 6361 6362 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6363 return false; 6364 } 6365 6366 mCodec->mCallback->onComponentConfigured(mCodec->mInputFormat, mCodec->mOutputFormat); 6367 6368 return true; 6369} 6370 6371status_t ACodec::LoadedState::setupInputSurface() { 6372 if (mCodec->mGraphicBufferSource == NULL) { 6373 return BAD_VALUE; 6374 } 6375 6376 android_dataspace dataSpace; 6377 status_t err = 6378 mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace); 6379 if (err != OK) { 6380 ALOGE("Failed to get default data space"); 6381 return err; 6382 } 6383 6384 err = statusFromBinderStatus( 6385 mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace)); 6386 if (err != OK) { 6387 ALOGE("[%s] Unable to configure for node (err %d)", 6388 mCodec->mComponentName.c_str(), err); 6389 return err; 6390 } 6391 6392 if (mCodec->mRepeatFrameDelayUs > 0ll) { 6393 err = statusFromBinderStatus( 6394 mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs( 6395 mCodec->mRepeatFrameDelayUs)); 6396 6397 if (err != OK) { 6398 ALOGE("[%s] Unable to configure option to repeat previous " 6399 "frames (err %d)", 6400 mCodec->mComponentName.c_str(), err); 6401 return err; 6402 } 6403 } 6404 6405 if (mCodec->mMaxPtsGapUs > 0ll) { 6406 OMX_PARAM_U32TYPE maxPtsGapParams; 6407 InitOMXParams(&maxPtsGapParams); 6408 maxPtsGapParams.nPortIndex = kPortIndexInput; 6409 maxPtsGapParams.nU32 = (uint32_t) mCodec->mMaxPtsGapUs; 6410 6411 err = mCodec->mOMXNode->setParameter( 6412 (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl, 6413 &maxPtsGapParams, sizeof(maxPtsGapParams)); 6414 6415 if (err != OK) { 6416 ALOGE("[%s] Unable to configure max timestamp gap (err %d)", 6417 mCodec->mComponentName.c_str(), err); 6418 return err; 6419 } 6420 } 6421 6422 if (mCodec->mMaxFps > 0) { 6423 err = statusFromBinderStatus( 6424 mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps)); 6425 6426 if (err != OK) { 6427 ALOGE("[%s] Unable to configure max fps (err %d)", 6428 mCodec->mComponentName.c_str(), err); 6429 return err; 6430 } 6431 } 6432 6433 if (mCodec->mTimePerCaptureUs > 0ll 6434 && mCodec->mTimePerFrameUs > 0ll) { 6435 err = statusFromBinderStatus( 6436 mCodec->mGraphicBufferSource->setTimeLapseConfig( 6437 mCodec->mTimePerFrameUs, mCodec->mTimePerCaptureUs)); 6438 6439 if (err != OK) { 6440 ALOGE("[%s] Unable to configure time lapse (err %d)", 6441 mCodec->mComponentName.c_str(), err); 6442 return err; 6443 } 6444 } 6445 6446 if (mCodec->mCreateInputBuffersSuspended) { 6447 err = statusFromBinderStatus( 6448 mCodec->mGraphicBufferSource->setSuspend(true)); 6449 6450 if (err != OK) { 6451 ALOGE("[%s] Unable to configure option to suspend (err %d)", 6452 mCodec->mComponentName.c_str(), err); 6453 return err; 6454 } 6455 } 6456 6457 uint32_t usageBits; 6458 if (mCodec->mOMXNode->getParameter( 6459 (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, 6460 &usageBits, sizeof(usageBits)) == OK) { 6461 mCodec->mInputFormat->setInt32( 6462 "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN)); 6463 } 6464 6465 sp<ABuffer> colorAspectsBuffer; 6466 if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) { 6467 if (colorAspectsBuffer->size() != sizeof(ColorAspects)) { 6468 return INVALID_OPERATION; 6469 } 6470 6471 err = statusFromBinderStatus( 6472 mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32( 6473 *(ColorAspects *)colorAspectsBuffer->base()))); 6474 6475 if (err != OK) { 6476 ALOGE("[%s] Unable to configure color aspects (err %d)", 6477 mCodec->mComponentName.c_str(), err); 6478 return err; 6479 } 6480 } 6481 return OK; 6482} 6483 6484void ACodec::LoadedState::onCreateInputSurface( 6485 const sp<AMessage> & /* msg */) { 6486 ALOGV("onCreateInputSurface"); 6487 6488 sp<IGraphicBufferProducer> bufferProducer; 6489 status_t err = mCodec->mOMX->createInputSurface( 6490 &bufferProducer, &mCodec->mGraphicBufferSource); 6491 6492 if (err == OK) { 6493 err = setupInputSurface(); 6494 } 6495 6496 if (err == OK) { 6497 mCodec->mCallback->onInputSurfaceCreated( 6498 mCodec->mInputFormat, 6499 mCodec->mOutputFormat, 6500 new BufferProducerWrapper(bufferProducer)); 6501 } else { 6502 // Can't use mCodec->signalError() here -- MediaCodec won't forward 6503 // the error through because it's in the "configured" state. We 6504 // send a kWhatInputSurfaceCreated with an error value instead. 6505 ALOGE("[%s] onCreateInputSurface returning error %d", 6506 mCodec->mComponentName.c_str(), err); 6507 mCodec->mCallback->onInputSurfaceCreationFailed(err); 6508 } 6509} 6510 6511void ACodec::LoadedState::onSetInputSurface(const sp<AMessage> &msg) { 6512 ALOGV("onSetInputSurface"); 6513 6514 sp<RefBase> obj; 6515 CHECK(msg->findObject("input-surface", &obj)); 6516 sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get()); 6517 mCodec->mGraphicBufferSource = surface->getBufferSource(); 6518 6519 status_t err = setupInputSurface(); 6520 6521 if (err == OK) { 6522 mCodec->mCallback->onInputSurfaceAccepted( 6523 mCodec->mInputFormat, mCodec->mOutputFormat); 6524 } else { 6525 // Can't use mCodec->signalError() here -- MediaCodec won't forward 6526 // the error through because it's in the "configured" state. We 6527 // send a kWhatInputSurfaceAccepted with an error value instead. 6528 ALOGE("[%s] onSetInputSurface returning error %d", 6529 mCodec->mComponentName.c_str(), err); 6530 mCodec->mCallback->onInputSurfaceDeclined(err); 6531 } 6532} 6533 6534void ACodec::LoadedState::onStart() { 6535 ALOGV("onStart"); 6536 6537 status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle); 6538 if (err != OK) { 6539 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6540 } else { 6541 mCodec->changeState(mCodec->mLoadedToIdleState); 6542 } 6543} 6544 6545//////////////////////////////////////////////////////////////////////////////// 6546 6547ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 6548 : BaseState(codec) { 6549} 6550 6551void ACodec::LoadedToIdleState::stateEntered() { 6552 ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 6553 6554 status_t err; 6555 if ((err = allocateBuffers()) != OK) { 6556 ALOGE("Failed to allocate buffers after transitioning to IDLE state " 6557 "(error 0x%08x)", 6558 err); 6559 6560 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6561 6562 mCodec->mOMXNode->sendCommand( 6563 OMX_CommandStateSet, OMX_StateLoaded); 6564 if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) { 6565 mCodec->freeBuffersOnPort(kPortIndexInput); 6566 } 6567 if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) { 6568 mCodec->freeBuffersOnPort(kPortIndexOutput); 6569 } 6570 6571 mCodec->changeState(mCodec->mLoadedState); 6572 } 6573} 6574 6575status_t ACodec::LoadedToIdleState::allocateBuffers() { 6576 status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 6577 if (err != OK) { 6578 return err; 6579 } 6580 6581 err = mCodec->allocateBuffersOnPort(kPortIndexOutput); 6582 if (err != OK) { 6583 return err; 6584 } 6585 6586 mCodec->mCallback->onStartCompleted(); 6587 6588 return OK; 6589} 6590 6591bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 6592 switch (msg->what()) { 6593 case kWhatSetParameters: 6594 case kWhatShutdown: 6595 { 6596 mCodec->deferMessage(msg); 6597 return true; 6598 } 6599 6600 case kWhatSignalEndOfInputStream: 6601 { 6602 mCodec->onSignalEndOfInputStream(); 6603 return true; 6604 } 6605 6606 case kWhatResume: 6607 { 6608 // We'll be active soon enough. 6609 return true; 6610 } 6611 6612 case kWhatFlush: 6613 { 6614 // We haven't even started yet, so we're flushed alright... 6615 mCodec->mCallback->onFlushCompleted(); 6616 return true; 6617 } 6618 6619 default: 6620 return BaseState::onMessageReceived(msg); 6621 } 6622} 6623 6624bool ACodec::LoadedToIdleState::onOMXEvent( 6625 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6626 switch (event) { 6627 case OMX_EventCmdComplete: 6628 { 6629 status_t err = OK; 6630 if (data1 != (OMX_U32)OMX_CommandStateSet 6631 || data2 != (OMX_U32)OMX_StateIdle) { 6632 ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)", 6633 asString((OMX_COMMANDTYPE)data1), data1, 6634 asString((OMX_STATETYPE)data2), data2); 6635 err = FAILED_TRANSACTION; 6636 } 6637 6638 if (err == OK) { 6639 err = mCodec->mOMXNode->sendCommand( 6640 OMX_CommandStateSet, OMX_StateExecuting); 6641 } 6642 6643 if (err != OK) { 6644 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6645 } else { 6646 mCodec->changeState(mCodec->mIdleToExecutingState); 6647 } 6648 6649 return true; 6650 } 6651 6652 default: 6653 return BaseState::onOMXEvent(event, data1, data2); 6654 } 6655} 6656 6657//////////////////////////////////////////////////////////////////////////////// 6658 6659ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 6660 : BaseState(codec) { 6661} 6662 6663void ACodec::IdleToExecutingState::stateEntered() { 6664 ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 6665} 6666 6667bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 6668 switch (msg->what()) { 6669 case kWhatSetParameters: 6670 case kWhatShutdown: 6671 { 6672 mCodec->deferMessage(msg); 6673 return true; 6674 } 6675 6676 case kWhatResume: 6677 { 6678 // We'll be active soon enough. 6679 return true; 6680 } 6681 6682 case kWhatFlush: 6683 { 6684 // We haven't even started yet, so we're flushed alright... 6685 mCodec->mCallback->onFlushCompleted(); 6686 return true; 6687 } 6688 6689 case kWhatSignalEndOfInputStream: 6690 { 6691 mCodec->onSignalEndOfInputStream(); 6692 return true; 6693 } 6694 6695 default: 6696 return BaseState::onMessageReceived(msg); 6697 } 6698} 6699 6700bool ACodec::IdleToExecutingState::onOMXEvent( 6701 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6702 switch (event) { 6703 case OMX_EventCmdComplete: 6704 { 6705 if (data1 != (OMX_U32)OMX_CommandStateSet 6706 || data2 != (OMX_U32)OMX_StateExecuting) { 6707 ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)", 6708 asString((OMX_COMMANDTYPE)data1), data1, 6709 asString((OMX_STATETYPE)data2), data2); 6710 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6711 return true; 6712 } 6713 6714 mCodec->mExecutingState->resume(); 6715 mCodec->changeState(mCodec->mExecutingState); 6716 6717 return true; 6718 } 6719 6720 default: 6721 return BaseState::onOMXEvent(event, data1, data2); 6722 } 6723} 6724 6725//////////////////////////////////////////////////////////////////////////////// 6726 6727ACodec::ExecutingState::ExecutingState(ACodec *codec) 6728 : BaseState(codec), 6729 mActive(false) { 6730} 6731 6732ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 6733 OMX_U32 /* portIndex */) { 6734 return RESUBMIT_BUFFERS; 6735} 6736 6737void ACodec::ExecutingState::submitOutputMetaBuffers() { 6738 // submit as many buffers as there are input buffers with the codec 6739 // in case we are in port reconfiguring 6740 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 6741 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 6742 6743 if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) { 6744 if (mCodec->submitOutputMetadataBuffer() != OK) 6745 break; 6746 } 6747 } 6748 6749 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 6750 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 6751} 6752 6753void ACodec::ExecutingState::submitRegularOutputBuffers() { 6754 bool failed = false; 6755 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 6756 BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 6757 6758 if (mCodec->mNativeWindow != NULL) { 6759 if (info->mStatus != BufferInfo::OWNED_BY_US 6760 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6761 ALOGE("buffers should be owned by us or the surface"); 6762 failed = true; 6763 break; 6764 } 6765 6766 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6767 continue; 6768 } 6769 } else { 6770 if (info->mStatus != BufferInfo::OWNED_BY_US) { 6771 ALOGE("buffers should be owned by us"); 6772 failed = true; 6773 break; 6774 } 6775 } 6776 6777 ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID); 6778 6779 info->checkWriteFence("submitRegularOutputBuffers"); 6780 status_t err = mCodec->fillBuffer(info); 6781 if (err != OK) { 6782 failed = true; 6783 break; 6784 } 6785 } 6786 6787 if (failed) { 6788 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6789 } 6790} 6791 6792void ACodec::ExecutingState::submitOutputBuffers() { 6793 submitRegularOutputBuffers(); 6794 if (mCodec->storingMetadataInDecodedBuffers()) { 6795 submitOutputMetaBuffers(); 6796 } 6797} 6798 6799void ACodec::ExecutingState::resume() { 6800 if (mActive) { 6801 ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str()); 6802 return; 6803 } 6804 6805 submitOutputBuffers(); 6806 6807 // Post all available input buffers 6808 if (mCodec->mBuffers[kPortIndexInput].size() == 0u) { 6809 ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str()); 6810 } 6811 6812 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) { 6813 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 6814 if (info->mStatus == BufferInfo::OWNED_BY_US) { 6815 postFillThisBuffer(info); 6816 } 6817 } 6818 6819 mActive = true; 6820} 6821 6822void ACodec::ExecutingState::stateEntered() { 6823 ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 6824 6825 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 6826 mCodec->processDeferredMessages(); 6827} 6828 6829bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 6830 bool handled = false; 6831 6832 switch (msg->what()) { 6833 case kWhatShutdown: 6834 { 6835 int32_t keepComponentAllocated; 6836 CHECK(msg->findInt32( 6837 "keepComponentAllocated", &keepComponentAllocated)); 6838 6839 mCodec->mShutdownInProgress = true; 6840 mCodec->mExplicitShutdown = true; 6841 mCodec->mKeepComponentAllocated = keepComponentAllocated; 6842 6843 mActive = false; 6844 6845 status_t err = mCodec->mOMXNode->sendCommand( 6846 OMX_CommandStateSet, OMX_StateIdle); 6847 if (err != OK) { 6848 if (keepComponentAllocated) { 6849 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6850 } 6851 // TODO: do some recovery here. 6852 } else { 6853 mCodec->changeState(mCodec->mExecutingToIdleState); 6854 } 6855 6856 handled = true; 6857 break; 6858 } 6859 6860 case kWhatFlush: 6861 { 6862 ALOGV("[%s] ExecutingState flushing now " 6863 "(codec owns %zu/%zu input, %zu/%zu output).", 6864 mCodec->mComponentName.c_str(), 6865 mCodec->countBuffersOwnedByComponent(kPortIndexInput), 6866 mCodec->mBuffers[kPortIndexInput].size(), 6867 mCodec->countBuffersOwnedByComponent(kPortIndexOutput), 6868 mCodec->mBuffers[kPortIndexOutput].size()); 6869 6870 mActive = false; 6871 6872 status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL); 6873 if (err != OK) { 6874 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6875 } else { 6876 mCodec->changeState(mCodec->mFlushingState); 6877 } 6878 6879 handled = true; 6880 break; 6881 } 6882 6883 case kWhatResume: 6884 { 6885 resume(); 6886 6887 handled = true; 6888 break; 6889 } 6890 6891 case kWhatRequestIDRFrame: 6892 { 6893 status_t err = mCodec->requestIDRFrame(); 6894 if (err != OK) { 6895 ALOGW("Requesting an IDR frame failed."); 6896 } 6897 6898 handled = true; 6899 break; 6900 } 6901 6902 case kWhatSetParameters: 6903 { 6904 sp<AMessage> params; 6905 CHECK(msg->findMessage("params", ¶ms)); 6906 6907 status_t err = mCodec->setParameters(params); 6908 6909 sp<AMessage> reply; 6910 if (msg->findMessage("reply", &reply)) { 6911 reply->setInt32("err", err); 6912 reply->post(); 6913 } 6914 6915 handled = true; 6916 break; 6917 } 6918 6919 case ACodec::kWhatSignalEndOfInputStream: 6920 { 6921 mCodec->onSignalEndOfInputStream(); 6922 handled = true; 6923 break; 6924 } 6925 6926 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 6927 case kWhatSubmitOutputMetadataBufferIfEOS: 6928 { 6929 if (mCodec->mPortEOS[kPortIndexInput] && 6930 !mCodec->mPortEOS[kPortIndexOutput]) { 6931 status_t err = mCodec->submitOutputMetadataBuffer(); 6932 if (err == OK) { 6933 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 6934 } 6935 } 6936 return true; 6937 } 6938 6939 default: 6940 handled = BaseState::onMessageReceived(msg); 6941 break; 6942 } 6943 6944 return handled; 6945} 6946 6947status_t ACodec::setParameters(const sp<AMessage> ¶ms) { 6948 int32_t videoBitrate; 6949 if (params->findInt32("video-bitrate", &videoBitrate)) { 6950 OMX_VIDEO_CONFIG_BITRATETYPE configParams; 6951 InitOMXParams(&configParams); 6952 configParams.nPortIndex = kPortIndexOutput; 6953 configParams.nEncodeBitrate = videoBitrate; 6954 6955 status_t err = mOMXNode->setConfig( 6956 OMX_IndexConfigVideoBitrate, 6957 &configParams, 6958 sizeof(configParams)); 6959 6960 if (err != OK) { 6961 ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d", 6962 videoBitrate, err); 6963 6964 return err; 6965 } 6966 } 6967 6968 int64_t timeOffsetUs; 6969 if (params->findInt64("time-offset-us", &timeOffsetUs)) { 6970 if (mGraphicBufferSource == NULL) { 6971 ALOGE("[%s] Invalid to set input buffer time offset without surface", 6972 mComponentName.c_str()); 6973 return INVALID_OPERATION; 6974 } 6975 6976 status_t err = statusFromBinderStatus( 6977 mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs)); 6978 6979 if (err != OK) { 6980 ALOGE("[%s] Unable to set input buffer time offset (err %d)", 6981 mComponentName.c_str(), 6982 err); 6983 return err; 6984 } 6985 } 6986 6987 int64_t skipFramesBeforeUs; 6988 if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) { 6989 if (mGraphicBufferSource == NULL) { 6990 ALOGE("[%s] Invalid to set start time without surface", 6991 mComponentName.c_str()); 6992 return INVALID_OPERATION; 6993 } 6994 6995 status_t err = statusFromBinderStatus( 6996 mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs)); 6997 6998 if (err != OK) { 6999 ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err); 7000 return err; 7001 } 7002 } 7003 7004 int32_t dropInputFrames; 7005 if (params->findInt32("drop-input-frames", &dropInputFrames)) { 7006 if (mGraphicBufferSource == NULL) { 7007 ALOGE("[%s] Invalid to set suspend without surface", 7008 mComponentName.c_str()); 7009 return INVALID_OPERATION; 7010 } 7011 7012 status_t err = statusFromBinderStatus( 7013 mGraphicBufferSource->setSuspend(dropInputFrames != 0)); 7014 7015 if (err != OK) { 7016 ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err); 7017 return err; 7018 } 7019 } 7020 7021 int32_t dummy; 7022 if (params->findInt32("request-sync", &dummy)) { 7023 status_t err = requestIDRFrame(); 7024 7025 if (err != OK) { 7026 ALOGE("Requesting a sync frame failed w/ err %d", err); 7027 return err; 7028 } 7029 } 7030 7031 float rate; 7032 if (params->findFloat("operating-rate", &rate) && rate > 0) { 7033 status_t err = setOperatingRate(rate, mIsVideo); 7034 if (err != OK) { 7035 ALOGE("Failed to set parameter 'operating-rate' (err %d)", err); 7036 return err; 7037 } 7038 } 7039 7040 int32_t intraRefreshPeriod = 0; 7041 if (params->findInt32("intra-refresh-period", &intraRefreshPeriod) 7042 && intraRefreshPeriod > 0) { 7043 status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false); 7044 if (err != OK) { 7045 ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional", 7046 mComponentName.c_str()); 7047 err = OK; 7048 } 7049 } 7050 7051 status_t err = configureTemporalLayers(params, false /* inConfigure */, mOutputFormat); 7052 if (err != OK) { 7053 err = OK; // ignore failure 7054 } 7055 7056 return err; 7057} 7058 7059void ACodec::onSignalEndOfInputStream() { 7060 status_t err = INVALID_OPERATION; 7061 if (mGraphicBufferSource != NULL) { 7062 err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream()); 7063 } 7064 mCallback->onSignaledInputEOS(err); 7065} 7066 7067bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { 7068 mCodec->onFrameRendered(mediaTimeUs, systemNano); 7069 return true; 7070} 7071 7072bool ACodec::ExecutingState::onOMXEvent( 7073 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7074 switch (event) { 7075 case OMX_EventPortSettingsChanged: 7076 { 7077 CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 7078 7079 mCodec->onOutputFormatChanged(); 7080 7081 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 7082 mCodec->mMetadataBuffersToSubmit = 0; 7083 CHECK_EQ(mCodec->mOMXNode->sendCommand( 7084 OMX_CommandPortDisable, kPortIndexOutput), 7085 (status_t)OK); 7086 7087 mCodec->freeOutputBuffersNotOwnedByComponent(); 7088 7089 mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 7090 } else if (data2 != OMX_IndexConfigCommonOutputCrop 7091 && data2 != OMX_IndexConfigAndroidIntraRefresh) { 7092 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x", 7093 mCodec->mComponentName.c_str(), data2); 7094 } 7095 7096 return true; 7097 } 7098 7099 case OMX_EventBufferFlag: 7100 { 7101 return true; 7102 } 7103 7104 default: 7105 return BaseState::onOMXEvent(event, data1, data2); 7106 } 7107} 7108 7109//////////////////////////////////////////////////////////////////////////////// 7110 7111ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 7112 ACodec *codec) 7113 : BaseState(codec) { 7114} 7115 7116ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 7117 OMX_U32 portIndex) { 7118 if (portIndex == kPortIndexOutput) { 7119 return FREE_BUFFERS; 7120 } 7121 7122 CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 7123 7124 return RESUBMIT_BUFFERS; 7125} 7126 7127bool ACodec::OutputPortSettingsChangedState::onMessageReceived( 7128 const sp<AMessage> &msg) { 7129 bool handled = false; 7130 7131 switch (msg->what()) { 7132 case kWhatFlush: 7133 case kWhatShutdown: 7134 case kWhatResume: 7135 case kWhatSetParameters: 7136 { 7137 if (msg->what() == kWhatResume) { 7138 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 7139 } 7140 7141 mCodec->deferMessage(msg); 7142 handled = true; 7143 break; 7144 } 7145 7146 default: 7147 handled = BaseState::onMessageReceived(msg); 7148 break; 7149 } 7150 7151 return handled; 7152} 7153 7154void ACodec::OutputPortSettingsChangedState::stateEntered() { 7155 ALOGV("[%s] Now handling output port settings change", 7156 mCodec->mComponentName.c_str()); 7157} 7158 7159bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered( 7160 int64_t mediaTimeUs, nsecs_t systemNano) { 7161 mCodec->onFrameRendered(mediaTimeUs, systemNano); 7162 return true; 7163} 7164 7165bool ACodec::OutputPortSettingsChangedState::onOMXEvent( 7166 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7167 switch (event) { 7168 case OMX_EventCmdComplete: 7169 { 7170 if (data1 == (OMX_U32)OMX_CommandPortDisable) { 7171 if (data2 != (OMX_U32)kPortIndexOutput) { 7172 ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2); 7173 return false; 7174 } 7175 7176 ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str()); 7177 7178 status_t err = OK; 7179 if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) { 7180 ALOGE("disabled port should be empty, but has %zu buffers", 7181 mCodec->mBuffers[kPortIndexOutput].size()); 7182 err = FAILED_TRANSACTION; 7183 } else { 7184 mCodec->mDealer[kPortIndexOutput].clear(); 7185 } 7186 7187 if (err == OK) { 7188 err = mCodec->mOMXNode->sendCommand( 7189 OMX_CommandPortEnable, kPortIndexOutput); 7190 } 7191 7192 if (err == OK) { 7193 err = mCodec->allocateBuffersOnPort(kPortIndexOutput); 7194 ALOGE_IF(err != OK, "Failed to allocate output port buffers after port " 7195 "reconfiguration: (%d)", err); 7196 mCodec->mCallback->onOutputBuffersChanged(); 7197 } 7198 7199 if (err != OK) { 7200 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 7201 7202 // This is technically not correct, but appears to be 7203 // the only way to free the component instance. 7204 // Controlled transitioning from excecuting->idle 7205 // and idle->loaded seem impossible probably because 7206 // the output port never finishes re-enabling. 7207 mCodec->mShutdownInProgress = true; 7208 mCodec->mKeepComponentAllocated = false; 7209 mCodec->changeState(mCodec->mLoadedState); 7210 } 7211 7212 return true; 7213 } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 7214 if (data2 != (OMX_U32)kPortIndexOutput) { 7215 ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2); 7216 return false; 7217 } 7218 7219 ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str()); 7220 7221 if (mCodec->mExecutingState->active()) { 7222 mCodec->mExecutingState->submitOutputBuffers(); 7223 } 7224 7225 mCodec->changeState(mCodec->mExecutingState); 7226 7227 return true; 7228 } 7229 7230 return false; 7231 } 7232 7233 default: 7234 return false; 7235 } 7236} 7237 7238//////////////////////////////////////////////////////////////////////////////// 7239 7240ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 7241 : BaseState(codec), 7242 mComponentNowIdle(false) { 7243} 7244 7245bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 7246 bool handled = false; 7247 7248 switch (msg->what()) { 7249 case kWhatFlush: 7250 { 7251 // Don't send me a flush request if you previously wanted me 7252 // to shutdown. 7253 ALOGW("Ignoring flush request in ExecutingToIdleState"); 7254 break; 7255 } 7256 7257 case kWhatShutdown: 7258 { 7259 mCodec->deferMessage(msg); 7260 handled = true; 7261 break; 7262 } 7263 7264 default: 7265 handled = BaseState::onMessageReceived(msg); 7266 break; 7267 } 7268 7269 return handled; 7270} 7271 7272void ACodec::ExecutingToIdleState::stateEntered() { 7273 ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 7274 7275 mComponentNowIdle = false; 7276 mCodec->mLastOutputFormat.clear(); 7277} 7278 7279bool ACodec::ExecutingToIdleState::onOMXEvent( 7280 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7281 switch (event) { 7282 case OMX_EventCmdComplete: 7283 { 7284 if (data1 != (OMX_U32)OMX_CommandStateSet 7285 || data2 != (OMX_U32)OMX_StateIdle) { 7286 ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)", 7287 asString((OMX_COMMANDTYPE)data1), data1, 7288 asString((OMX_STATETYPE)data2), data2); 7289 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7290 return true; 7291 } 7292 7293 mComponentNowIdle = true; 7294 7295 changeStateIfWeOwnAllBuffers(); 7296 7297 return true; 7298 } 7299 7300 case OMX_EventPortSettingsChanged: 7301 case OMX_EventBufferFlag: 7302 { 7303 // We're shutting down and don't care about this anymore. 7304 return true; 7305 } 7306 7307 default: 7308 return BaseState::onOMXEvent(event, data1, data2); 7309 } 7310} 7311 7312void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 7313 if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) { 7314 status_t err = mCodec->mOMXNode->sendCommand( 7315 OMX_CommandStateSet, OMX_StateLoaded); 7316 if (err == OK) { 7317 err = mCodec->freeBuffersOnPort(kPortIndexInput); 7318 status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput); 7319 if (err == OK) { 7320 err = err2; 7321 } 7322 } 7323 7324 if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) 7325 && mCodec->mNativeWindow != NULL) { 7326 // We push enough 1x1 blank buffers to ensure that one of 7327 // them has made it to the display. This allows the OMX 7328 // component teardown to zero out any protected buffers 7329 // without the risk of scanning out one of those buffers. 7330 pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get()); 7331 } 7332 7333 if (err != OK) { 7334 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7335 return; 7336 } 7337 7338 mCodec->changeState(mCodec->mIdleToLoadedState); 7339 } 7340} 7341 7342void ACodec::ExecutingToIdleState::onInputBufferFilled( 7343 const sp<AMessage> &msg) { 7344 BaseState::onInputBufferFilled(msg); 7345 7346 changeStateIfWeOwnAllBuffers(); 7347} 7348 7349void ACodec::ExecutingToIdleState::onOutputBufferDrained( 7350 const sp<AMessage> &msg) { 7351 BaseState::onOutputBufferDrained(msg); 7352 7353 changeStateIfWeOwnAllBuffers(); 7354} 7355 7356//////////////////////////////////////////////////////////////////////////////// 7357 7358ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 7359 : BaseState(codec) { 7360} 7361 7362bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 7363 bool handled = false; 7364 7365 switch (msg->what()) { 7366 case kWhatShutdown: 7367 { 7368 mCodec->deferMessage(msg); 7369 handled = true; 7370 break; 7371 } 7372 7373 case kWhatFlush: 7374 { 7375 // Don't send me a flush request if you previously wanted me 7376 // to shutdown. 7377 ALOGE("Got flush request in IdleToLoadedState"); 7378 break; 7379 } 7380 7381 default: 7382 handled = BaseState::onMessageReceived(msg); 7383 break; 7384 } 7385 7386 return handled; 7387} 7388 7389void ACodec::IdleToLoadedState::stateEntered() { 7390 ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 7391} 7392 7393bool ACodec::IdleToLoadedState::onOMXEvent( 7394 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7395 switch (event) { 7396 case OMX_EventCmdComplete: 7397 { 7398 if (data1 != (OMX_U32)OMX_CommandStateSet 7399 || data2 != (OMX_U32)OMX_StateLoaded) { 7400 ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)", 7401 asString((OMX_COMMANDTYPE)data1), data1, 7402 asString((OMX_STATETYPE)data2), data2); 7403 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7404 return true; 7405 } 7406 7407 mCodec->changeState(mCodec->mLoadedState); 7408 7409 return true; 7410 } 7411 7412 default: 7413 return BaseState::onOMXEvent(event, data1, data2); 7414 } 7415} 7416 7417//////////////////////////////////////////////////////////////////////////////// 7418 7419ACodec::FlushingState::FlushingState(ACodec *codec) 7420 : BaseState(codec) { 7421} 7422 7423void ACodec::FlushingState::stateEntered() { 7424 ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 7425 7426 mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 7427} 7428 7429bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 7430 bool handled = false; 7431 7432 switch (msg->what()) { 7433 case kWhatShutdown: 7434 { 7435 mCodec->deferMessage(msg); 7436 break; 7437 } 7438 7439 case kWhatFlush: 7440 { 7441 // We're already doing this right now. 7442 handled = true; 7443 break; 7444 } 7445 7446 default: 7447 handled = BaseState::onMessageReceived(msg); 7448 break; 7449 } 7450 7451 return handled; 7452} 7453 7454bool ACodec::FlushingState::onOMXEvent( 7455 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 7456 ALOGV("[%s] FlushingState onOMXEvent(%u,%d)", 7457 mCodec->mComponentName.c_str(), event, (OMX_S32)data1); 7458 7459 switch (event) { 7460 case OMX_EventCmdComplete: 7461 { 7462 if (data1 != (OMX_U32)OMX_CommandFlush) { 7463 ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState", 7464 asString((OMX_COMMANDTYPE)data1), data1, data2); 7465 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 7466 return true; 7467 } 7468 7469 if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 7470 if (mFlushComplete[data2]) { 7471 ALOGW("Flush already completed for %s port", 7472 data2 == kPortIndexInput ? "input" : "output"); 7473 return true; 7474 } 7475 mFlushComplete[data2] = true; 7476 7477 if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) { 7478 changeStateIfWeOwnAllBuffers(); 7479 } 7480 } else if (data2 == OMX_ALL) { 7481 if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) { 7482 ALOGW("received flush complete event for OMX_ALL before ports have been" 7483 "flushed (%d/%d)", 7484 mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]); 7485 return false; 7486 } 7487 7488 changeStateIfWeOwnAllBuffers(); 7489 } else { 7490 ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2); 7491 } 7492 7493 return true; 7494 } 7495 7496 case OMX_EventPortSettingsChanged: 7497 { 7498 sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec); 7499 msg->setInt32("type", omx_message::EVENT); 7500 msg->setInt32("generation", mCodec->mNodeGeneration); 7501 msg->setInt32("event", event); 7502 msg->setInt32("data1", data1); 7503 msg->setInt32("data2", data2); 7504 7505 ALOGV("[%s] Deferring OMX_EventPortSettingsChanged", 7506 mCodec->mComponentName.c_str()); 7507 7508 mCodec->deferMessage(msg); 7509 7510 return true; 7511 } 7512 7513 default: 7514 return BaseState::onOMXEvent(event, data1, data2); 7515 } 7516 7517 return true; 7518} 7519 7520void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 7521 BaseState::onOutputBufferDrained(msg); 7522 7523 changeStateIfWeOwnAllBuffers(); 7524} 7525 7526void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 7527 BaseState::onInputBufferFilled(msg); 7528 7529 changeStateIfWeOwnAllBuffers(); 7530} 7531 7532void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 7533 if (mFlushComplete[kPortIndexInput] 7534 && mFlushComplete[kPortIndexOutput] 7535 && mCodec->allYourBuffersAreBelongToUs()) { 7536 // We now own all buffers except possibly those still queued with 7537 // the native window for rendering. Let's get those back as well. 7538 mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs(); 7539 7540 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 7541 7542 mCodec->mCallback->onFlushCompleted(); 7543 7544 mCodec->mPortEOS[kPortIndexInput] = 7545 mCodec->mPortEOS[kPortIndexOutput] = false; 7546 7547 mCodec->mInputEOSResult = OK; 7548 7549 if (mCodec->mSkipCutBuffer != NULL) { 7550 mCodec->mSkipCutBuffer->clear(); 7551 } 7552 7553 mCodec->changeState(mCodec->mExecutingState); 7554 } 7555} 7556 7557status_t ACodec::queryCapabilities( 7558 const AString &name, const AString &mime, bool isEncoder, 7559 sp<MediaCodecInfo::Capabilities> *caps) { 7560 (*caps).clear(); 7561 const char *role = GetComponentRole(isEncoder, mime.c_str()); 7562 if (role == NULL) { 7563 return BAD_VALUE; 7564 } 7565 7566 OMXClient client; 7567 status_t err = client.connect(); 7568 if (err != OK) { 7569 return err; 7570 } 7571 7572 sp<IOMX> omx = client.interface(); 7573 sp<CodecObserver> observer = new CodecObserver; 7574 sp<IOMXNode> omxNode; 7575 7576 err = omx->allocateNode(name.c_str(), observer, &omxNode); 7577 if (err != OK) { 7578 client.disconnect(); 7579 return err; 7580 } 7581 7582 err = SetComponentRole(omxNode, role); 7583 if (err != OK) { 7584 omxNode->freeNode(); 7585 client.disconnect(); 7586 return err; 7587 } 7588 7589 sp<MediaCodecInfo::CapabilitiesBuilder> builder = new MediaCodecInfo::CapabilitiesBuilder(); 7590 bool isVideo = mime.startsWithIgnoreCase("video/"); 7591 7592 if (isVideo) { 7593 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 7594 InitOMXParams(¶m); 7595 param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput; 7596 7597 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 7598 param.nProfileIndex = index; 7599 status_t err = omxNode->getParameter( 7600 OMX_IndexParamVideoProfileLevelQuerySupported, 7601 ¶m, sizeof(param)); 7602 if (err != OK) { 7603 break; 7604 } 7605 builder->addProfileLevel(param.eProfile, param.eLevel); 7606 7607 if (index == kMaxIndicesToCheck) { 7608 ALOGW("[%s] stopping checking profiles after %u: %x/%x", 7609 name.c_str(), index, 7610 param.eProfile, param.eLevel); 7611 } 7612 } 7613 7614 // Color format query 7615 // return colors in the order reported by the OMX component 7616 // prefix "flexible" standard ones with the flexible equivalent 7617 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 7618 InitOMXParams(&portFormat); 7619 portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput; 7620 Vector<uint32_t> supportedColors; // shadow copy to check for duplicates 7621 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 7622 portFormat.nIndex = index; 7623 status_t err = omxNode->getParameter( 7624 OMX_IndexParamVideoPortFormat, 7625 &portFormat, sizeof(portFormat)); 7626 if (err != OK) { 7627 break; 7628 } 7629 7630 OMX_U32 flexibleEquivalent; 7631 if (IsFlexibleColorFormat( 7632 omxNode, portFormat.eColorFormat, false /* usingNativeWindow */, 7633 &flexibleEquivalent)) { 7634 bool marked = false; 7635 for (size_t i = 0; i < supportedColors.size(); ++i) { 7636 if (supportedColors[i] == flexibleEquivalent) { 7637 marked = true; 7638 break; 7639 } 7640 } 7641 if (!marked) { 7642 supportedColors.push(flexibleEquivalent); 7643 builder->addColorFormat(flexibleEquivalent); 7644 } 7645 } 7646 supportedColors.push(portFormat.eColorFormat); 7647 builder->addColorFormat(portFormat.eColorFormat); 7648 7649 if (index == kMaxIndicesToCheck) { 7650 ALOGW("[%s] stopping checking formats after %u: %s(%x)", 7651 name.c_str(), index, 7652 asString(portFormat.eColorFormat), portFormat.eColorFormat); 7653 } 7654 } 7655 } else if (mime.equalsIgnoreCase(MEDIA_MIMETYPE_AUDIO_AAC)) { 7656 // More audio codecs if they have profiles. 7657 OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param; 7658 InitOMXParams(¶m); 7659 param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput; 7660 for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) { 7661 param.nProfileIndex = index; 7662 status_t err = omxNode->getParameter( 7663 (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported, 7664 ¶m, sizeof(param)); 7665 if (err != OK) { 7666 break; 7667 } 7668 // For audio, level is ignored. 7669 builder->addProfileLevel(param.eProfile, 0 /* level */); 7670 7671 if (index == kMaxIndicesToCheck) { 7672 ALOGW("[%s] stopping checking profiles after %u: %x", 7673 name.c_str(), index, 7674 param.eProfile); 7675 } 7676 } 7677 7678 // NOTE: Without Android extensions, OMX does not provide a way to query 7679 // AAC profile support 7680 if (param.nProfileIndex == 0) { 7681 ALOGW("component %s doesn't support profile query.", name.c_str()); 7682 } 7683 } 7684 7685 if (isVideo && !isEncoder) { 7686 native_handle_t *sidebandHandle = NULL; 7687 if (omxNode->configureVideoTunnelMode( 7688 kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) { 7689 // tunneled playback includes adaptive playback 7690 builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback 7691 | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback); 7692 } else if (omxNode->setPortMode( 7693 kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK || 7694 omxNode->prepareForAdaptivePlayback( 7695 kPortIndexOutput, OMX_TRUE, 7696 1280 /* width */, 720 /* height */) == OK) { 7697 builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback); 7698 } 7699 } 7700 7701 if (isVideo && isEncoder) { 7702 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params; 7703 InitOMXParams(¶ms); 7704 params.nPortIndex = kPortIndexOutput; 7705 // TODO: should we verify if fallback is supported? 7706 if (omxNode->getConfig( 7707 (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, 7708 ¶ms, sizeof(params)) == OK) { 7709 builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh); 7710 } 7711 } 7712 7713 *caps = builder; 7714 omxNode->freeNode(); 7715 client.disconnect(); 7716 return OK; 7717} 7718 7719// These are supposed be equivalent to the logic in 7720// "audio_channel_out_mask_from_count". 7721//static 7722status_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) { 7723 switch (numChannels) { 7724 case 1: 7725 map[0] = OMX_AUDIO_ChannelCF; 7726 break; 7727 case 2: 7728 map[0] = OMX_AUDIO_ChannelLF; 7729 map[1] = OMX_AUDIO_ChannelRF; 7730 break; 7731 case 3: 7732 map[0] = OMX_AUDIO_ChannelLF; 7733 map[1] = OMX_AUDIO_ChannelRF; 7734 map[2] = OMX_AUDIO_ChannelCF; 7735 break; 7736 case 4: 7737 map[0] = OMX_AUDIO_ChannelLF; 7738 map[1] = OMX_AUDIO_ChannelRF; 7739 map[2] = OMX_AUDIO_ChannelLR; 7740 map[3] = OMX_AUDIO_ChannelRR; 7741 break; 7742 case 5: 7743 map[0] = OMX_AUDIO_ChannelLF; 7744 map[1] = OMX_AUDIO_ChannelRF; 7745 map[2] = OMX_AUDIO_ChannelCF; 7746 map[3] = OMX_AUDIO_ChannelLR; 7747 map[4] = OMX_AUDIO_ChannelRR; 7748 break; 7749 case 6: 7750 map[0] = OMX_AUDIO_ChannelLF; 7751 map[1] = OMX_AUDIO_ChannelRF; 7752 map[2] = OMX_AUDIO_ChannelCF; 7753 map[3] = OMX_AUDIO_ChannelLFE; 7754 map[4] = OMX_AUDIO_ChannelLR; 7755 map[5] = OMX_AUDIO_ChannelRR; 7756 break; 7757 case 7: 7758 map[0] = OMX_AUDIO_ChannelLF; 7759 map[1] = OMX_AUDIO_ChannelRF; 7760 map[2] = OMX_AUDIO_ChannelCF; 7761 map[3] = OMX_AUDIO_ChannelLFE; 7762 map[4] = OMX_AUDIO_ChannelLR; 7763 map[5] = OMX_AUDIO_ChannelRR; 7764 map[6] = OMX_AUDIO_ChannelCS; 7765 break; 7766 case 8: 7767 map[0] = OMX_AUDIO_ChannelLF; 7768 map[1] = OMX_AUDIO_ChannelRF; 7769 map[2] = OMX_AUDIO_ChannelCF; 7770 map[3] = OMX_AUDIO_ChannelLFE; 7771 map[4] = OMX_AUDIO_ChannelLR; 7772 map[5] = OMX_AUDIO_ChannelRR; 7773 map[6] = OMX_AUDIO_ChannelLS; 7774 map[7] = OMX_AUDIO_ChannelRS; 7775 break; 7776 default: 7777 return -EINVAL; 7778 } 7779 7780 return OK; 7781} 7782 7783} // namespace android 7784