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