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