ACodec.cpp revision d291c222357303b9611cab89d0c3b047584ef377
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/MediaCodecList.h> 41#include <media/stagefright/MediaDefs.h> 42#include <media/stagefright/OMXClient.h> 43#include <media/stagefright/OMXCodec.h> 44#include <media/stagefright/PersistentSurface.h> 45#include <media/hardware/HardwareAPI.h> 46 47#include <OMX_AudioExt.h> 48#include <OMX_VideoExt.h> 49#include <OMX_Component.h> 50#include <OMX_IndexExt.h> 51 52#include "include/avc_utils.h" 53 54namespace android { 55 56// OMX errors are directly mapped into status_t range if 57// there is no corresponding MediaError status code. 58// Use the statusFromOMXError(int32_t omxError) function. 59// 60// Currently this is a direct map. 61// See frameworks/native/include/media/openmax/OMX_Core.h 62// 63// Vendor OMX errors from 0x90000000 - 0x9000FFFF 64// Extension OMX errors from 0x8F000000 - 0x90000000 65// Standard OMX errors from 0x80001000 - 0x80001024 (0x80001024 current) 66// 67 68// returns true if err is a recognized OMX error code. 69// as OMX error is OMX_S32, this is an int32_t type 70static inline bool isOMXError(int32_t err) { 71 return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX); 72} 73 74// converts an OMX error to a status_t 75static inline status_t statusFromOMXError(int32_t omxError) { 76 switch (omxError) { 77 case OMX_ErrorInvalidComponentName: 78 case OMX_ErrorComponentNotFound: 79 return NAME_NOT_FOUND; // can trigger illegal argument error for provided names. 80 default: 81 return isOMXError(omxError) ? omxError : 0; // no translation required 82 } 83} 84 85// checks and converts status_t to a non-side-effect status_t 86static inline status_t makeNoSideEffectStatus(status_t err) { 87 switch (err) { 88 // the following errors have side effects and may come 89 // from other code modules. Remap for safety reasons. 90 case INVALID_OPERATION: 91 case DEAD_OBJECT: 92 return UNKNOWN_ERROR; 93 default: 94 return err; 95 } 96} 97 98template<class T> 99static void InitOMXParams(T *params) { 100 params->nSize = sizeof(T); 101 params->nVersion.s.nVersionMajor = 1; 102 params->nVersion.s.nVersionMinor = 0; 103 params->nVersion.s.nRevision = 0; 104 params->nVersion.s.nStep = 0; 105} 106 107struct CodecObserver : public BnOMXObserver { 108 CodecObserver() {} 109 110 void setNotificationMessage(const sp<AMessage> &msg) { 111 mNotify = msg; 112 } 113 114 // from IOMXObserver 115 virtual void onMessage(const omx_message &omx_msg) { 116 sp<AMessage> msg = mNotify->dup(); 117 118 msg->setInt32("type", omx_msg.type); 119 msg->setInt32("node", omx_msg.node); 120 121 switch (omx_msg.type) { 122 case omx_message::EVENT: 123 { 124 msg->setInt32("event", omx_msg.u.event_data.event); 125 msg->setInt32("data1", omx_msg.u.event_data.data1); 126 msg->setInt32("data2", omx_msg.u.event_data.data2); 127 break; 128 } 129 130 case omx_message::EMPTY_BUFFER_DONE: 131 { 132 msg->setInt32("buffer", omx_msg.u.buffer_data.buffer); 133 break; 134 } 135 136 case omx_message::FILL_BUFFER_DONE: 137 { 138 msg->setInt32( 139 "buffer", omx_msg.u.extended_buffer_data.buffer); 140 msg->setInt32( 141 "range_offset", 142 omx_msg.u.extended_buffer_data.range_offset); 143 msg->setInt32( 144 "range_length", 145 omx_msg.u.extended_buffer_data.range_length); 146 msg->setInt32( 147 "flags", 148 omx_msg.u.extended_buffer_data.flags); 149 msg->setInt64( 150 "timestamp", 151 omx_msg.u.extended_buffer_data.timestamp); 152 break; 153 } 154 155 default: 156 TRESPASS(); 157 break; 158 } 159 160 msg->post(); 161 } 162 163protected: 164 virtual ~CodecObserver() {} 165 166private: 167 sp<AMessage> mNotify; 168 169 DISALLOW_EVIL_CONSTRUCTORS(CodecObserver); 170}; 171 172//////////////////////////////////////////////////////////////////////////////// 173 174struct ACodec::BaseState : public AState { 175 BaseState(ACodec *codec, const sp<AState> &parentState = NULL); 176 177protected: 178 enum PortMode { 179 KEEP_BUFFERS, 180 RESUBMIT_BUFFERS, 181 FREE_BUFFERS, 182 }; 183 184 ACodec *mCodec; 185 186 virtual PortMode getPortMode(OMX_U32 portIndex); 187 188 virtual bool onMessageReceived(const sp<AMessage> &msg); 189 190 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 191 192 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 193 virtual void onInputBufferFilled(const sp<AMessage> &msg); 194 195 void postFillThisBuffer(BufferInfo *info); 196 197private: 198 bool onOMXMessage(const sp<AMessage> &msg); 199 200 bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID); 201 202 bool onOMXFillBufferDone( 203 IOMX::buffer_id bufferID, 204 size_t rangeOffset, size_t rangeLength, 205 OMX_U32 flags, 206 int64_t timeUs); 207 208 void getMoreInputDataIfPossible(); 209 210 DISALLOW_EVIL_CONSTRUCTORS(BaseState); 211}; 212 213//////////////////////////////////////////////////////////////////////////////// 214 215struct ACodec::DeathNotifier : public IBinder::DeathRecipient { 216 DeathNotifier(const sp<AMessage> ¬ify) 217 : mNotify(notify) { 218 } 219 220 virtual void binderDied(const wp<IBinder> &) { 221 mNotify->post(); 222 } 223 224protected: 225 virtual ~DeathNotifier() {} 226 227private: 228 sp<AMessage> mNotify; 229 230 DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier); 231}; 232 233struct ACodec::UninitializedState : public ACodec::BaseState { 234 UninitializedState(ACodec *codec); 235 236protected: 237 virtual bool onMessageReceived(const sp<AMessage> &msg); 238 virtual void stateEntered(); 239 240private: 241 void onSetup(const sp<AMessage> &msg); 242 bool onAllocateComponent(const sp<AMessage> &msg); 243 244 sp<DeathNotifier> mDeathNotifier; 245 246 DISALLOW_EVIL_CONSTRUCTORS(UninitializedState); 247}; 248 249//////////////////////////////////////////////////////////////////////////////// 250 251struct ACodec::LoadedState : public ACodec::BaseState { 252 LoadedState(ACodec *codec); 253 254protected: 255 virtual bool onMessageReceived(const sp<AMessage> &msg); 256 virtual void stateEntered(); 257 258private: 259 friend struct ACodec::UninitializedState; 260 261 bool onConfigureComponent(const sp<AMessage> &msg); 262 void onCreateInputSurface(const sp<AMessage> &msg); 263 void onUsePersistentInputSurface(const sp<AMessage> &msg); 264 void onStart(); 265 void onShutdown(bool keepComponentAllocated); 266 267 status_t setupInputSurface(); 268 269 DISALLOW_EVIL_CONSTRUCTORS(LoadedState); 270}; 271 272//////////////////////////////////////////////////////////////////////////////// 273 274struct ACodec::LoadedToIdleState : public ACodec::BaseState { 275 LoadedToIdleState(ACodec *codec); 276 277protected: 278 virtual bool onMessageReceived(const sp<AMessage> &msg); 279 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 280 virtual void stateEntered(); 281 282private: 283 status_t allocateBuffers(); 284 285 DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState); 286}; 287 288//////////////////////////////////////////////////////////////////////////////// 289 290struct ACodec::IdleToExecutingState : public ACodec::BaseState { 291 IdleToExecutingState(ACodec *codec); 292 293protected: 294 virtual bool onMessageReceived(const sp<AMessage> &msg); 295 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 296 virtual void stateEntered(); 297 298private: 299 DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState); 300}; 301 302//////////////////////////////////////////////////////////////////////////////// 303 304struct ACodec::ExecutingState : public ACodec::BaseState { 305 ExecutingState(ACodec *codec); 306 307 void submitRegularOutputBuffers(); 308 void submitOutputMetaBuffers(); 309 void submitOutputBuffers(); 310 311 // Submit output buffers to the decoder, submit input buffers to client 312 // to fill with data. 313 void resume(); 314 315 // Returns true iff input and output buffers are in play. 316 bool active() const { return mActive; } 317 318protected: 319 virtual PortMode getPortMode(OMX_U32 portIndex); 320 virtual bool onMessageReceived(const sp<AMessage> &msg); 321 virtual void stateEntered(); 322 323 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 324 325private: 326 bool mActive; 327 328 DISALLOW_EVIL_CONSTRUCTORS(ExecutingState); 329}; 330 331//////////////////////////////////////////////////////////////////////////////// 332 333struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState { 334 OutputPortSettingsChangedState(ACodec *codec); 335 336protected: 337 virtual PortMode getPortMode(OMX_U32 portIndex); 338 virtual bool onMessageReceived(const sp<AMessage> &msg); 339 virtual void stateEntered(); 340 341 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 342 343private: 344 DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState); 345}; 346 347//////////////////////////////////////////////////////////////////////////////// 348 349struct ACodec::ExecutingToIdleState : public ACodec::BaseState { 350 ExecutingToIdleState(ACodec *codec); 351 352protected: 353 virtual bool onMessageReceived(const sp<AMessage> &msg); 354 virtual void stateEntered(); 355 356 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 357 358 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 359 virtual void onInputBufferFilled(const sp<AMessage> &msg); 360 361private: 362 void changeStateIfWeOwnAllBuffers(); 363 364 bool mComponentNowIdle; 365 366 DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState); 367}; 368 369//////////////////////////////////////////////////////////////////////////////// 370 371struct ACodec::IdleToLoadedState : public ACodec::BaseState { 372 IdleToLoadedState(ACodec *codec); 373 374protected: 375 virtual bool onMessageReceived(const sp<AMessage> &msg); 376 virtual void stateEntered(); 377 378 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 379 380private: 381 DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState); 382}; 383 384//////////////////////////////////////////////////////////////////////////////// 385 386struct ACodec::FlushingState : public ACodec::BaseState { 387 FlushingState(ACodec *codec); 388 389protected: 390 virtual bool onMessageReceived(const sp<AMessage> &msg); 391 virtual void stateEntered(); 392 393 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 394 395 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 396 virtual void onInputBufferFilled(const sp<AMessage> &msg); 397 398private: 399 bool mFlushComplete[2]; 400 401 void changeStateIfWeOwnAllBuffers(); 402 403 DISALLOW_EVIL_CONSTRUCTORS(FlushingState); 404}; 405 406//////////////////////////////////////////////////////////////////////////////// 407 408ACodec::ACodec() 409 : mQuirks(0), 410 mNode(0), 411 mSentFormat(false), 412 mIsVideo(false), 413 mIsEncoder(false), 414 mUseMetadataOnEncoderOutput(false), 415 mShutdownInProgress(false), 416 mExplicitShutdown(false), 417 mEncoderDelay(0), 418 mEncoderPadding(0), 419 mRotationDegrees(0), 420 mChannelMaskPresent(false), 421 mChannelMask(0), 422 mDequeueCounter(0), 423 mStoreMetaDataInOutputBuffers(false), 424 mMetaDataBuffersToSubmit(0), 425 mRepeatFrameDelayUs(-1ll), 426 mMaxPtsGapUs(-1ll), 427 mMaxFps(-1), 428 mTimePerFrameUs(-1ll), 429 mTimePerCaptureUs(-1ll), 430 mCreateInputBuffersSuspended(false), 431 mTunneled(false) { 432 mUninitializedState = new UninitializedState(this); 433 mLoadedState = new LoadedState(this); 434 mLoadedToIdleState = new LoadedToIdleState(this); 435 mIdleToExecutingState = new IdleToExecutingState(this); 436 mExecutingState = new ExecutingState(this); 437 438 mOutputPortSettingsChangedState = 439 new OutputPortSettingsChangedState(this); 440 441 mExecutingToIdleState = new ExecutingToIdleState(this); 442 mIdleToLoadedState = new IdleToLoadedState(this); 443 mFlushingState = new FlushingState(this); 444 445 mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false; 446 mInputEOSResult = OK; 447 448 changeState(mUninitializedState); 449} 450 451ACodec::~ACodec() { 452} 453 454void ACodec::setNotificationMessage(const sp<AMessage> &msg) { 455 mNotify = msg; 456} 457 458void ACodec::initiateSetup(const sp<AMessage> &msg) { 459 msg->setWhat(kWhatSetup); 460 msg->setTarget(this); 461 msg->post(); 462} 463 464void ACodec::signalSetParameters(const sp<AMessage> ¶ms) { 465 sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 466 msg->setMessage("params", params); 467 msg->post(); 468} 469 470void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) { 471 msg->setWhat(kWhatAllocateComponent); 472 msg->setTarget(this); 473 msg->post(); 474} 475 476void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) { 477 msg->setWhat(kWhatConfigureComponent); 478 msg->setTarget(this); 479 msg->post(); 480} 481 482void ACodec::initiateCreateInputSurface() { 483 (new AMessage(kWhatCreateInputSurface, this))->post(); 484} 485 486void ACodec::initiateUsePersistentInputSurface( 487 const sp<PersistentSurface> &surface) { 488 sp<AMessage> msg = new AMessage(kWhatUsePersistentInputSurface, this); 489 msg->setObject("input-surface", surface); 490 msg->post(); 491} 492 493void ACodec::signalEndOfInputStream() { 494 (new AMessage(kWhatSignalEndOfInputStream, this))->post(); 495} 496 497void ACodec::initiateStart() { 498 (new AMessage(kWhatStart, this))->post(); 499} 500 501void ACodec::signalFlush() { 502 ALOGV("[%s] signalFlush", mComponentName.c_str()); 503 (new AMessage(kWhatFlush, this))->post(); 504} 505 506void ACodec::signalResume() { 507 (new AMessage(kWhatResume, this))->post(); 508} 509 510void ACodec::initiateShutdown(bool keepComponentAllocated) { 511 sp<AMessage> msg = new AMessage(kWhatShutdown, this); 512 msg->setInt32("keepComponentAllocated", keepComponentAllocated); 513 msg->post(); 514 if (!keepComponentAllocated) { 515 // ensure shutdown completes in 3 seconds 516 (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000); 517 } 518} 519 520void ACodec::signalRequestIDRFrame() { 521 (new AMessage(kWhatRequestIDRFrame, this))->post(); 522} 523 524// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 525// Some codecs may return input buffers before having them processed. 526// This causes a halt if we already signaled an EOS on the input 527// port. For now keep submitting an output buffer if there was an 528// EOS on the input port, but not yet on the output port. 529void ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() { 530 if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] && 531 mMetaDataBuffersToSubmit > 0) { 532 (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, this))->post(); 533 } 534} 535 536status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) { 537 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 538 539 CHECK(mDealer[portIndex] == NULL); 540 CHECK(mBuffers[portIndex].isEmpty()); 541 542 status_t err; 543 if (mNativeWindow != NULL && portIndex == kPortIndexOutput) { 544 if (mStoreMetaDataInOutputBuffers) { 545 err = allocateOutputMetaDataBuffers(); 546 } else { 547 err = allocateOutputBuffersFromNativeWindow(); 548 } 549 } else { 550 OMX_PARAM_PORTDEFINITIONTYPE def; 551 InitOMXParams(&def); 552 def.nPortIndex = portIndex; 553 554 err = mOMX->getParameter( 555 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 556 557 if (err == OK) { 558 ALOGV("[%s] Allocating %u buffers of size %u on %s port", 559 mComponentName.c_str(), 560 def.nBufferCountActual, def.nBufferSize, 561 portIndex == kPortIndexInput ? "input" : "output"); 562 563 size_t totalSize = def.nBufferCountActual * def.nBufferSize; 564 mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec"); 565 566 for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { 567 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); 568 CHECK(mem.get() != NULL); 569 570 BufferInfo info; 571 info.mStatus = BufferInfo::OWNED_BY_US; 572 573 uint32_t requiresAllocateBufferBit = 574 (portIndex == kPortIndexInput) 575 ? OMXCodec::kRequiresAllocateBufferOnInputPorts 576 : OMXCodec::kRequiresAllocateBufferOnOutputPorts; 577 578 if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) 579 || mUseMetadataOnEncoderOutput) { 580 mem.clear(); 581 582 void *ptr; 583 err = mOMX->allocateBuffer( 584 mNode, portIndex, def.nBufferSize, &info.mBufferID, 585 &ptr); 586 587 int32_t bufSize = mUseMetadataOnEncoderOutput ? 588 (4 + sizeof(buffer_handle_t)) : def.nBufferSize; 589 590 info.mData = new ABuffer(ptr, bufSize); 591 } else if (mQuirks & requiresAllocateBufferBit) { 592 err = mOMX->allocateBufferWithBackup( 593 mNode, portIndex, mem, &info.mBufferID); 594 } else { 595 err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID); 596 } 597 598 if (mem != NULL) { 599 info.mData = new ABuffer(mem->pointer(), def.nBufferSize); 600 } 601 602 mBuffers[portIndex].push(info); 603 } 604 } 605 } 606 607 if (err != OK) { 608 return err; 609 } 610 611 sp<AMessage> notify = mNotify->dup(); 612 notify->setInt32("what", CodecBase::kWhatBuffersAllocated); 613 614 notify->setInt32("portIndex", portIndex); 615 616 sp<PortDescription> desc = new PortDescription; 617 618 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 619 const BufferInfo &info = mBuffers[portIndex][i]; 620 621 desc->addBuffer(info.mBufferID, info.mData); 622 } 623 624 notify->setObject("portDesc", desc); 625 notify->post(); 626 627 return OK; 628} 629 630status_t ACodec::configureOutputBuffersFromNativeWindow( 631 OMX_U32 *bufferCount, OMX_U32 *bufferSize, 632 OMX_U32 *minUndequeuedBuffers) { 633 OMX_PARAM_PORTDEFINITIONTYPE def; 634 InitOMXParams(&def); 635 def.nPortIndex = kPortIndexOutput; 636 637 status_t err = mOMX->getParameter( 638 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 639 640 if (err != OK) { 641 return err; 642 } 643 644 err = native_window_set_buffers_dimensions( 645 mNativeWindow.get(), 646 def.format.video.nFrameWidth, 647 def.format.video.nFrameHeight); 648 649 if (err != 0) { 650 ALOGE("native_window_set_buffers_dimensions failed: %s (%d)", 651 strerror(-err), -err); 652 return err; 653 } 654 655 err = native_window_set_buffers_format( 656 mNativeWindow.get(), 657 def.format.video.eColorFormat); 658 659 if (err != 0) { 660 ALOGE("native_window_set_buffers_format failed: %s (%d)", 661 strerror(-err), -err); 662 return err; 663 } 664 665 if (mRotationDegrees != 0) { 666 uint32_t transform = 0; 667 switch (mRotationDegrees) { 668 case 0: transform = 0; break; 669 case 90: transform = HAL_TRANSFORM_ROT_90; break; 670 case 180: transform = HAL_TRANSFORM_ROT_180; break; 671 case 270: transform = HAL_TRANSFORM_ROT_270; break; 672 default: transform = 0; break; 673 } 674 675 if (transform > 0) { 676 err = native_window_set_buffers_transform( 677 mNativeWindow.get(), transform); 678 if (err != 0) { 679 ALOGE("native_window_set_buffers_transform failed: %s (%d)", 680 strerror(-err), -err); 681 return err; 682 } 683 } 684 } 685 686 // Set up the native window. 687 OMX_U32 usage = 0; 688 err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage); 689 if (err != 0) { 690 ALOGW("querying usage flags from OMX IL component failed: %d", err); 691 // XXX: Currently this error is logged, but not fatal. 692 usage = 0; 693 } 694 int omxUsage = usage; 695 696 if (mFlags & kFlagIsGrallocUsageProtected) { 697 usage |= GRALLOC_USAGE_PROTECTED; 698 } 699 700 // Make sure to check whether either Stagefright or the video decoder 701 // requested protected buffers. 702 if (usage & GRALLOC_USAGE_PROTECTED) { 703 // Verify that the ANativeWindow sends images directly to 704 // SurfaceFlinger. 705 int queuesToNativeWindow = 0; 706 err = mNativeWindow->query( 707 mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, 708 &queuesToNativeWindow); 709 if (err != 0) { 710 ALOGE("error authenticating native window: %d", err); 711 return err; 712 } 713 if (queuesToNativeWindow != 1) { 714 ALOGE("native window could not be authenticated"); 715 return PERMISSION_DENIED; 716 } 717 } 718 719 int consumerUsage = 0; 720 err = mNativeWindow->query( 721 mNativeWindow.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS, 722 &consumerUsage); 723 if (err != 0) { 724 ALOGW("failed to get consumer usage bits. ignoring"); 725 err = 0; 726 } 727 728 ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec) + %#x(Consumer) = %#x", 729 omxUsage, usage, consumerUsage, usage | consumerUsage); 730 usage |= consumerUsage; 731 err = native_window_set_usage( 732 mNativeWindow.get(), 733 usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP); 734 735 if (err != 0) { 736 ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err); 737 return err; 738 } 739 740 // Exits here for tunneled video playback codecs -- i.e. skips native window 741 // buffer allocation step as this is managed by the tunneled OMX omponent 742 // itself and explicitly sets def.nBufferCountActual to 0. 743 if (mTunneled) { 744 ALOGV("Tunneled Playback: skipping native window buffer allocation."); 745 def.nBufferCountActual = 0; 746 err = mOMX->setParameter( 747 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 748 749 *minUndequeuedBuffers = 0; 750 *bufferCount = 0; 751 *bufferSize = 0; 752 return err; 753 } 754 755 *minUndequeuedBuffers = 0; 756 err = mNativeWindow->query( 757 mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 758 (int *)minUndequeuedBuffers); 759 760 if (err != 0) { 761 ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 762 strerror(-err), -err); 763 return err; 764 } 765 766 // FIXME: assume that surface is controlled by app (native window 767 // returns the number for the case when surface is not controlled by app) 768 // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported 769 // For now, try to allocate 1 more buffer, but don't fail if unsuccessful 770 771 // Use conservative allocation while also trying to reduce starvation 772 // 773 // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the 774 // minimum needed for the consumer to be able to work 775 // 2. try to allocate two (2) additional buffers to reduce starvation from 776 // the consumer 777 // plus an extra buffer to account for incorrect minUndequeuedBufs 778 for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) { 779 OMX_U32 newBufferCount = 780 def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers; 781 def.nBufferCountActual = newBufferCount; 782 err = mOMX->setParameter( 783 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 784 785 if (err == OK) { 786 *minUndequeuedBuffers += extraBuffers; 787 break; 788 } 789 790 ALOGW("[%s] setting nBufferCountActual to %u failed: %d", 791 mComponentName.c_str(), newBufferCount, err); 792 /* exit condition */ 793 if (extraBuffers == 0) { 794 return err; 795 } 796 } 797 798 err = native_window_set_buffer_count( 799 mNativeWindow.get(), def.nBufferCountActual); 800 801 if (err != 0) { 802 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 803 -err); 804 return err; 805 } 806 807 *bufferCount = def.nBufferCountActual; 808 *bufferSize = def.nBufferSize; 809 return err; 810} 811 812status_t ACodec::allocateOutputBuffersFromNativeWindow() { 813 OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers; 814 status_t err = configureOutputBuffersFromNativeWindow( 815 &bufferCount, &bufferSize, &minUndequeuedBuffers); 816 if (err != 0) 817 return err; 818 mNumUndequeuedBuffers = minUndequeuedBuffers; 819 820 if (!mStoreMetaDataInOutputBuffers) { 821 static_cast<Surface*>(mNativeWindow.get()) 822 ->getIGraphicBufferProducer()->allowAllocation(true); 823 } 824 825 ALOGV("[%s] Allocating %u buffers from a native window of size %u on " 826 "output port", 827 mComponentName.c_str(), bufferCount, bufferSize); 828 829 // Dequeue buffers and send them to OMX 830 for (OMX_U32 i = 0; i < bufferCount; i++) { 831 ANativeWindowBuffer *buf; 832 err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf); 833 if (err != 0) { 834 ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 835 break; 836 } 837 838 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 839 BufferInfo info; 840 info.mStatus = BufferInfo::OWNED_BY_US; 841 info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */); 842 info.mGraphicBuffer = graphicBuffer; 843 mBuffers[kPortIndexOutput].push(info); 844 845 IOMX::buffer_id bufferId; 846 err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer, 847 &bufferId); 848 if (err != 0) { 849 ALOGE("registering GraphicBuffer %u with OMX IL component failed: " 850 "%d", i, err); 851 break; 852 } 853 854 mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId; 855 856 ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)", 857 mComponentName.c_str(), 858 bufferId, graphicBuffer.get()); 859 } 860 861 OMX_U32 cancelStart; 862 OMX_U32 cancelEnd; 863 864 if (err != 0) { 865 // If an error occurred while dequeuing we need to cancel any buffers 866 // that were dequeued. 867 cancelStart = 0; 868 cancelEnd = mBuffers[kPortIndexOutput].size(); 869 } else { 870 // Return the required minimum undequeued buffers to the native window. 871 cancelStart = bufferCount - minUndequeuedBuffers; 872 cancelEnd = bufferCount; 873 } 874 875 for (OMX_U32 i = cancelStart; i < cancelEnd; i++) { 876 BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 877 status_t error = cancelBufferToNativeWindow(info); 878 if (err == 0) { 879 err = error; 880 } 881 } 882 883 if (!mStoreMetaDataInOutputBuffers) { 884 static_cast<Surface*>(mNativeWindow.get()) 885 ->getIGraphicBufferProducer()->allowAllocation(false); 886 } 887 888 return err; 889} 890 891status_t ACodec::allocateOutputMetaDataBuffers() { 892 OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers; 893 status_t err = configureOutputBuffersFromNativeWindow( 894 &bufferCount, &bufferSize, &minUndequeuedBuffers); 895 if (err != 0) 896 return err; 897 mNumUndequeuedBuffers = minUndequeuedBuffers; 898 899 ALOGV("[%s] Allocating %u meta buffers on output port", 900 mComponentName.c_str(), bufferCount); 901 902 size_t totalSize = bufferCount * 8; 903 mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec"); 904 905 // Dequeue buffers and send them to OMX 906 for (OMX_U32 i = 0; i < bufferCount; i++) { 907 BufferInfo info; 908 info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 909 info.mGraphicBuffer = NULL; 910 info.mDequeuedAt = mDequeueCounter; 911 912 sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate( 913 sizeof(struct VideoDecoderOutputMetaData)); 914 CHECK(mem.get() != NULL); 915 info.mData = new ABuffer(mem->pointer(), mem->size()); 916 917 // we use useBuffer for metadata regardless of quirks 918 err = mOMX->useBuffer( 919 mNode, kPortIndexOutput, mem, &info.mBufferID); 920 921 mBuffers[kPortIndexOutput].push(info); 922 923 ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)", 924 mComponentName.c_str(), info.mBufferID, mem->pointer()); 925 } 926 927 mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers; 928 return err; 929} 930 931status_t ACodec::submitOutputMetaDataBuffer() { 932 CHECK(mStoreMetaDataInOutputBuffers); 933 if (mMetaDataBuffersToSubmit == 0) 934 return OK; 935 936 BufferInfo *info = dequeueBufferFromNativeWindow(); 937 if (info == NULL) 938 return ERROR_IO; 939 940 ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p", 941 mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get()); 942 943 --mMetaDataBuffersToSubmit; 944 CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID), 945 (status_t)OK); 946 947 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 948 return OK; 949} 950 951status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) { 952 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 953 954 ALOGV("[%s] Calling cancelBuffer on buffer %u", 955 mComponentName.c_str(), info->mBufferID); 956 957 int err = mNativeWindow->cancelBuffer( 958 mNativeWindow.get(), info->mGraphicBuffer.get(), -1); 959 960 ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window", 961 mComponentName.c_str(), info->mBufferID); 962 963 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 964 965 return err; 966} 967 968ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() { 969 ANativeWindowBuffer *buf; 970 CHECK(mNativeWindow.get() != NULL); 971 972 if (mTunneled) { 973 ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel" 974 " video playback mode mode!"); 975 return NULL; 976 } 977 978 if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) { 979 ALOGE("dequeueBuffer failed."); 980 return NULL; 981 } 982 983 BufferInfo *oldest = NULL; 984 for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { 985 BufferInfo *info = 986 &mBuffers[kPortIndexOutput].editItemAt(i); 987 988 if (info->mGraphicBuffer != NULL && 989 info->mGraphicBuffer->handle == buf->handle) { 990 CHECK_EQ((int)info->mStatus, 991 (int)BufferInfo::OWNED_BY_NATIVE_WINDOW); 992 993 info->mStatus = BufferInfo::OWNED_BY_US; 994 995 return info; 996 } 997 998 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW && 999 (oldest == NULL || 1000 // avoid potential issues from counter rolling over 1001 mDequeueCounter - info->mDequeuedAt > 1002 mDequeueCounter - oldest->mDequeuedAt)) { 1003 oldest = info; 1004 } 1005 } 1006 1007 if (oldest) { 1008 CHECK(mStoreMetaDataInOutputBuffers); 1009 1010 // discard buffer in LRU info and replace with new buffer 1011 oldest->mGraphicBuffer = new GraphicBuffer(buf, false); 1012 oldest->mStatus = BufferInfo::OWNED_BY_US; 1013 1014 mOMX->updateGraphicBufferInMeta( 1015 mNode, kPortIndexOutput, oldest->mGraphicBuffer, 1016 oldest->mBufferID); 1017 1018 VideoDecoderOutputMetaData *metaData = 1019 reinterpret_cast<VideoDecoderOutputMetaData *>( 1020 oldest->mData->base()); 1021 CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource); 1022 1023 ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)", 1024 (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]), 1025 mDequeueCounter - oldest->mDequeuedAt, 1026 metaData->pHandle, 1027 oldest->mGraphicBuffer->handle, oldest->mData->base()); 1028 1029 return oldest; 1030 } 1031 1032 TRESPASS(); 1033 1034 return NULL; 1035} 1036 1037status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) { 1038 for (size_t i = mBuffers[portIndex].size(); i-- > 0;) { 1039 CHECK_EQ((status_t)OK, freeBuffer(portIndex, i)); 1040 } 1041 1042 mDealer[portIndex].clear(); 1043 1044 return OK; 1045} 1046 1047status_t ACodec::freeOutputBuffersNotOwnedByComponent() { 1048 for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { 1049 BufferInfo *info = 1050 &mBuffers[kPortIndexOutput].editItemAt(i); 1051 1052 // At this time some buffers may still be with the component 1053 // or being drained. 1054 if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT && 1055 info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) { 1056 CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i)); 1057 } 1058 } 1059 1060 return OK; 1061} 1062 1063status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) { 1064 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 1065 1066 CHECK(info->mStatus == BufferInfo::OWNED_BY_US 1067 || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW); 1068 1069 if (portIndex == kPortIndexOutput && mNativeWindow != NULL 1070 && info->mStatus == BufferInfo::OWNED_BY_US) { 1071 cancelBufferToNativeWindow(info); 1072 } 1073 1074 CHECK_EQ(mOMX->freeBuffer( 1075 mNode, portIndex, info->mBufferID), 1076 (status_t)OK); 1077 1078 mBuffers[portIndex].removeAt(i); 1079 1080 return OK; 1081} 1082 1083ACodec::BufferInfo *ACodec::findBufferByID( 1084 uint32_t portIndex, IOMX::buffer_id bufferID, 1085 ssize_t *index) { 1086 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 1087 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 1088 1089 if (info->mBufferID == bufferID) { 1090 if (index != NULL) { 1091 *index = i; 1092 } 1093 return info; 1094 } 1095 } 1096 1097 TRESPASS(); 1098 1099 return NULL; 1100} 1101 1102status_t ACodec::setComponentRole( 1103 bool isEncoder, const char *mime) { 1104 struct MimeToRole { 1105 const char *mime; 1106 const char *decoderRole; 1107 const char *encoderRole; 1108 }; 1109 1110 static const MimeToRole kMimeToRole[] = { 1111 { MEDIA_MIMETYPE_AUDIO_MPEG, 1112 "audio_decoder.mp3", "audio_encoder.mp3" }, 1113 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I, 1114 "audio_decoder.mp1", "audio_encoder.mp1" }, 1115 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II, 1116 "audio_decoder.mp2", "audio_encoder.mp2" }, 1117 { MEDIA_MIMETYPE_AUDIO_AMR_NB, 1118 "audio_decoder.amrnb", "audio_encoder.amrnb" }, 1119 { MEDIA_MIMETYPE_AUDIO_AMR_WB, 1120 "audio_decoder.amrwb", "audio_encoder.amrwb" }, 1121 { MEDIA_MIMETYPE_AUDIO_AAC, 1122 "audio_decoder.aac", "audio_encoder.aac" }, 1123 { MEDIA_MIMETYPE_AUDIO_VORBIS, 1124 "audio_decoder.vorbis", "audio_encoder.vorbis" }, 1125 { MEDIA_MIMETYPE_AUDIO_OPUS, 1126 "audio_decoder.opus", "audio_encoder.opus" }, 1127 { MEDIA_MIMETYPE_AUDIO_G711_MLAW, 1128 "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" }, 1129 { MEDIA_MIMETYPE_AUDIO_G711_ALAW, 1130 "audio_decoder.g711alaw", "audio_encoder.g711alaw" }, 1131 { MEDIA_MIMETYPE_VIDEO_AVC, 1132 "video_decoder.avc", "video_encoder.avc" }, 1133 { MEDIA_MIMETYPE_VIDEO_HEVC, 1134 "video_decoder.hevc", "video_encoder.hevc" }, 1135 { MEDIA_MIMETYPE_VIDEO_MPEG4, 1136 "video_decoder.mpeg4", "video_encoder.mpeg4" }, 1137 { MEDIA_MIMETYPE_VIDEO_H263, 1138 "video_decoder.h263", "video_encoder.h263" }, 1139 { MEDIA_MIMETYPE_VIDEO_VP8, 1140 "video_decoder.vp8", "video_encoder.vp8" }, 1141 { MEDIA_MIMETYPE_VIDEO_VP9, 1142 "video_decoder.vp9", "video_encoder.vp9" }, 1143 { MEDIA_MIMETYPE_AUDIO_RAW, 1144 "audio_decoder.raw", "audio_encoder.raw" }, 1145 { MEDIA_MIMETYPE_AUDIO_FLAC, 1146 "audio_decoder.flac", "audio_encoder.flac" }, 1147 { MEDIA_MIMETYPE_AUDIO_MSGSM, 1148 "audio_decoder.gsm", "audio_encoder.gsm" }, 1149 { MEDIA_MIMETYPE_VIDEO_MPEG2, 1150 "video_decoder.mpeg2", "video_encoder.mpeg2" }, 1151 { MEDIA_MIMETYPE_AUDIO_AC3, 1152 "audio_decoder.ac3", "audio_encoder.ac3" }, 1153 { MEDIA_MIMETYPE_AUDIO_EAC3, 1154 "audio_decoder.eac3", "audio_encoder.eac3" }, 1155 }; 1156 1157 static const size_t kNumMimeToRole = 1158 sizeof(kMimeToRole) / sizeof(kMimeToRole[0]); 1159 1160 size_t i; 1161 for (i = 0; i < kNumMimeToRole; ++i) { 1162 if (!strcasecmp(mime, kMimeToRole[i].mime)) { 1163 break; 1164 } 1165 } 1166 1167 if (i == kNumMimeToRole) { 1168 return ERROR_UNSUPPORTED; 1169 } 1170 1171 const char *role = 1172 isEncoder ? kMimeToRole[i].encoderRole 1173 : kMimeToRole[i].decoderRole; 1174 1175 if (role != NULL) { 1176 OMX_PARAM_COMPONENTROLETYPE roleParams; 1177 InitOMXParams(&roleParams); 1178 1179 strncpy((char *)roleParams.cRole, 1180 role, OMX_MAX_STRINGNAME_SIZE - 1); 1181 1182 roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 1183 1184 status_t err = mOMX->setParameter( 1185 mNode, OMX_IndexParamStandardComponentRole, 1186 &roleParams, sizeof(roleParams)); 1187 1188 if (err != OK) { 1189 ALOGW("[%s] Failed to set standard component role '%s'.", 1190 mComponentName.c_str(), role); 1191 1192 return err; 1193 } 1194 } 1195 1196 return OK; 1197} 1198 1199status_t ACodec::configureCodec( 1200 const char *mime, const sp<AMessage> &msg) { 1201 int32_t encoder; 1202 if (!msg->findInt32("encoder", &encoder)) { 1203 encoder = false; 1204 } 1205 1206 sp<AMessage> inputFormat = new AMessage(); 1207 sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged 1208 1209 mIsEncoder = encoder; 1210 1211 1212 status_t err = setComponentRole(encoder /* isEncoder */, mime); 1213 1214 if (err != OK) { 1215 return err; 1216 } 1217 1218 int32_t bitRate = 0; 1219 // FLAC encoder doesn't need a bitrate, other encoders do 1220 if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC) 1221 && !msg->findInt32("bitrate", &bitRate)) { 1222 return INVALID_OPERATION; 1223 } 1224 1225 int32_t storeMeta; 1226 if (encoder 1227 && msg->findInt32("store-metadata-in-buffers", &storeMeta) 1228 && storeMeta != 0) { 1229 err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE); 1230 1231 if (err != OK) { 1232 ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d", 1233 mComponentName.c_str(), err); 1234 1235 return err; 1236 } 1237 } 1238 1239 int32_t prependSPSPPS = 0; 1240 if (encoder 1241 && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS) 1242 && prependSPSPPS != 0) { 1243 OMX_INDEXTYPE index; 1244 err = mOMX->getExtensionIndex( 1245 mNode, 1246 "OMX.google.android.index.prependSPSPPSToIDRFrames", 1247 &index); 1248 1249 if (err == OK) { 1250 PrependSPSPPSToIDRFramesParams params; 1251 InitOMXParams(¶ms); 1252 params.bEnable = OMX_TRUE; 1253 1254 err = mOMX->setParameter( 1255 mNode, index, ¶ms, sizeof(params)); 1256 } 1257 1258 if (err != OK) { 1259 ALOGE("Encoder could not be configured to emit SPS/PPS before " 1260 "IDR frames. (err %d)", err); 1261 1262 return err; 1263 } 1264 } 1265 1266 // Only enable metadata mode on encoder output if encoder can prepend 1267 // sps/pps to idr frames, since in metadata mode the bitstream is in an 1268 // opaque handle, to which we don't have access. 1269 int32_t video = !strncasecmp(mime, "video/", 6); 1270 mIsVideo = video; 1271 if (encoder && video) { 1272 OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS 1273 && msg->findInt32("store-metadata-in-buffers-output", &storeMeta) 1274 && storeMeta != 0); 1275 1276 err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable); 1277 1278 if (err != OK) { 1279 ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d", 1280 mComponentName.c_str(), err); 1281 mUseMetadataOnEncoderOutput = 0; 1282 } else { 1283 mUseMetadataOnEncoderOutput = enable; 1284 } 1285 1286 if (!msg->findInt64( 1287 "repeat-previous-frame-after", 1288 &mRepeatFrameDelayUs)) { 1289 mRepeatFrameDelayUs = -1ll; 1290 } 1291 1292 if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) { 1293 mMaxPtsGapUs = -1ll; 1294 } 1295 1296 if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) { 1297 mMaxFps = -1; 1298 } 1299 1300 if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) { 1301 mTimePerCaptureUs = -1ll; 1302 } 1303 1304 if (!msg->findInt32( 1305 "create-input-buffers-suspended", 1306 (int32_t*)&mCreateInputBuffersSuspended)) { 1307 mCreateInputBuffersSuspended = false; 1308 } 1309 } 1310 1311 // NOTE: we only use native window for video decoders 1312 sp<RefBase> obj; 1313 bool haveNativeWindow = msg->findObject("native-window", &obj) 1314 && obj != NULL && video && !encoder; 1315 mStoreMetaDataInOutputBuffers = false; 1316 if (video && !encoder) { 1317 inputFormat->setInt32("adaptive-playback", false); 1318 1319 int32_t usageProtected; 1320 if (msg->findInt32("protected", &usageProtected) && usageProtected) { 1321 if (!haveNativeWindow) { 1322 ALOGE("protected output buffers must be sent to an ANativeWindow"); 1323 return PERMISSION_DENIED; 1324 } 1325 mFlags |= kFlagIsGrallocUsageProtected; 1326 mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 1327 } 1328 } 1329 if (haveNativeWindow) { 1330 sp<ANativeWindow> nativeWindow = 1331 static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get())); 1332 1333 // START of temporary support for automatic FRC - THIS WILL BE REMOVED 1334 int32_t autoFrc; 1335 if (msg->findInt32("auto-frc", &autoFrc)) { 1336 bool enabled = autoFrc; 1337 OMX_CONFIG_BOOLEANTYPE config; 1338 InitOMXParams(&config); 1339 config.bEnabled = (OMX_BOOL)enabled; 1340 status_t temp = mOMX->setConfig( 1341 mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion, 1342 &config, sizeof(config)); 1343 if (temp == OK) { 1344 outputFormat->setInt32("auto-frc", enabled); 1345 } else if (enabled) { 1346 ALOGI("codec does not support requested auto-frc (err %d)", temp); 1347 } 1348 } 1349 // END of temporary support for automatic FRC 1350 1351 int32_t tunneled; 1352 if (msg->findInt32("feature-tunneled-playback", &tunneled) && 1353 tunneled != 0) { 1354 ALOGI("Configuring TUNNELED video playback."); 1355 mTunneled = true; 1356 1357 int32_t audioHwSync = 0; 1358 if (!msg->findInt32("audio-hw-sync", &audioHwSync)) { 1359 ALOGW("No Audio HW Sync provided for video tunnel"); 1360 } 1361 err = configureTunneledVideoPlayback(audioHwSync, nativeWindow); 1362 if (err != OK) { 1363 ALOGE("configureTunneledVideoPlayback(%d,%p) failed!", 1364 audioHwSync, nativeWindow.get()); 1365 return err; 1366 } 1367 1368 int32_t maxWidth = 0, maxHeight = 0; 1369 if (msg->findInt32("max-width", &maxWidth) && 1370 msg->findInt32("max-height", &maxHeight)) { 1371 1372 err = mOMX->prepareForAdaptivePlayback( 1373 mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight); 1374 if (err != OK) { 1375 ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d", 1376 mComponentName.c_str(), err); 1377 // allow failure 1378 err = OK; 1379 } else { 1380 inputFormat->setInt32("max-width", maxWidth); 1381 inputFormat->setInt32("max-height", maxHeight); 1382 inputFormat->setInt32("adaptive-playback", true); 1383 } 1384 } 1385 } else { 1386 ALOGV("Configuring CPU controlled video playback."); 1387 mTunneled = false; 1388 1389 // Explicity reset the sideband handle of the window for 1390 // non-tunneled video in case the window was previously used 1391 // for a tunneled video playback. 1392 err = native_window_set_sideband_stream(nativeWindow.get(), NULL); 1393 if (err != OK) { 1394 ALOGE("set_sideband_stream(NULL) failed! (err %d).", err); 1395 return err; 1396 } 1397 1398 // Always try to enable dynamic output buffers on native surface 1399 err = mOMX->storeMetaDataInBuffers( 1400 mNode, kPortIndexOutput, OMX_TRUE); 1401 if (err != OK) { 1402 ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d", 1403 mComponentName.c_str(), err); 1404 1405 // if adaptive playback has been requested, try JB fallback 1406 // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS 1407 // LARGE MEMORY REQUIREMENT 1408 1409 // we will not do adaptive playback on software accessed 1410 // surfaces as they never had to respond to changes in the 1411 // crop window, and we don't trust that they will be able to. 1412 int usageBits = 0; 1413 bool canDoAdaptivePlayback; 1414 1415 if (nativeWindow->query( 1416 nativeWindow.get(), 1417 NATIVE_WINDOW_CONSUMER_USAGE_BITS, 1418 &usageBits) != OK) { 1419 canDoAdaptivePlayback = false; 1420 } else { 1421 canDoAdaptivePlayback = 1422 (usageBits & 1423 (GRALLOC_USAGE_SW_READ_MASK | 1424 GRALLOC_USAGE_SW_WRITE_MASK)) == 0; 1425 } 1426 1427 int32_t maxWidth = 0, maxHeight = 0; 1428 if (canDoAdaptivePlayback && 1429 msg->findInt32("max-width", &maxWidth) && 1430 msg->findInt32("max-height", &maxHeight)) { 1431 ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)", 1432 mComponentName.c_str(), maxWidth, maxHeight); 1433 1434 err = mOMX->prepareForAdaptivePlayback( 1435 mNode, kPortIndexOutput, OMX_TRUE, maxWidth, 1436 maxHeight); 1437 ALOGW_IF(err != OK, 1438 "[%s] prepareForAdaptivePlayback failed w/ err %d", 1439 mComponentName.c_str(), err); 1440 1441 if (err == OK) { 1442 inputFormat->setInt32("max-width", maxWidth); 1443 inputFormat->setInt32("max-height", maxHeight); 1444 inputFormat->setInt32("adaptive-playback", true); 1445 } 1446 } 1447 // allow failure 1448 err = OK; 1449 } else { 1450 ALOGV("[%s] storeMetaDataInBuffers succeeded", 1451 mComponentName.c_str()); 1452 mStoreMetaDataInOutputBuffers = true; 1453 inputFormat->setInt32("adaptive-playback", true); 1454 } 1455 1456 int32_t push; 1457 if (msg->findInt32("push-blank-buffers-on-shutdown", &push) 1458 && push != 0) { 1459 mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 1460 } 1461 } 1462 1463 int32_t rotationDegrees; 1464 if (msg->findInt32("rotation-degrees", &rotationDegrees)) { 1465 mRotationDegrees = rotationDegrees; 1466 } else { 1467 mRotationDegrees = 0; 1468 } 1469 } 1470 1471 if (video) { 1472 // determine need for software renderer 1473 bool usingSwRenderer = false; 1474 if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) { 1475 usingSwRenderer = true; 1476 haveNativeWindow = false; 1477 } 1478 1479 if (encoder) { 1480 err = setupVideoEncoder(mime, msg); 1481 } else { 1482 err = setupVideoDecoder(mime, msg, haveNativeWindow); 1483 } 1484 1485 if (err != OK) { 1486 return err; 1487 } 1488 1489 if (haveNativeWindow) { 1490 mNativeWindow = static_cast<Surface *>(obj.get()); 1491 CHECK(mNativeWindow != NULL); 1492 1493 native_window_set_scaling_mode( 1494 mNativeWindow.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 1495 } 1496 1497 // initialize native window now to get actual output format 1498 // TODO: this is needed for some encoders even though they don't use native window 1499 CHECK_EQ((status_t)OK, initNativeWindow()); 1500 1501 // fallback for devices that do not handle flex-YUV for native buffers 1502 if (haveNativeWindow) { 1503 int32_t requestedColorFormat = OMX_COLOR_FormatUnused; 1504 if (msg->findInt32("color-format", &requestedColorFormat) && 1505 requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) { 1506 CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK); 1507 int32_t colorFormat = OMX_COLOR_FormatUnused; 1508 OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused; 1509 CHECK(outputFormat->findInt32("color-format", &colorFormat)); 1510 ALOGD("[%s] Requested output format %#x and got %#x.", 1511 mComponentName.c_str(), requestedColorFormat, colorFormat); 1512 if (!isFlexibleColorFormat( 1513 mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent) 1514 || flexibleEquivalent != (OMX_U32)requestedColorFormat) { 1515 // device did not handle flex-YUV request for native window, fall back 1516 // to SW renderer 1517 ALOGI("[%s] Falling back to software renderer", mComponentName.c_str()); 1518 mNativeWindow.clear(); 1519 haveNativeWindow = false; 1520 usingSwRenderer = true; 1521 if (mStoreMetaDataInOutputBuffers) { 1522 err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_FALSE); 1523 mStoreMetaDataInOutputBuffers = false; 1524 // TODO: implement adaptive-playback support for bytebuffer mode. 1525 // This is done by SW codecs, but most HW codecs don't support it. 1526 inputFormat->setInt32("adaptive-playback", false); 1527 } 1528 if (err == OK) { 1529 err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE); 1530 } 1531 if (mFlags & kFlagIsGrallocUsageProtected) { 1532 // fallback is not supported for protected playback 1533 err = PERMISSION_DENIED; 1534 } else if (err == OK) { 1535 err = setupVideoDecoder(mime, msg, false); 1536 } 1537 } 1538 } 1539 } 1540 1541 if (usingSwRenderer) { 1542 outputFormat->setInt32("using-sw-renderer", 1); 1543 } 1544 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { 1545 int32_t numChannels, sampleRate; 1546 if (!msg->findInt32("channel-count", &numChannels) 1547 || !msg->findInt32("sample-rate", &sampleRate)) { 1548 // Since we did not always check for these, leave them optional 1549 // and have the decoder figure it all out. 1550 err = OK; 1551 } else { 1552 err = setupRawAudioFormat( 1553 encoder ? kPortIndexInput : kPortIndexOutput, 1554 sampleRate, 1555 numChannels); 1556 } 1557 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1558 int32_t numChannels, sampleRate; 1559 if (!msg->findInt32("channel-count", &numChannels) 1560 || !msg->findInt32("sample-rate", &sampleRate)) { 1561 err = INVALID_OPERATION; 1562 } else { 1563 int32_t isADTS, aacProfile; 1564 int32_t sbrMode; 1565 int32_t maxOutputChannelCount; 1566 int32_t pcmLimiterEnable; 1567 drcParams_t drc; 1568 if (!msg->findInt32("is-adts", &isADTS)) { 1569 isADTS = 0; 1570 } 1571 if (!msg->findInt32("aac-profile", &aacProfile)) { 1572 aacProfile = OMX_AUDIO_AACObjectNull; 1573 } 1574 if (!msg->findInt32("aac-sbr-mode", &sbrMode)) { 1575 sbrMode = -1; 1576 } 1577 1578 if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) { 1579 maxOutputChannelCount = -1; 1580 } 1581 if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) { 1582 // value is unknown 1583 pcmLimiterEnable = -1; 1584 } 1585 if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) { 1586 // value is unknown 1587 drc.encodedTargetLevel = -1; 1588 } 1589 if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) { 1590 // value is unknown 1591 drc.drcCut = -1; 1592 } 1593 if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) { 1594 // value is unknown 1595 drc.drcBoost = -1; 1596 } 1597 if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) { 1598 // value is unknown 1599 drc.heavyCompression = -1; 1600 } 1601 if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) { 1602 // value is unknown 1603 drc.targetRefLevel = -1; 1604 } 1605 1606 err = setupAACCodec( 1607 encoder, numChannels, sampleRate, bitRate, aacProfile, 1608 isADTS != 0, sbrMode, maxOutputChannelCount, drc, 1609 pcmLimiterEnable); 1610 } 1611 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 1612 err = setupAMRCodec(encoder, false /* isWAMR */, bitRate); 1613 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 1614 err = setupAMRCodec(encoder, true /* isWAMR */, bitRate); 1615 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW) 1616 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) { 1617 // These are PCM-like formats with a fixed sample rate but 1618 // a variable number of channels. 1619 1620 int32_t numChannels; 1621 if (!msg->findInt32("channel-count", &numChannels)) { 1622 err = INVALID_OPERATION; 1623 } else { 1624 int32_t sampleRate; 1625 if (!msg->findInt32("sample-rate", &sampleRate)) { 1626 sampleRate = 8000; 1627 } 1628 err = setupG711Codec(encoder, sampleRate, numChannels); 1629 } 1630 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) { 1631 int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1; 1632 if (encoder && 1633 (!msg->findInt32("channel-count", &numChannels) 1634 || !msg->findInt32("sample-rate", &sampleRate))) { 1635 ALOGE("missing channel count or sample rate for FLAC encoder"); 1636 err = INVALID_OPERATION; 1637 } else { 1638 if (encoder) { 1639 if (!msg->findInt32( 1640 "complexity", &compressionLevel) && 1641 !msg->findInt32( 1642 "flac-compression-level", &compressionLevel)) { 1643 compressionLevel = 5; // default FLAC compression level 1644 } else if (compressionLevel < 0) { 1645 ALOGW("compression level %d outside [0..8] range, " 1646 "using 0", 1647 compressionLevel); 1648 compressionLevel = 0; 1649 } else if (compressionLevel > 8) { 1650 ALOGW("compression level %d outside [0..8] range, " 1651 "using 8", 1652 compressionLevel); 1653 compressionLevel = 8; 1654 } 1655 } 1656 err = setupFlacCodec( 1657 encoder, numChannels, sampleRate, compressionLevel); 1658 } 1659 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) { 1660 int32_t numChannels, sampleRate; 1661 if (encoder 1662 || !msg->findInt32("channel-count", &numChannels) 1663 || !msg->findInt32("sample-rate", &sampleRate)) { 1664 err = INVALID_OPERATION; 1665 } else { 1666 err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 1667 } 1668 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) { 1669 int32_t numChannels; 1670 int32_t sampleRate; 1671 if (!msg->findInt32("channel-count", &numChannels) 1672 || !msg->findInt32("sample-rate", &sampleRate)) { 1673 err = INVALID_OPERATION; 1674 } else { 1675 err = setupAC3Codec(encoder, numChannels, sampleRate); 1676 } 1677 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) { 1678 int32_t numChannels; 1679 int32_t sampleRate; 1680 if (!msg->findInt32("channel-count", &numChannels) 1681 || !msg->findInt32("sample-rate", &sampleRate)) { 1682 err = INVALID_OPERATION; 1683 } else { 1684 err = setupEAC3Codec(encoder, numChannels, sampleRate); 1685 } 1686 } 1687 1688 if (err != OK) { 1689 return err; 1690 } 1691 1692 if (!msg->findInt32("encoder-delay", &mEncoderDelay)) { 1693 mEncoderDelay = 0; 1694 } 1695 1696 if (!msg->findInt32("encoder-padding", &mEncoderPadding)) { 1697 mEncoderPadding = 0; 1698 } 1699 1700 if (msg->findInt32("channel-mask", &mChannelMask)) { 1701 mChannelMaskPresent = true; 1702 } else { 1703 mChannelMaskPresent = false; 1704 } 1705 1706 int32_t maxInputSize; 1707 if (msg->findInt32("max-input-size", &maxInputSize)) { 1708 err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize); 1709 } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) { 1710 err = setMinBufferSize(kPortIndexInput, 8192); // XXX 1711 } 1712 1713 int32_t priority; 1714 if (msg->findInt32("priority", &priority)) { 1715 err = setPriority(priority); 1716 } 1717 1718 int32_t rateInt = -1; 1719 float rateFloat = -1; 1720 if (!msg->findFloat("operating-rate", &rateFloat)) { 1721 msg->findInt32("operating-rate", &rateInt); 1722 rateFloat = (float)rateInt; // 16MHz (FLINTMAX) is OK for upper bound. 1723 } 1724 if (rateFloat > 0) { 1725 err = setOperatingRate(rateFloat, video); 1726 } 1727 1728 mBaseOutputFormat = outputFormat; 1729 1730 CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK); 1731 CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK); 1732 mInputFormat = inputFormat; 1733 mOutputFormat = outputFormat; 1734 1735 return err; 1736} 1737 1738status_t ACodec::setPriority(int32_t priority) { 1739 if (priority < 0) { 1740 return BAD_VALUE; 1741 } 1742 OMX_PARAM_U32TYPE config; 1743 InitOMXParams(&config); 1744 config.nU32 = (OMX_U32)priority; 1745 status_t temp = mOMX->setConfig( 1746 mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority, 1747 &config, sizeof(config)); 1748 if (temp != OK) { 1749 ALOGI("codec does not support config priority (err %d)", temp); 1750 } 1751 return OK; 1752} 1753 1754status_t ACodec::setOperatingRate(float rateFloat, bool isVideo) { 1755 if (rateFloat < 0) { 1756 return BAD_VALUE; 1757 } 1758 OMX_U32 rate; 1759 if (isVideo) { 1760 if (rateFloat > 65535) { 1761 return BAD_VALUE; 1762 } 1763 rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f); 1764 } else { 1765 if (rateFloat > UINT_MAX) { 1766 return BAD_VALUE; 1767 } 1768 rate = (OMX_U32)(rateFloat); 1769 } 1770 OMX_PARAM_U32TYPE config; 1771 InitOMXParams(&config); 1772 config.nU32 = rate; 1773 status_t err = mOMX->setConfig( 1774 mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate, 1775 &config, sizeof(config)); 1776 if (err != OK) { 1777 ALOGI("codec does not support config operating rate (err %d)", err); 1778 } 1779 return OK; 1780} 1781 1782status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) { 1783 OMX_PARAM_PORTDEFINITIONTYPE def; 1784 InitOMXParams(&def); 1785 def.nPortIndex = portIndex; 1786 1787 status_t err = mOMX->getParameter( 1788 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1789 1790 if (err != OK) { 1791 return err; 1792 } 1793 1794 if (def.nBufferSize >= size) { 1795 return OK; 1796 } 1797 1798 def.nBufferSize = size; 1799 1800 err = mOMX->setParameter( 1801 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1802 1803 if (err != OK) { 1804 return err; 1805 } 1806 1807 err = mOMX->getParameter( 1808 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1809 1810 if (err != OK) { 1811 return err; 1812 } 1813 1814 CHECK(def.nBufferSize >= size); 1815 1816 return OK; 1817} 1818 1819status_t ACodec::selectAudioPortFormat( 1820 OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) { 1821 OMX_AUDIO_PARAM_PORTFORMATTYPE format; 1822 InitOMXParams(&format); 1823 1824 format.nPortIndex = portIndex; 1825 for (OMX_U32 index = 0;; ++index) { 1826 format.nIndex = index; 1827 1828 status_t err = mOMX->getParameter( 1829 mNode, OMX_IndexParamAudioPortFormat, 1830 &format, sizeof(format)); 1831 1832 if (err != OK) { 1833 return err; 1834 } 1835 1836 if (format.eEncoding == desiredFormat) { 1837 break; 1838 } 1839 } 1840 1841 return mOMX->setParameter( 1842 mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format)); 1843} 1844 1845status_t ACodec::setupAACCodec( 1846 bool encoder, int32_t numChannels, int32_t sampleRate, 1847 int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode, 1848 int32_t maxOutputChannelCount, const drcParams_t& drc, 1849 int32_t pcmLimiterEnable) { 1850 if (encoder && isADTS) { 1851 return -EINVAL; 1852 } 1853 1854 status_t err = setupRawAudioFormat( 1855 encoder ? kPortIndexInput : kPortIndexOutput, 1856 sampleRate, 1857 numChannels); 1858 1859 if (err != OK) { 1860 return err; 1861 } 1862 1863 if (encoder) { 1864 err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC); 1865 1866 if (err != OK) { 1867 return err; 1868 } 1869 1870 OMX_PARAM_PORTDEFINITIONTYPE def; 1871 InitOMXParams(&def); 1872 def.nPortIndex = kPortIndexOutput; 1873 1874 err = mOMX->getParameter( 1875 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1876 1877 if (err != OK) { 1878 return err; 1879 } 1880 1881 def.format.audio.bFlagErrorConcealment = OMX_TRUE; 1882 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 1883 1884 err = mOMX->setParameter( 1885 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1886 1887 if (err != OK) { 1888 return err; 1889 } 1890 1891 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 1892 InitOMXParams(&profile); 1893 profile.nPortIndex = kPortIndexOutput; 1894 1895 err = mOMX->getParameter( 1896 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1897 1898 if (err != OK) { 1899 return err; 1900 } 1901 1902 profile.nChannels = numChannels; 1903 1904 profile.eChannelMode = 1905 (numChannels == 1) 1906 ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo; 1907 1908 profile.nSampleRate = sampleRate; 1909 profile.nBitRate = bitRate; 1910 profile.nAudioBandWidth = 0; 1911 profile.nFrameLength = 0; 1912 profile.nAACtools = OMX_AUDIO_AACToolAll; 1913 profile.nAACERtools = OMX_AUDIO_AACERNone; 1914 profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile; 1915 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; 1916 switch (sbrMode) { 1917 case 0: 1918 // disable sbr 1919 profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR; 1920 profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR; 1921 break; 1922 case 1: 1923 // enable single-rate sbr 1924 profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR; 1925 profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR; 1926 break; 1927 case 2: 1928 // enable dual-rate sbr 1929 profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR; 1930 profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR; 1931 break; 1932 case -1: 1933 // enable both modes -> the codec will decide which mode should be used 1934 profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR; 1935 profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR; 1936 break; 1937 default: 1938 // unsupported sbr mode 1939 return BAD_VALUE; 1940 } 1941 1942 1943 err = mOMX->setParameter( 1944 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1945 1946 if (err != OK) { 1947 return err; 1948 } 1949 1950 return err; 1951 } 1952 1953 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 1954 InitOMXParams(&profile); 1955 profile.nPortIndex = kPortIndexInput; 1956 1957 err = mOMX->getParameter( 1958 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1959 1960 if (err != OK) { 1961 return err; 1962 } 1963 1964 profile.nChannels = numChannels; 1965 profile.nSampleRate = sampleRate; 1966 1967 profile.eAACStreamFormat = 1968 isADTS 1969 ? OMX_AUDIO_AACStreamFormatMP4ADTS 1970 : OMX_AUDIO_AACStreamFormatMP4FF; 1971 1972 OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation; 1973 presentation.nMaxOutputChannels = maxOutputChannelCount; 1974 presentation.nDrcCut = drc.drcCut; 1975 presentation.nDrcBoost = drc.drcBoost; 1976 presentation.nHeavyCompression = drc.heavyCompression; 1977 presentation.nTargetReferenceLevel = drc.targetRefLevel; 1978 presentation.nEncodedTargetLevel = drc.encodedTargetLevel; 1979 presentation.nPCMLimiterEnable = pcmLimiterEnable; 1980 1981 status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1982 if (res == OK) { 1983 // optional parameters, will not cause configuration failure 1984 mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation, 1985 &presentation, sizeof(presentation)); 1986 } else { 1987 ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res); 1988 } 1989 return res; 1990} 1991 1992status_t ACodec::setupAC3Codec( 1993 bool encoder, int32_t numChannels, int32_t sampleRate) { 1994 status_t err = setupRawAudioFormat( 1995 encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels); 1996 1997 if (err != OK) { 1998 return err; 1999 } 2000 2001 if (encoder) { 2002 ALOGW("AC3 encoding is not supported."); 2003 return INVALID_OPERATION; 2004 } 2005 2006 OMX_AUDIO_PARAM_ANDROID_AC3TYPE def; 2007 InitOMXParams(&def); 2008 def.nPortIndex = kPortIndexInput; 2009 2010 err = mOMX->getParameter( 2011 mNode, 2012 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 2013 &def, 2014 sizeof(def)); 2015 2016 if (err != OK) { 2017 return err; 2018 } 2019 2020 def.nChannels = numChannels; 2021 def.nSampleRate = sampleRate; 2022 2023 return mOMX->setParameter( 2024 mNode, 2025 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 2026 &def, 2027 sizeof(def)); 2028} 2029 2030status_t ACodec::setupEAC3Codec( 2031 bool encoder, int32_t numChannels, int32_t sampleRate) { 2032 status_t err = setupRawAudioFormat( 2033 encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels); 2034 2035 if (err != OK) { 2036 return err; 2037 } 2038 2039 if (encoder) { 2040 ALOGW("EAC3 encoding is not supported."); 2041 return INVALID_OPERATION; 2042 } 2043 2044 OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def; 2045 InitOMXParams(&def); 2046 def.nPortIndex = kPortIndexInput; 2047 2048 err = mOMX->getParameter( 2049 mNode, 2050 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, 2051 &def, 2052 sizeof(def)); 2053 2054 if (err != OK) { 2055 return err; 2056 } 2057 2058 def.nChannels = numChannels; 2059 def.nSampleRate = sampleRate; 2060 2061 return mOMX->setParameter( 2062 mNode, 2063 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, 2064 &def, 2065 sizeof(def)); 2066} 2067 2068static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate( 2069 bool isAMRWB, int32_t bps) { 2070 if (isAMRWB) { 2071 if (bps <= 6600) { 2072 return OMX_AUDIO_AMRBandModeWB0; 2073 } else if (bps <= 8850) { 2074 return OMX_AUDIO_AMRBandModeWB1; 2075 } else if (bps <= 12650) { 2076 return OMX_AUDIO_AMRBandModeWB2; 2077 } else if (bps <= 14250) { 2078 return OMX_AUDIO_AMRBandModeWB3; 2079 } else if (bps <= 15850) { 2080 return OMX_AUDIO_AMRBandModeWB4; 2081 } else if (bps <= 18250) { 2082 return OMX_AUDIO_AMRBandModeWB5; 2083 } else if (bps <= 19850) { 2084 return OMX_AUDIO_AMRBandModeWB6; 2085 } else if (bps <= 23050) { 2086 return OMX_AUDIO_AMRBandModeWB7; 2087 } 2088 2089 // 23850 bps 2090 return OMX_AUDIO_AMRBandModeWB8; 2091 } else { // AMRNB 2092 if (bps <= 4750) { 2093 return OMX_AUDIO_AMRBandModeNB0; 2094 } else if (bps <= 5150) { 2095 return OMX_AUDIO_AMRBandModeNB1; 2096 } else if (bps <= 5900) { 2097 return OMX_AUDIO_AMRBandModeNB2; 2098 } else if (bps <= 6700) { 2099 return OMX_AUDIO_AMRBandModeNB3; 2100 } else if (bps <= 7400) { 2101 return OMX_AUDIO_AMRBandModeNB4; 2102 } else if (bps <= 7950) { 2103 return OMX_AUDIO_AMRBandModeNB5; 2104 } else if (bps <= 10200) { 2105 return OMX_AUDIO_AMRBandModeNB6; 2106 } 2107 2108 // 12200 bps 2109 return OMX_AUDIO_AMRBandModeNB7; 2110 } 2111} 2112 2113status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) { 2114 OMX_AUDIO_PARAM_AMRTYPE def; 2115 InitOMXParams(&def); 2116 def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput; 2117 2118 status_t err = 2119 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2120 2121 if (err != OK) { 2122 return err; 2123 } 2124 2125 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 2126 def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate); 2127 2128 err = mOMX->setParameter( 2129 mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 2130 2131 if (err != OK) { 2132 return err; 2133 } 2134 2135 return setupRawAudioFormat( 2136 encoder ? kPortIndexInput : kPortIndexOutput, 2137 isWAMR ? 16000 : 8000 /* sampleRate */, 2138 1 /* numChannels */); 2139} 2140 2141status_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) { 2142 CHECK(!encoder); // XXX TODO 2143 2144 return setupRawAudioFormat( 2145 kPortIndexInput, sampleRate, numChannels); 2146} 2147 2148status_t ACodec::setupFlacCodec( 2149 bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) { 2150 2151 if (encoder) { 2152 OMX_AUDIO_PARAM_FLACTYPE def; 2153 InitOMXParams(&def); 2154 def.nPortIndex = kPortIndexOutput; 2155 2156 // configure compression level 2157 status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def)); 2158 if (err != OK) { 2159 ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err); 2160 return err; 2161 } 2162 def.nCompressionLevel = compressionLevel; 2163 err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def)); 2164 if (err != OK) { 2165 ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err); 2166 return err; 2167 } 2168 } 2169 2170 return setupRawAudioFormat( 2171 encoder ? kPortIndexInput : kPortIndexOutput, 2172 sampleRate, 2173 numChannels); 2174} 2175 2176status_t ACodec::setupRawAudioFormat( 2177 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 2178 OMX_PARAM_PORTDEFINITIONTYPE def; 2179 InitOMXParams(&def); 2180 def.nPortIndex = portIndex; 2181 2182 status_t err = mOMX->getParameter( 2183 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2184 2185 if (err != OK) { 2186 return err; 2187 } 2188 2189 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 2190 2191 err = mOMX->setParameter( 2192 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2193 2194 if (err != OK) { 2195 return err; 2196 } 2197 2198 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 2199 InitOMXParams(&pcmParams); 2200 pcmParams.nPortIndex = portIndex; 2201 2202 err = mOMX->getParameter( 2203 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2204 2205 if (err != OK) { 2206 return err; 2207 } 2208 2209 pcmParams.nChannels = numChannels; 2210 pcmParams.eNumData = OMX_NumericalDataSigned; 2211 pcmParams.bInterleaved = OMX_TRUE; 2212 pcmParams.nBitPerSample = 16; 2213 pcmParams.nSamplingRate = sampleRate; 2214 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 2215 2216 if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) { 2217 return OMX_ErrorNone; 2218 } 2219 2220 return mOMX->setParameter( 2221 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 2222} 2223 2224status_t ACodec::configureTunneledVideoPlayback( 2225 int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) { 2226 native_handle_t* sidebandHandle; 2227 2228 status_t err = mOMX->configureVideoTunnelMode( 2229 mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle); 2230 if (err != OK) { 2231 ALOGE("configureVideoTunnelMode failed! (err %d).", err); 2232 return err; 2233 } 2234 2235 err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle); 2236 if (err != OK) { 2237 ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).", 2238 sidebandHandle, err); 2239 return err; 2240 } 2241 2242 return OK; 2243} 2244 2245status_t ACodec::setVideoPortFormatType( 2246 OMX_U32 portIndex, 2247 OMX_VIDEO_CODINGTYPE compressionFormat, 2248 OMX_COLOR_FORMATTYPE colorFormat, 2249 bool usingNativeBuffers) { 2250 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 2251 InitOMXParams(&format); 2252 format.nPortIndex = portIndex; 2253 format.nIndex = 0; 2254 bool found = false; 2255 2256 OMX_U32 index = 0; 2257 for (;;) { 2258 format.nIndex = index; 2259 status_t err = mOMX->getParameter( 2260 mNode, OMX_IndexParamVideoPortFormat, 2261 &format, sizeof(format)); 2262 2263 if (err != OK) { 2264 return err; 2265 } 2266 2267 // substitute back flexible color format to codec supported format 2268 OMX_U32 flexibleEquivalent; 2269 if (compressionFormat == OMX_VIDEO_CodingUnused 2270 && isFlexibleColorFormat( 2271 mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent) 2272 && colorFormat == flexibleEquivalent) { 2273 ALOGI("[%s] using color format %#x in place of %#x", 2274 mComponentName.c_str(), format.eColorFormat, colorFormat); 2275 colorFormat = format.eColorFormat; 2276 } 2277 2278 // The following assertion is violated by TI's video decoder. 2279 // CHECK_EQ(format.nIndex, index); 2280 2281 if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) { 2282 if (portIndex == kPortIndexInput 2283 && colorFormat == format.eColorFormat) { 2284 // eCompressionFormat does not seem right. 2285 found = true; 2286 break; 2287 } 2288 if (portIndex == kPortIndexOutput 2289 && compressionFormat == format.eCompressionFormat) { 2290 // eColorFormat does not seem right. 2291 found = true; 2292 break; 2293 } 2294 } 2295 2296 if (format.eCompressionFormat == compressionFormat 2297 && format.eColorFormat == colorFormat) { 2298 found = true; 2299 break; 2300 } 2301 2302 ++index; 2303 } 2304 2305 if (!found) { 2306 return UNKNOWN_ERROR; 2307 } 2308 2309 status_t err = mOMX->setParameter( 2310 mNode, OMX_IndexParamVideoPortFormat, 2311 &format, sizeof(format)); 2312 2313 return err; 2314} 2315 2316// Set optimal output format. OMX component lists output formats in the order 2317// of preference, but this got more complicated since the introduction of flexible 2318// YUV formats. We support a legacy behavior for applications that do not use 2319// surface output, do not specify an output format, but expect a "usable" standard 2320// OMX format. SW readable and standard formats must be flex-YUV. 2321// 2322// Suggested preference order: 2323// - optimal format for texture rendering (mediaplayer behavior) 2324// - optimal SW readable & texture renderable format (flex-YUV support) 2325// - optimal SW readable non-renderable format (flex-YUV bytebuffer support) 2326// - legacy "usable" standard formats 2327// 2328// For legacy support, we prefer a standard format, but will settle for a SW readable 2329// flex-YUV format. 2330status_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) { 2331 OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat; 2332 InitOMXParams(&format); 2333 format.nPortIndex = kPortIndexOutput; 2334 2335 InitOMXParams(&legacyFormat); 2336 // this field will change when we find a suitable legacy format 2337 legacyFormat.eColorFormat = OMX_COLOR_FormatUnused; 2338 2339 for (OMX_U32 index = 0; ; ++index) { 2340 format.nIndex = index; 2341 status_t err = mOMX->getParameter( 2342 mNode, OMX_IndexParamVideoPortFormat, 2343 &format, sizeof(format)); 2344 if (err != OK) { 2345 // no more formats, pick legacy format if found 2346 if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) { 2347 memcpy(&format, &legacyFormat, sizeof(format)); 2348 break; 2349 } 2350 return err; 2351 } 2352 if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) { 2353 return OMX_ErrorBadParameter; 2354 } 2355 if (!getLegacyFlexibleFormat) { 2356 break; 2357 } 2358 // standard formats that were exposed to users before 2359 if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar 2360 || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar 2361 || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar 2362 || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar 2363 || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { 2364 break; 2365 } 2366 // find best legacy non-standard format 2367 OMX_U32 flexibleEquivalent; 2368 if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused 2369 && isFlexibleColorFormat( 2370 mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */, 2371 &flexibleEquivalent) 2372 && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) { 2373 memcpy(&legacyFormat, &format, sizeof(format)); 2374 } 2375 } 2376 return mOMX->setParameter( 2377 mNode, OMX_IndexParamVideoPortFormat, 2378 &format, sizeof(format)); 2379} 2380 2381static const struct VideoCodingMapEntry { 2382 const char *mMime; 2383 OMX_VIDEO_CODINGTYPE mVideoCodingType; 2384} kVideoCodingMapEntry[] = { 2385 { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC }, 2386 { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC }, 2387 { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 }, 2388 { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 }, 2389 { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 }, 2390 { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 }, 2391 { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 }, 2392}; 2393 2394static status_t GetVideoCodingTypeFromMime( 2395 const char *mime, OMX_VIDEO_CODINGTYPE *codingType) { 2396 for (size_t i = 0; 2397 i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]); 2398 ++i) { 2399 if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) { 2400 *codingType = kVideoCodingMapEntry[i].mVideoCodingType; 2401 return OK; 2402 } 2403 } 2404 2405 *codingType = OMX_VIDEO_CodingUnused; 2406 2407 return ERROR_UNSUPPORTED; 2408} 2409 2410static status_t GetMimeTypeForVideoCoding( 2411 OMX_VIDEO_CODINGTYPE codingType, AString *mime) { 2412 for (size_t i = 0; 2413 i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]); 2414 ++i) { 2415 if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) { 2416 *mime = kVideoCodingMapEntry[i].mMime; 2417 return OK; 2418 } 2419 } 2420 2421 mime->clear(); 2422 2423 return ERROR_UNSUPPORTED; 2424} 2425 2426status_t ACodec::setupVideoDecoder( 2427 const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) { 2428 int32_t width, height; 2429 if (!msg->findInt32("width", &width) 2430 || !msg->findInt32("height", &height)) { 2431 return INVALID_OPERATION; 2432 } 2433 2434 OMX_VIDEO_CODINGTYPE compressionFormat; 2435 status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat); 2436 2437 if (err != OK) { 2438 return err; 2439 } 2440 2441 err = setVideoPortFormatType( 2442 kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 2443 2444 if (err != OK) { 2445 return err; 2446 } 2447 2448 int32_t tmp; 2449 if (msg->findInt32("color-format", &tmp)) { 2450 OMX_COLOR_FORMATTYPE colorFormat = 2451 static_cast<OMX_COLOR_FORMATTYPE>(tmp); 2452 err = setVideoPortFormatType( 2453 kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow); 2454 if (err != OK) { 2455 ALOGW("[%s] does not support color format %d", 2456 mComponentName.c_str(), colorFormat); 2457 err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */); 2458 } 2459 } else { 2460 err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */); 2461 } 2462 2463 if (err != OK) { 2464 return err; 2465 } 2466 2467 int32_t frameRateInt; 2468 float frameRateFloat; 2469 if (!msg->findFloat("frame-rate", &frameRateFloat)) { 2470 if (!msg->findInt32("frame-rate", &frameRateInt)) { 2471 frameRateInt = -1; 2472 } 2473 frameRateFloat = (float)frameRateInt; 2474 } 2475 2476 err = setVideoFormatOnPort( 2477 kPortIndexInput, width, height, compressionFormat, frameRateFloat); 2478 2479 if (err != OK) { 2480 return err; 2481 } 2482 2483 err = setVideoFormatOnPort( 2484 kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused); 2485 2486 if (err != OK) { 2487 return err; 2488 } 2489 2490 return OK; 2491} 2492 2493status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) { 2494 int32_t tmp; 2495 if (!msg->findInt32("color-format", &tmp)) { 2496 return INVALID_OPERATION; 2497 } 2498 2499 OMX_COLOR_FORMATTYPE colorFormat = 2500 static_cast<OMX_COLOR_FORMATTYPE>(tmp); 2501 2502 status_t err = setVideoPortFormatType( 2503 kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat); 2504 2505 if (err != OK) { 2506 ALOGE("[%s] does not support color format %d", 2507 mComponentName.c_str(), colorFormat); 2508 2509 return err; 2510 } 2511 2512 /* Input port configuration */ 2513 2514 OMX_PARAM_PORTDEFINITIONTYPE def; 2515 InitOMXParams(&def); 2516 2517 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2518 2519 def.nPortIndex = kPortIndexInput; 2520 2521 err = mOMX->getParameter( 2522 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2523 2524 if (err != OK) { 2525 return err; 2526 } 2527 2528 int32_t width, height, bitrate; 2529 if (!msg->findInt32("width", &width) 2530 || !msg->findInt32("height", &height) 2531 || !msg->findInt32("bitrate", &bitrate)) { 2532 return INVALID_OPERATION; 2533 } 2534 2535 video_def->nFrameWidth = width; 2536 video_def->nFrameHeight = height; 2537 2538 int32_t stride; 2539 if (!msg->findInt32("stride", &stride)) { 2540 stride = width; 2541 } 2542 2543 video_def->nStride = stride; 2544 2545 int32_t sliceHeight; 2546 if (!msg->findInt32("slice-height", &sliceHeight)) { 2547 sliceHeight = height; 2548 } 2549 2550 video_def->nSliceHeight = sliceHeight; 2551 2552 def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2; 2553 2554 float frameRate; 2555 if (!msg->findFloat("frame-rate", &frameRate)) { 2556 int32_t tmp; 2557 if (!msg->findInt32("frame-rate", &tmp)) { 2558 return INVALID_OPERATION; 2559 } 2560 frameRate = (float)tmp; 2561 mTimePerFrameUs = (int64_t) (1000000.0f / frameRate); 2562 } 2563 2564 video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f); 2565 video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; 2566 // this is redundant as it was already set up in setVideoPortFormatType 2567 // FIXME for now skip this only for flexible YUV formats 2568 if (colorFormat != OMX_COLOR_FormatYUV420Flexible) { 2569 video_def->eColorFormat = colorFormat; 2570 } 2571 2572 err = mOMX->setParameter( 2573 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2574 2575 if (err != OK) { 2576 ALOGE("[%s] failed to set input port definition parameters.", 2577 mComponentName.c_str()); 2578 2579 return err; 2580 } 2581 2582 /* Output port configuration */ 2583 2584 OMX_VIDEO_CODINGTYPE compressionFormat; 2585 err = GetVideoCodingTypeFromMime(mime, &compressionFormat); 2586 2587 if (err != OK) { 2588 return err; 2589 } 2590 2591 err = setVideoPortFormatType( 2592 kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused); 2593 2594 if (err != OK) { 2595 ALOGE("[%s] does not support compression format %d", 2596 mComponentName.c_str(), compressionFormat); 2597 2598 return err; 2599 } 2600 2601 def.nPortIndex = kPortIndexOutput; 2602 2603 err = mOMX->getParameter( 2604 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2605 2606 if (err != OK) { 2607 return err; 2608 } 2609 2610 video_def->nFrameWidth = width; 2611 video_def->nFrameHeight = height; 2612 video_def->xFramerate = 0; 2613 video_def->nBitrate = bitrate; 2614 video_def->eCompressionFormat = compressionFormat; 2615 video_def->eColorFormat = OMX_COLOR_FormatUnused; 2616 2617 err = mOMX->setParameter( 2618 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2619 2620 if (err != OK) { 2621 ALOGE("[%s] failed to set output port definition parameters.", 2622 mComponentName.c_str()); 2623 2624 return err; 2625 } 2626 2627 switch (compressionFormat) { 2628 case OMX_VIDEO_CodingMPEG4: 2629 err = setupMPEG4EncoderParameters(msg); 2630 break; 2631 2632 case OMX_VIDEO_CodingH263: 2633 err = setupH263EncoderParameters(msg); 2634 break; 2635 2636 case OMX_VIDEO_CodingAVC: 2637 err = setupAVCEncoderParameters(msg); 2638 break; 2639 2640 case OMX_VIDEO_CodingHEVC: 2641 err = setupHEVCEncoderParameters(msg); 2642 break; 2643 2644 case OMX_VIDEO_CodingVP8: 2645 case OMX_VIDEO_CodingVP9: 2646 err = setupVPXEncoderParameters(msg); 2647 break; 2648 2649 default: 2650 break; 2651 } 2652 2653 ALOGI("setupVideoEncoder succeeded"); 2654 2655 return err; 2656} 2657 2658status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) { 2659 OMX_VIDEO_PARAM_INTRAREFRESHTYPE params; 2660 InitOMXParams(¶ms); 2661 params.nPortIndex = kPortIndexOutput; 2662 2663 params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode); 2664 2665 if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic || 2666 params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 2667 int32_t mbs; 2668 if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) { 2669 return INVALID_OPERATION; 2670 } 2671 params.nCirMBs = mbs; 2672 } 2673 2674 if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive || 2675 params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 2676 int32_t mbs; 2677 if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) { 2678 return INVALID_OPERATION; 2679 } 2680 params.nAirMBs = mbs; 2681 2682 int32_t ref; 2683 if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) { 2684 return INVALID_OPERATION; 2685 } 2686 params.nAirRef = ref; 2687 } 2688 2689 status_t err = mOMX->setParameter( 2690 mNode, OMX_IndexParamVideoIntraRefresh, 2691 ¶ms, sizeof(params)); 2692 return err; 2693} 2694 2695static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) { 2696 if (iFramesInterval < 0) { 2697 return 0xFFFFFFFF; 2698 } else if (iFramesInterval == 0) { 2699 return 0; 2700 } 2701 OMX_U32 ret = frameRate * iFramesInterval; 2702 return ret; 2703} 2704 2705static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) { 2706 int32_t tmp; 2707 if (!msg->findInt32("bitrate-mode", &tmp)) { 2708 return OMX_Video_ControlRateVariable; 2709 } 2710 2711 return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp); 2712} 2713 2714status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) { 2715 int32_t bitrate, iFrameInterval; 2716 if (!msg->findInt32("bitrate", &bitrate) 2717 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 2718 return INVALID_OPERATION; 2719 } 2720 2721 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 2722 2723 float frameRate; 2724 if (!msg->findFloat("frame-rate", &frameRate)) { 2725 int32_t tmp; 2726 if (!msg->findInt32("frame-rate", &tmp)) { 2727 return INVALID_OPERATION; 2728 } 2729 frameRate = (float)tmp; 2730 } 2731 2732 OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type; 2733 InitOMXParams(&mpeg4type); 2734 mpeg4type.nPortIndex = kPortIndexOutput; 2735 2736 status_t err = mOMX->getParameter( 2737 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 2738 2739 if (err != OK) { 2740 return err; 2741 } 2742 2743 mpeg4type.nSliceHeaderSpacing = 0; 2744 mpeg4type.bSVH = OMX_FALSE; 2745 mpeg4type.bGov = OMX_FALSE; 2746 2747 mpeg4type.nAllowedPictureTypes = 2748 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 2749 2750 mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 2751 if (mpeg4type.nPFrames == 0) { 2752 mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 2753 } 2754 mpeg4type.nBFrames = 0; 2755 mpeg4type.nIDCVLCThreshold = 0; 2756 mpeg4type.bACPred = OMX_TRUE; 2757 mpeg4type.nMaxPacketSize = 256; 2758 mpeg4type.nTimeIncRes = 1000; 2759 mpeg4type.nHeaderExtension = 0; 2760 mpeg4type.bReversibleVLC = OMX_FALSE; 2761 2762 int32_t profile; 2763 if (msg->findInt32("profile", &profile)) { 2764 int32_t level; 2765 if (!msg->findInt32("level", &level)) { 2766 return INVALID_OPERATION; 2767 } 2768 2769 err = verifySupportForProfileAndLevel(profile, level); 2770 2771 if (err != OK) { 2772 return err; 2773 } 2774 2775 mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile); 2776 mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level); 2777 } 2778 2779 err = mOMX->setParameter( 2780 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 2781 2782 if (err != OK) { 2783 return err; 2784 } 2785 2786 err = configureBitrate(bitrate, bitrateMode); 2787 2788 if (err != OK) { 2789 return err; 2790 } 2791 2792 return setupErrorCorrectionParameters(); 2793} 2794 2795status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) { 2796 int32_t bitrate, iFrameInterval; 2797 if (!msg->findInt32("bitrate", &bitrate) 2798 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 2799 return INVALID_OPERATION; 2800 } 2801 2802 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 2803 2804 float frameRate; 2805 if (!msg->findFloat("frame-rate", &frameRate)) { 2806 int32_t tmp; 2807 if (!msg->findInt32("frame-rate", &tmp)) { 2808 return INVALID_OPERATION; 2809 } 2810 frameRate = (float)tmp; 2811 } 2812 2813 OMX_VIDEO_PARAM_H263TYPE h263type; 2814 InitOMXParams(&h263type); 2815 h263type.nPortIndex = kPortIndexOutput; 2816 2817 status_t err = mOMX->getParameter( 2818 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 2819 2820 if (err != OK) { 2821 return err; 2822 } 2823 2824 h263type.nAllowedPictureTypes = 2825 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 2826 2827 h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 2828 if (h263type.nPFrames == 0) { 2829 h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 2830 } 2831 h263type.nBFrames = 0; 2832 2833 int32_t profile; 2834 if (msg->findInt32("profile", &profile)) { 2835 int32_t level; 2836 if (!msg->findInt32("level", &level)) { 2837 return INVALID_OPERATION; 2838 } 2839 2840 err = verifySupportForProfileAndLevel(profile, level); 2841 2842 if (err != OK) { 2843 return err; 2844 } 2845 2846 h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile); 2847 h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level); 2848 } 2849 2850 h263type.bPLUSPTYPEAllowed = OMX_FALSE; 2851 h263type.bForceRoundingTypeToZero = OMX_FALSE; 2852 h263type.nPictureHeaderRepetition = 0; 2853 h263type.nGOBHeaderInterval = 0; 2854 2855 err = mOMX->setParameter( 2856 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 2857 2858 if (err != OK) { 2859 return err; 2860 } 2861 2862 err = configureBitrate(bitrate, bitrateMode); 2863 2864 if (err != OK) { 2865 return err; 2866 } 2867 2868 return setupErrorCorrectionParameters(); 2869} 2870 2871// static 2872int /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor( 2873 int width, int height, int rate, int bitrate, 2874 OMX_VIDEO_AVCPROFILETYPE profile) { 2875 // convert bitrate to main/baseline profile kbps equivalent 2876 switch (profile) { 2877 case OMX_VIDEO_AVCProfileHigh10: 2878 bitrate = divUp(bitrate, 3000); break; 2879 case OMX_VIDEO_AVCProfileHigh: 2880 bitrate = divUp(bitrate, 1250); break; 2881 default: 2882 bitrate = divUp(bitrate, 1000); break; 2883 } 2884 2885 // convert size and rate to MBs 2886 width = divUp(width, 16); 2887 height = divUp(height, 16); 2888 int mbs = width * height; 2889 rate *= mbs; 2890 int maxDimension = max(width, height); 2891 2892 static const int limits[][5] = { 2893 /* MBps MB dim bitrate level */ 2894 { 1485, 99, 28, 64, OMX_VIDEO_AVCLevel1 }, 2895 { 1485, 99, 28, 128, OMX_VIDEO_AVCLevel1b }, 2896 { 3000, 396, 56, 192, OMX_VIDEO_AVCLevel11 }, 2897 { 6000, 396, 56, 384, OMX_VIDEO_AVCLevel12 }, 2898 { 11880, 396, 56, 768, OMX_VIDEO_AVCLevel13 }, 2899 { 11880, 396, 56, 2000, OMX_VIDEO_AVCLevel2 }, 2900 { 19800, 792, 79, 4000, OMX_VIDEO_AVCLevel21 }, 2901 { 20250, 1620, 113, 4000, OMX_VIDEO_AVCLevel22 }, 2902 { 40500, 1620, 113, 10000, OMX_VIDEO_AVCLevel3 }, 2903 { 108000, 3600, 169, 14000, OMX_VIDEO_AVCLevel31 }, 2904 { 216000, 5120, 202, 20000, OMX_VIDEO_AVCLevel32 }, 2905 { 245760, 8192, 256, 20000, OMX_VIDEO_AVCLevel4 }, 2906 { 245760, 8192, 256, 50000, OMX_VIDEO_AVCLevel41 }, 2907 { 522240, 8704, 263, 50000, OMX_VIDEO_AVCLevel42 }, 2908 { 589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5 }, 2909 { 983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 }, 2910 { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 }, 2911 }; 2912 2913 for (size_t i = 0; i < ARRAY_SIZE(limits); i++) { 2914 const int (&limit)[5] = limits[i]; 2915 if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2] 2916 && bitrate <= limit[3]) { 2917 return limit[4]; 2918 } 2919 } 2920 return 0; 2921} 2922 2923status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) { 2924 int32_t bitrate, iFrameInterval; 2925 if (!msg->findInt32("bitrate", &bitrate) 2926 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 2927 return INVALID_OPERATION; 2928 } 2929 2930 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 2931 2932 float frameRate; 2933 if (!msg->findFloat("frame-rate", &frameRate)) { 2934 int32_t tmp; 2935 if (!msg->findInt32("frame-rate", &tmp)) { 2936 return INVALID_OPERATION; 2937 } 2938 frameRate = (float)tmp; 2939 } 2940 2941 status_t err = OK; 2942 int32_t intraRefreshMode = 0; 2943 if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) { 2944 err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode); 2945 if (err != OK) { 2946 ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x", 2947 err, intraRefreshMode); 2948 return err; 2949 } 2950 } 2951 2952 OMX_VIDEO_PARAM_AVCTYPE h264type; 2953 InitOMXParams(&h264type); 2954 h264type.nPortIndex = kPortIndexOutput; 2955 2956 err = mOMX->getParameter( 2957 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 2958 2959 if (err != OK) { 2960 return err; 2961 } 2962 2963 h264type.nAllowedPictureTypes = 2964 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 2965 2966 int32_t profile; 2967 if (msg->findInt32("profile", &profile)) { 2968 int32_t level; 2969 if (!msg->findInt32("level", &level)) { 2970 return INVALID_OPERATION; 2971 } 2972 2973 err = verifySupportForProfileAndLevel(profile, level); 2974 2975 if (err != OK) { 2976 return err; 2977 } 2978 2979 h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile); 2980 h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level); 2981 } 2982 2983 // XXX 2984 if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) { 2985 ALOGW("Use baseline profile instead of %d for AVC recording", 2986 h264type.eProfile); 2987 h264type.eProfile = OMX_VIDEO_AVCProfileBaseline; 2988 } 2989 2990 if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) { 2991 h264type.nSliceHeaderSpacing = 0; 2992 h264type.bUseHadamard = OMX_TRUE; 2993 h264type.nRefFrames = 1; 2994 h264type.nBFrames = 0; 2995 h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 2996 if (h264type.nPFrames == 0) { 2997 h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 2998 } 2999 h264type.nRefIdx10ActiveMinus1 = 0; 3000 h264type.nRefIdx11ActiveMinus1 = 0; 3001 h264type.bEntropyCodingCABAC = OMX_FALSE; 3002 h264type.bWeightedPPrediction = OMX_FALSE; 3003 h264type.bconstIpred = OMX_FALSE; 3004 h264type.bDirect8x8Inference = OMX_FALSE; 3005 h264type.bDirectSpatialTemporal = OMX_FALSE; 3006 h264type.nCabacInitIdc = 0; 3007 } 3008 3009 if (h264type.nBFrames != 0) { 3010 h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; 3011 } 3012 3013 h264type.bEnableUEP = OMX_FALSE; 3014 h264type.bEnableFMO = OMX_FALSE; 3015 h264type.bEnableASO = OMX_FALSE; 3016 h264type.bEnableRS = OMX_FALSE; 3017 h264type.bFrameMBsOnly = OMX_TRUE; 3018 h264type.bMBAFF = OMX_FALSE; 3019 h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; 3020 3021 err = mOMX->setParameter( 3022 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 3023 3024 if (err != OK) { 3025 return err; 3026 } 3027 3028 return configureBitrate(bitrate, bitrateMode); 3029} 3030 3031status_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) { 3032 int32_t bitrate, iFrameInterval; 3033 if (!msg->findInt32("bitrate", &bitrate) 3034 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 3035 return INVALID_OPERATION; 3036 } 3037 3038 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 3039 3040 float frameRate; 3041 if (!msg->findFloat("frame-rate", &frameRate)) { 3042 int32_t tmp; 3043 if (!msg->findInt32("frame-rate", &tmp)) { 3044 return INVALID_OPERATION; 3045 } 3046 frameRate = (float)tmp; 3047 } 3048 3049 OMX_VIDEO_PARAM_HEVCTYPE hevcType; 3050 InitOMXParams(&hevcType); 3051 hevcType.nPortIndex = kPortIndexOutput; 3052 3053 status_t err = OK; 3054 err = mOMX->getParameter( 3055 mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType)); 3056 if (err != OK) { 3057 return err; 3058 } 3059 3060 int32_t profile; 3061 if (msg->findInt32("profile", &profile)) { 3062 int32_t level; 3063 if (!msg->findInt32("level", &level)) { 3064 return INVALID_OPERATION; 3065 } 3066 3067 err = verifySupportForProfileAndLevel(profile, level); 3068 if (err != OK) { 3069 return err; 3070 } 3071 3072 hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile); 3073 hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level); 3074 } 3075 3076 // TODO: Need OMX structure definition for setting iFrameInterval 3077 3078 err = mOMX->setParameter( 3079 mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType)); 3080 if (err != OK) { 3081 return err; 3082 } 3083 3084 return configureBitrate(bitrate, bitrateMode); 3085} 3086 3087status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) { 3088 int32_t bitrate; 3089 int32_t iFrameInterval = 0; 3090 size_t tsLayers = 0; 3091 OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern = 3092 OMX_VIDEO_VPXTemporalLayerPatternNone; 3093 static const uint32_t kVp8LayerRateAlloction 3094 [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] 3095 [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = { 3096 {100, 100, 100}, // 1 layer 3097 { 60, 100, 100}, // 2 layers {60%, 40%} 3098 { 40, 60, 100}, // 3 layers {40%, 20%, 40%} 3099 }; 3100 if (!msg->findInt32("bitrate", &bitrate)) { 3101 return INVALID_OPERATION; 3102 } 3103 msg->findInt32("i-frame-interval", &iFrameInterval); 3104 3105 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 3106 3107 float frameRate; 3108 if (!msg->findFloat("frame-rate", &frameRate)) { 3109 int32_t tmp; 3110 if (!msg->findInt32("frame-rate", &tmp)) { 3111 return INVALID_OPERATION; 3112 } 3113 frameRate = (float)tmp; 3114 } 3115 3116 AString tsSchema; 3117 if (msg->findString("ts-schema", &tsSchema)) { 3118 if (tsSchema == "webrtc.vp8.1-layer") { 3119 pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 3120 tsLayers = 1; 3121 } else if (tsSchema == "webrtc.vp8.2-layer") { 3122 pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 3123 tsLayers = 2; 3124 } else if (tsSchema == "webrtc.vp8.3-layer") { 3125 pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 3126 tsLayers = 3; 3127 } else { 3128 ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str()); 3129 } 3130 } 3131 3132 OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; 3133 InitOMXParams(&vp8type); 3134 vp8type.nPortIndex = kPortIndexOutput; 3135 status_t err = mOMX->getParameter( 3136 mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 3137 &vp8type, sizeof(vp8type)); 3138 3139 if (err == OK) { 3140 if (iFrameInterval > 0) { 3141 vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate); 3142 } 3143 vp8type.eTemporalPattern = pattern; 3144 vp8type.nTemporalLayerCount = tsLayers; 3145 if (tsLayers > 0) { 3146 for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) { 3147 vp8type.nTemporalLayerBitrateRatio[i] = 3148 kVp8LayerRateAlloction[tsLayers - 1][i]; 3149 } 3150 } 3151 if (bitrateMode == OMX_Video_ControlRateConstant) { 3152 vp8type.nMinQuantizer = 2; 3153 vp8type.nMaxQuantizer = 63; 3154 } 3155 3156 err = mOMX->setParameter( 3157 mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 3158 &vp8type, sizeof(vp8type)); 3159 if (err != OK) { 3160 ALOGW("Extended VP8 parameters set failed: %d", err); 3161 } 3162 } 3163 3164 return configureBitrate(bitrate, bitrateMode); 3165} 3166 3167status_t ACodec::verifySupportForProfileAndLevel( 3168 int32_t profile, int32_t level) { 3169 OMX_VIDEO_PARAM_PROFILELEVELTYPE params; 3170 InitOMXParams(¶ms); 3171 params.nPortIndex = kPortIndexOutput; 3172 3173 for (params.nProfileIndex = 0;; ++params.nProfileIndex) { 3174 status_t err = mOMX->getParameter( 3175 mNode, 3176 OMX_IndexParamVideoProfileLevelQuerySupported, 3177 ¶ms, 3178 sizeof(params)); 3179 3180 if (err != OK) { 3181 return err; 3182 } 3183 3184 int32_t supportedProfile = static_cast<int32_t>(params.eProfile); 3185 int32_t supportedLevel = static_cast<int32_t>(params.eLevel); 3186 3187 if (profile == supportedProfile && level <= supportedLevel) { 3188 return OK; 3189 } 3190 } 3191} 3192 3193status_t ACodec::configureBitrate( 3194 int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) { 3195 OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 3196 InitOMXParams(&bitrateType); 3197 bitrateType.nPortIndex = kPortIndexOutput; 3198 3199 status_t err = mOMX->getParameter( 3200 mNode, OMX_IndexParamVideoBitrate, 3201 &bitrateType, sizeof(bitrateType)); 3202 3203 if (err != OK) { 3204 return err; 3205 } 3206 3207 bitrateType.eControlRate = bitrateMode; 3208 bitrateType.nTargetBitrate = bitrate; 3209 3210 return mOMX->setParameter( 3211 mNode, OMX_IndexParamVideoBitrate, 3212 &bitrateType, sizeof(bitrateType)); 3213} 3214 3215status_t ACodec::setupErrorCorrectionParameters() { 3216 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; 3217 InitOMXParams(&errorCorrectionType); 3218 errorCorrectionType.nPortIndex = kPortIndexOutput; 3219 3220 status_t err = mOMX->getParameter( 3221 mNode, OMX_IndexParamVideoErrorCorrection, 3222 &errorCorrectionType, sizeof(errorCorrectionType)); 3223 3224 if (err != OK) { 3225 return OK; // Optional feature. Ignore this failure 3226 } 3227 3228 errorCorrectionType.bEnableHEC = OMX_FALSE; 3229 errorCorrectionType.bEnableResync = OMX_TRUE; 3230 errorCorrectionType.nResynchMarkerSpacing = 256; 3231 errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; 3232 errorCorrectionType.bEnableRVLC = OMX_FALSE; 3233 3234 return mOMX->setParameter( 3235 mNode, OMX_IndexParamVideoErrorCorrection, 3236 &errorCorrectionType, sizeof(errorCorrectionType)); 3237} 3238 3239status_t ACodec::setVideoFormatOnPort( 3240 OMX_U32 portIndex, 3241 int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat, 3242 float frameRate) { 3243 OMX_PARAM_PORTDEFINITIONTYPE def; 3244 InitOMXParams(&def); 3245 def.nPortIndex = portIndex; 3246 3247 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 3248 3249 status_t err = mOMX->getParameter( 3250 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3251 3252 CHECK_EQ(err, (status_t)OK); 3253 3254 if (portIndex == kPortIndexInput) { 3255 // XXX Need a (much) better heuristic to compute input buffer sizes. 3256 const size_t X = 64 * 1024; 3257 if (def.nBufferSize < X) { 3258 def.nBufferSize = X; 3259 } 3260 } 3261 3262 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 3263 3264 video_def->nFrameWidth = width; 3265 video_def->nFrameHeight = height; 3266 3267 if (portIndex == kPortIndexInput) { 3268 video_def->eCompressionFormat = compressionFormat; 3269 video_def->eColorFormat = OMX_COLOR_FormatUnused; 3270 if (frameRate >= 0) { 3271 video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f); 3272 } 3273 } 3274 3275 err = mOMX->setParameter( 3276 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3277 3278 return err; 3279} 3280 3281status_t ACodec::initNativeWindow() { 3282 if (mNativeWindow != NULL) { 3283 return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE); 3284 } 3285 3286 mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE); 3287 return OK; 3288} 3289 3290size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const { 3291 size_t n = 0; 3292 3293 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 3294 const BufferInfo &info = mBuffers[portIndex].itemAt(i); 3295 3296 if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) { 3297 ++n; 3298 } 3299 } 3300 3301 return n; 3302} 3303 3304size_t ACodec::countBuffersOwnedByNativeWindow() const { 3305 size_t n = 0; 3306 3307 for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) { 3308 const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i); 3309 3310 if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 3311 ++n; 3312 } 3313 } 3314 3315 return n; 3316} 3317 3318void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() { 3319 if (mNativeWindow == NULL) { 3320 return; 3321 } 3322 3323 while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers 3324 && dequeueBufferFromNativeWindow() != NULL) { 3325 // these buffers will be submitted as regular buffers; account for this 3326 if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) { 3327 --mMetaDataBuffersToSubmit; 3328 } 3329 } 3330} 3331 3332bool ACodec::allYourBuffersAreBelongToUs( 3333 OMX_U32 portIndex) { 3334 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 3335 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 3336 3337 if (info->mStatus != BufferInfo::OWNED_BY_US 3338 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 3339 ALOGV("[%s] Buffer %u on port %u still has status %d", 3340 mComponentName.c_str(), 3341 info->mBufferID, portIndex, info->mStatus); 3342 return false; 3343 } 3344 } 3345 3346 return true; 3347} 3348 3349bool ACodec::allYourBuffersAreBelongToUs() { 3350 return allYourBuffersAreBelongToUs(kPortIndexInput) 3351 && allYourBuffersAreBelongToUs(kPortIndexOutput); 3352} 3353 3354void ACodec::deferMessage(const sp<AMessage> &msg) { 3355 mDeferredQueue.push_back(msg); 3356} 3357 3358void ACodec::processDeferredMessages() { 3359 List<sp<AMessage> > queue = mDeferredQueue; 3360 mDeferredQueue.clear(); 3361 3362 List<sp<AMessage> >::iterator it = queue.begin(); 3363 while (it != queue.end()) { 3364 onMessageReceived(*it++); 3365 } 3366} 3367 3368// static 3369bool ACodec::describeDefaultColorFormat(DescribeColorFormatParams ¶ms) { 3370 MediaImage &image = params.sMediaImage; 3371 memset(&image, 0, sizeof(image)); 3372 3373 image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN; 3374 image.mNumPlanes = 0; 3375 3376 const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat; 3377 image.mWidth = params.nFrameWidth; 3378 image.mHeight = params.nFrameHeight; 3379 3380 // only supporting YUV420 3381 if (fmt != OMX_COLOR_FormatYUV420Planar && 3382 fmt != OMX_COLOR_FormatYUV420PackedPlanar && 3383 fmt != OMX_COLOR_FormatYUV420SemiPlanar && 3384 fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar && 3385 fmt != HAL_PIXEL_FORMAT_YV12) { 3386 ALOGW("do not know color format 0x%x = %d", fmt, fmt); 3387 return false; 3388 } 3389 3390 // TEMPORARY FIX for some vendors that advertise sliceHeight as 0 3391 if (params.nStride != 0 && params.nSliceHeight == 0) { 3392 ALOGW("using sliceHeight=%u instead of what codec advertised (=0)", 3393 params.nFrameHeight); 3394 params.nSliceHeight = params.nFrameHeight; 3395 } 3396 3397 // we need stride and slice-height to be non-zero 3398 if (params.nStride == 0 || params.nSliceHeight == 0) { 3399 ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u", 3400 fmt, fmt, params.nStride, params.nSliceHeight); 3401 return false; 3402 } 3403 3404 // set-up YUV format 3405 image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV; 3406 image.mNumPlanes = 3; 3407 image.mBitDepth = 8; 3408 image.mPlane[image.Y].mOffset = 0; 3409 image.mPlane[image.Y].mColInc = 1; 3410 image.mPlane[image.Y].mRowInc = params.nStride; 3411 image.mPlane[image.Y].mHorizSubsampling = 1; 3412 image.mPlane[image.Y].mVertSubsampling = 1; 3413 3414 switch ((int)fmt) { 3415 case HAL_PIXEL_FORMAT_YV12: 3416 if (params.bUsingNativeBuffers) { 3417 size_t ystride = align(params.nStride, 16); 3418 size_t cstride = align(params.nStride / 2, 16); 3419 image.mPlane[image.Y].mRowInc = ystride; 3420 3421 image.mPlane[image.V].mOffset = ystride * params.nSliceHeight; 3422 image.mPlane[image.V].mColInc = 1; 3423 image.mPlane[image.V].mRowInc = cstride; 3424 image.mPlane[image.V].mHorizSubsampling = 2; 3425 image.mPlane[image.V].mVertSubsampling = 2; 3426 3427 image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset 3428 + (cstride * params.nSliceHeight / 2); 3429 image.mPlane[image.U].mColInc = 1; 3430 image.mPlane[image.U].mRowInc = cstride; 3431 image.mPlane[image.U].mHorizSubsampling = 2; 3432 image.mPlane[image.U].mVertSubsampling = 2; 3433 break; 3434 } else { 3435 // fall through as YV12 is used for YUV420Planar by some codecs 3436 } 3437 3438 case OMX_COLOR_FormatYUV420Planar: 3439 case OMX_COLOR_FormatYUV420PackedPlanar: 3440 image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight; 3441 image.mPlane[image.U].mColInc = 1; 3442 image.mPlane[image.U].mRowInc = params.nStride / 2; 3443 image.mPlane[image.U].mHorizSubsampling = 2; 3444 image.mPlane[image.U].mVertSubsampling = 2; 3445 3446 image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset 3447 + (params.nStride * params.nSliceHeight / 4); 3448 image.mPlane[image.V].mColInc = 1; 3449 image.mPlane[image.V].mRowInc = params.nStride / 2; 3450 image.mPlane[image.V].mHorizSubsampling = 2; 3451 image.mPlane[image.V].mVertSubsampling = 2; 3452 break; 3453 3454 case OMX_COLOR_FormatYUV420SemiPlanar: 3455 // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder 3456 case OMX_COLOR_FormatYUV420PackedSemiPlanar: 3457 // NV12 3458 image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight; 3459 image.mPlane[image.U].mColInc = 2; 3460 image.mPlane[image.U].mRowInc = params.nStride; 3461 image.mPlane[image.U].mHorizSubsampling = 2; 3462 image.mPlane[image.U].mVertSubsampling = 2; 3463 3464 image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1; 3465 image.mPlane[image.V].mColInc = 2; 3466 image.mPlane[image.V].mRowInc = params.nStride; 3467 image.mPlane[image.V].mHorizSubsampling = 2; 3468 image.mPlane[image.V].mVertSubsampling = 2; 3469 break; 3470 3471 default: 3472 TRESPASS(); 3473 } 3474 return true; 3475} 3476 3477// static 3478bool ACodec::describeColorFormat( 3479 const sp<IOMX> &omx, IOMX::node_id node, 3480 DescribeColorFormatParams &describeParams) 3481{ 3482 OMX_INDEXTYPE describeColorFormatIndex; 3483 if (omx->getExtensionIndex( 3484 node, "OMX.google.android.index.describeColorFormat", 3485 &describeColorFormatIndex) != OK || 3486 omx->getParameter( 3487 node, describeColorFormatIndex, 3488 &describeParams, sizeof(describeParams)) != OK) { 3489 return describeDefaultColorFormat(describeParams); 3490 } 3491 return describeParams.sMediaImage.mType != 3492 MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN; 3493} 3494 3495// static 3496bool ACodec::isFlexibleColorFormat( 3497 const sp<IOMX> &omx, IOMX::node_id node, 3498 uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) { 3499 DescribeColorFormatParams describeParams; 3500 InitOMXParams(&describeParams); 3501 describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat; 3502 // reasonable dummy values 3503 describeParams.nFrameWidth = 128; 3504 describeParams.nFrameHeight = 128; 3505 describeParams.nStride = 128; 3506 describeParams.nSliceHeight = 128; 3507 describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers; 3508 3509 CHECK(flexibleEquivalent != NULL); 3510 3511 if (!describeColorFormat(omx, node, describeParams)) { 3512 return false; 3513 } 3514 3515 const MediaImage &img = describeParams.sMediaImage; 3516 if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) { 3517 if (img.mNumPlanes != 3 || 3518 img.mPlane[img.Y].mHorizSubsampling != 1 || 3519 img.mPlane[img.Y].mVertSubsampling != 1) { 3520 return false; 3521 } 3522 3523 // YUV 420 3524 if (img.mPlane[img.U].mHorizSubsampling == 2 3525 && img.mPlane[img.U].mVertSubsampling == 2 3526 && img.mPlane[img.V].mHorizSubsampling == 2 3527 && img.mPlane[img.V].mVertSubsampling == 2) { 3528 // possible flexible YUV420 format 3529 if (img.mBitDepth <= 8) { 3530 *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible; 3531 return true; 3532 } 3533 } 3534 } 3535 return false; 3536} 3537 3538status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) { 3539 // TODO: catch errors an return them instead of using CHECK 3540 OMX_PARAM_PORTDEFINITIONTYPE def; 3541 InitOMXParams(&def); 3542 def.nPortIndex = portIndex; 3543 3544 CHECK_EQ(mOMX->getParameter( 3545 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)), 3546 (status_t)OK); 3547 3548 CHECK_EQ((int)def.eDir, 3549 (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)); 3550 3551 switch (def.eDomain) { 3552 case OMX_PortDomainVideo: 3553 { 3554 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 3555 switch ((int)videoDef->eCompressionFormat) { 3556 case OMX_VIDEO_CodingUnused: 3557 { 3558 CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput)); 3559 notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW); 3560 3561 notify->setInt32("stride", videoDef->nStride); 3562 notify->setInt32("slice-height", videoDef->nSliceHeight); 3563 notify->setInt32("color-format", videoDef->eColorFormat); 3564 3565 if (mNativeWindow == NULL) { 3566 DescribeColorFormatParams describeParams; 3567 InitOMXParams(&describeParams); 3568 describeParams.eColorFormat = videoDef->eColorFormat; 3569 describeParams.nFrameWidth = videoDef->nFrameWidth; 3570 describeParams.nFrameHeight = videoDef->nFrameHeight; 3571 describeParams.nStride = videoDef->nStride; 3572 describeParams.nSliceHeight = videoDef->nSliceHeight; 3573 describeParams.bUsingNativeBuffers = OMX_FALSE; 3574 3575 if (describeColorFormat(mOMX, mNode, describeParams)) { 3576 notify->setBuffer( 3577 "image-data", 3578 ABuffer::CreateAsCopy( 3579 &describeParams.sMediaImage, 3580 sizeof(describeParams.sMediaImage))); 3581 3582 MediaImage *img = &describeParams.sMediaImage; 3583 ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }", 3584 mComponentName.c_str(), img->mWidth, img->mHeight, 3585 img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc, 3586 img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc, 3587 img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc); 3588 } 3589 } 3590 3591 if (portIndex != kPortIndexOutput) { 3592 // TODO: also get input crop 3593 break; 3594 } 3595 3596 OMX_CONFIG_RECTTYPE rect; 3597 InitOMXParams(&rect); 3598 rect.nPortIndex = portIndex; 3599 3600 if (mOMX->getConfig( 3601 mNode, 3602 (portIndex == kPortIndexOutput ? 3603 OMX_IndexConfigCommonOutputCrop : 3604 OMX_IndexConfigCommonInputCrop), 3605 &rect, sizeof(rect)) != OK) { 3606 rect.nLeft = 0; 3607 rect.nTop = 0; 3608 rect.nWidth = videoDef->nFrameWidth; 3609 rect.nHeight = videoDef->nFrameHeight; 3610 } 3611 3612 CHECK_GE(rect.nLeft, 0); 3613 CHECK_GE(rect.nTop, 0); 3614 CHECK_GE(rect.nWidth, 0u); 3615 CHECK_GE(rect.nHeight, 0u); 3616 CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth); 3617 CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight); 3618 3619 notify->setRect( 3620 "crop", 3621 rect.nLeft, 3622 rect.nTop, 3623 rect.nLeft + rect.nWidth - 1, 3624 rect.nTop + rect.nHeight - 1); 3625 3626 break; 3627 } 3628 3629 case OMX_VIDEO_CodingVP8: 3630 case OMX_VIDEO_CodingVP9: 3631 { 3632 OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; 3633 InitOMXParams(&vp8type); 3634 vp8type.nPortIndex = kPortIndexOutput; 3635 status_t err = mOMX->getParameter( 3636 mNode, 3637 (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 3638 &vp8type, 3639 sizeof(vp8type)); 3640 3641 if (err == OK) { 3642 AString tsSchema = "none"; 3643 if (vp8type.eTemporalPattern 3644 == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) { 3645 switch (vp8type.nTemporalLayerCount) { 3646 case 1: 3647 { 3648 tsSchema = "webrtc.vp8.1-layer"; 3649 break; 3650 } 3651 case 2: 3652 { 3653 tsSchema = "webrtc.vp8.2-layer"; 3654 break; 3655 } 3656 case 3: 3657 { 3658 tsSchema = "webrtc.vp8.3-layer"; 3659 break; 3660 } 3661 default: 3662 { 3663 break; 3664 } 3665 } 3666 } 3667 notify->setString("ts-schema", tsSchema); 3668 } 3669 // Fall through to set up mime. 3670 } 3671 3672 default: 3673 { 3674 CHECK(mIsEncoder ^ (portIndex == kPortIndexInput)); 3675 AString mime; 3676 if (GetMimeTypeForVideoCoding( 3677 videoDef->eCompressionFormat, &mime) != OK) { 3678 notify->setString("mime", "application/octet-stream"); 3679 } else { 3680 notify->setString("mime", mime.c_str()); 3681 } 3682 break; 3683 } 3684 } 3685 notify->setInt32("width", videoDef->nFrameWidth); 3686 notify->setInt32("height", videoDef->nFrameHeight); 3687 ALOGV("[%s] %s format is %s", mComponentName.c_str(), 3688 portIndex == kPortIndexInput ? "input" : "output", 3689 notify->debugString().c_str()); 3690 3691 break; 3692 } 3693 3694 case OMX_PortDomainAudio: 3695 { 3696 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 3697 3698 switch ((int)audioDef->eEncoding) { 3699 case OMX_AUDIO_CodingPCM: 3700 { 3701 OMX_AUDIO_PARAM_PCMMODETYPE params; 3702 InitOMXParams(¶ms); 3703 params.nPortIndex = portIndex; 3704 3705 CHECK_EQ(mOMX->getParameter( 3706 mNode, OMX_IndexParamAudioPcm, 3707 ¶ms, sizeof(params)), 3708 (status_t)OK); 3709 3710 CHECK_GT(params.nChannels, 0); 3711 CHECK(params.nChannels == 1 || params.bInterleaved); 3712 CHECK_EQ(params.nBitPerSample, 16u); 3713 3714 CHECK_EQ((int)params.eNumData, 3715 (int)OMX_NumericalDataSigned); 3716 3717 CHECK_EQ((int)params.ePCMMode, 3718 (int)OMX_AUDIO_PCMModeLinear); 3719 3720 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW); 3721 notify->setInt32("channel-count", params.nChannels); 3722 notify->setInt32("sample-rate", params.nSamplingRate); 3723 3724 if (mChannelMaskPresent) { 3725 notify->setInt32("channel-mask", mChannelMask); 3726 } 3727 break; 3728 } 3729 3730 case OMX_AUDIO_CodingAAC: 3731 { 3732 OMX_AUDIO_PARAM_AACPROFILETYPE params; 3733 InitOMXParams(¶ms); 3734 params.nPortIndex = portIndex; 3735 3736 CHECK_EQ(mOMX->getParameter( 3737 mNode, OMX_IndexParamAudioAac, 3738 ¶ms, sizeof(params)), 3739 (status_t)OK); 3740 3741 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 3742 notify->setInt32("channel-count", params.nChannels); 3743 notify->setInt32("sample-rate", params.nSampleRate); 3744 break; 3745 } 3746 3747 case OMX_AUDIO_CodingAMR: 3748 { 3749 OMX_AUDIO_PARAM_AMRTYPE params; 3750 InitOMXParams(¶ms); 3751 params.nPortIndex = portIndex; 3752 3753 CHECK_EQ(mOMX->getParameter( 3754 mNode, OMX_IndexParamAudioAmr, 3755 ¶ms, sizeof(params)), 3756 (status_t)OK); 3757 3758 notify->setInt32("channel-count", 1); 3759 if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) { 3760 notify->setString( 3761 "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB); 3762 3763 notify->setInt32("sample-rate", 16000); 3764 } else { 3765 notify->setString( 3766 "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB); 3767 3768 notify->setInt32("sample-rate", 8000); 3769 } 3770 break; 3771 } 3772 3773 case OMX_AUDIO_CodingFLAC: 3774 { 3775 OMX_AUDIO_PARAM_FLACTYPE params; 3776 InitOMXParams(¶ms); 3777 params.nPortIndex = portIndex; 3778 3779 CHECK_EQ(mOMX->getParameter( 3780 mNode, OMX_IndexParamAudioFlac, 3781 ¶ms, sizeof(params)), 3782 (status_t)OK); 3783 3784 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC); 3785 notify->setInt32("channel-count", params.nChannels); 3786 notify->setInt32("sample-rate", params.nSampleRate); 3787 break; 3788 } 3789 3790 case OMX_AUDIO_CodingMP3: 3791 { 3792 OMX_AUDIO_PARAM_MP3TYPE params; 3793 InitOMXParams(¶ms); 3794 params.nPortIndex = portIndex; 3795 3796 CHECK_EQ(mOMX->getParameter( 3797 mNode, OMX_IndexParamAudioMp3, 3798 ¶ms, sizeof(params)), 3799 (status_t)OK); 3800 3801 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG); 3802 notify->setInt32("channel-count", params.nChannels); 3803 notify->setInt32("sample-rate", params.nSampleRate); 3804 break; 3805 } 3806 3807 case OMX_AUDIO_CodingVORBIS: 3808 { 3809 OMX_AUDIO_PARAM_VORBISTYPE params; 3810 InitOMXParams(¶ms); 3811 params.nPortIndex = portIndex; 3812 3813 CHECK_EQ(mOMX->getParameter( 3814 mNode, OMX_IndexParamAudioVorbis, 3815 ¶ms, sizeof(params)), 3816 (status_t)OK); 3817 3818 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS); 3819 notify->setInt32("channel-count", params.nChannels); 3820 notify->setInt32("sample-rate", params.nSampleRate); 3821 break; 3822 } 3823 3824 case OMX_AUDIO_CodingAndroidAC3: 3825 { 3826 OMX_AUDIO_PARAM_ANDROID_AC3TYPE params; 3827 InitOMXParams(¶ms); 3828 params.nPortIndex = portIndex; 3829 3830 CHECK_EQ((status_t)OK, mOMX->getParameter( 3831 mNode, 3832 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 3833 ¶ms, 3834 sizeof(params))); 3835 3836 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3); 3837 notify->setInt32("channel-count", params.nChannels); 3838 notify->setInt32("sample-rate", params.nSampleRate); 3839 break; 3840 } 3841 3842 case OMX_AUDIO_CodingAndroidEAC3: 3843 { 3844 OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params; 3845 InitOMXParams(¶ms); 3846 params.nPortIndex = portIndex; 3847 3848 CHECK_EQ((status_t)OK, mOMX->getParameter( 3849 mNode, 3850 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, 3851 ¶ms, 3852 sizeof(params))); 3853 3854 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3); 3855 notify->setInt32("channel-count", params.nChannels); 3856 notify->setInt32("sample-rate", params.nSampleRate); 3857 break; 3858 } 3859 3860 case OMX_AUDIO_CodingAndroidOPUS: 3861 { 3862 OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params; 3863 InitOMXParams(¶ms); 3864 params.nPortIndex = portIndex; 3865 3866 CHECK_EQ((status_t)OK, mOMX->getParameter( 3867 mNode, 3868 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, 3869 ¶ms, 3870 sizeof(params))); 3871 3872 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS); 3873 notify->setInt32("channel-count", params.nChannels); 3874 notify->setInt32("sample-rate", params.nSampleRate); 3875 break; 3876 } 3877 3878 case OMX_AUDIO_CodingG711: 3879 { 3880 OMX_AUDIO_PARAM_PCMMODETYPE params; 3881 InitOMXParams(¶ms); 3882 params.nPortIndex = portIndex; 3883 3884 CHECK_EQ((status_t)OK, mOMX->getParameter( 3885 mNode, 3886 (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, 3887 ¶ms, 3888 sizeof(params))); 3889 3890 const char *mime = NULL; 3891 if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) { 3892 mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW; 3893 } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) { 3894 mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW; 3895 } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear 3896 mime = MEDIA_MIMETYPE_AUDIO_RAW; 3897 } 3898 notify->setString("mime", mime); 3899 notify->setInt32("channel-count", params.nChannels); 3900 notify->setInt32("sample-rate", params.nSamplingRate); 3901 break; 3902 } 3903 3904 case OMX_AUDIO_CodingGSMFR: 3905 { 3906 OMX_AUDIO_PARAM_MP3TYPE params; 3907 InitOMXParams(¶ms); 3908 params.nPortIndex = portIndex; 3909 3910 CHECK_EQ(mOMX->getParameter( 3911 mNode, OMX_IndexParamAudioPcm, 3912 ¶ms, sizeof(params)), 3913 (status_t)OK); 3914 3915 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM); 3916 notify->setInt32("channel-count", params.nChannels); 3917 notify->setInt32("sample-rate", params.nSampleRate); 3918 break; 3919 } 3920 3921 default: 3922 ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding); 3923 TRESPASS(); 3924 } 3925 break; 3926 } 3927 3928 default: 3929 TRESPASS(); 3930 } 3931 3932 return OK; 3933} 3934 3935void ACodec::sendFormatChange(const sp<AMessage> &reply) { 3936 sp<AMessage> notify = mBaseOutputFormat->dup(); 3937 notify->setInt32("what", kWhatOutputFormatChanged); 3938 3939 CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK); 3940 3941 AString mime; 3942 CHECK(notify->findString("mime", &mime)); 3943 3944 int32_t left, top, right, bottom; 3945 if (mime == MEDIA_MIMETYPE_VIDEO_RAW && 3946 mNativeWindow != NULL && 3947 notify->findRect("crop", &left, &top, &right, &bottom)) { 3948 // notify renderer of the crop change 3949 // NOTE: native window uses extended right-bottom coordinate 3950 reply->setRect("crop", left, top, right + 1, bottom + 1); 3951 } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW && 3952 (mEncoderDelay || mEncoderPadding)) { 3953 int32_t channelCount; 3954 CHECK(notify->findInt32("channel-count", &channelCount)); 3955 size_t frameSize = channelCount * sizeof(int16_t); 3956 if (mSkipCutBuffer != NULL) { 3957 size_t prevbufsize = mSkipCutBuffer->size(); 3958 if (prevbufsize != 0) { 3959 ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize); 3960 } 3961 } 3962 mSkipCutBuffer = new SkipCutBuffer( 3963 mEncoderDelay * frameSize, 3964 mEncoderPadding * frameSize); 3965 } 3966 3967 notify->post(); 3968 3969 mSentFormat = true; 3970} 3971 3972void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) { 3973 sp<AMessage> notify = mNotify->dup(); 3974 notify->setInt32("what", CodecBase::kWhatError); 3975 ALOGE("signalError(omxError %#x, internalError %d)", error, internalError); 3976 3977 if (internalError == UNKNOWN_ERROR) { // find better error code 3978 const status_t omxStatus = statusFromOMXError(error); 3979 if (omxStatus != 0) { 3980 internalError = omxStatus; 3981 } else { 3982 ALOGW("Invalid OMX error %#x", error); 3983 } 3984 } 3985 notify->setInt32("err", internalError); 3986 notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error. 3987 notify->post(); 3988} 3989 3990status_t ACodec::pushBlankBuffersToNativeWindow() { 3991 status_t err = NO_ERROR; 3992 ANativeWindowBuffer* anb = NULL; 3993 int numBufs = 0; 3994 int minUndequeuedBufs = 0; 3995 3996 // We need to reconnect to the ANativeWindow as a CPU client to ensure that 3997 // no frames get dropped by SurfaceFlinger assuming that these are video 3998 // frames. 3999 err = native_window_api_disconnect(mNativeWindow.get(), 4000 NATIVE_WINDOW_API_MEDIA); 4001 if (err != NO_ERROR) { 4002 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", 4003 strerror(-err), -err); 4004 return err; 4005 } 4006 4007 err = native_window_api_connect(mNativeWindow.get(), 4008 NATIVE_WINDOW_API_CPU); 4009 if (err != NO_ERROR) { 4010 ALOGE("error pushing blank frames: api_connect failed: %s (%d)", 4011 strerror(-err), -err); 4012 return err; 4013 } 4014 4015 err = native_window_set_buffers_dimensions(mNativeWindow.get(), 1, 1); 4016 if (err != NO_ERROR) { 4017 ALOGE("error pushing blank frames: set_buffers_dimensions failed: %s (%d)", 4018 strerror(-err), -err); 4019 goto error; 4020 } 4021 4022 err = native_window_set_buffers_format(mNativeWindow.get(), HAL_PIXEL_FORMAT_RGBX_8888); 4023 if (err != NO_ERROR) { 4024 ALOGE("error pushing blank frames: set_buffers_format failed: %s (%d)", 4025 strerror(-err), -err); 4026 goto error; 4027 } 4028 4029 err = native_window_set_scaling_mode(mNativeWindow.get(), 4030 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 4031 if (err != NO_ERROR) { 4032 ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)", 4033 strerror(-err), -err); 4034 goto error; 4035 } 4036 4037 err = native_window_set_usage(mNativeWindow.get(), 4038 GRALLOC_USAGE_SW_WRITE_OFTEN); 4039 if (err != NO_ERROR) { 4040 ALOGE("error pushing blank frames: set_usage failed: %s (%d)", 4041 strerror(-err), -err); 4042 goto error; 4043 } 4044 4045 err = mNativeWindow->query(mNativeWindow.get(), 4046 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); 4047 if (err != NO_ERROR) { 4048 ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query " 4049 "failed: %s (%d)", strerror(-err), -err); 4050 goto error; 4051 } 4052 4053 numBufs = minUndequeuedBufs + 1; 4054 err = native_window_set_buffer_count(mNativeWindow.get(), numBufs); 4055 if (err != NO_ERROR) { 4056 ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)", 4057 strerror(-err), -err); 4058 goto error; 4059 } 4060 4061 // We push numBufs + 1 buffers to ensure that we've drawn into the same 4062 // buffer twice. This should guarantee that the buffer has been displayed 4063 // on the screen and then been replaced, so an previous video frames are 4064 // guaranteed NOT to be currently displayed. 4065 for (int i = 0; i < numBufs + 1; i++) { 4066 err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb); 4067 if (err != NO_ERROR) { 4068 ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)", 4069 strerror(-err), -err); 4070 goto error; 4071 } 4072 4073 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 4074 4075 // Fill the buffer with the a 1x1 checkerboard pattern ;) 4076 uint32_t* img = NULL; 4077 err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 4078 if (err != NO_ERROR) { 4079 ALOGE("error pushing blank frames: lock failed: %s (%d)", 4080 strerror(-err), -err); 4081 goto error; 4082 } 4083 4084 *img = 0; 4085 4086 err = buf->unlock(); 4087 if (err != NO_ERROR) { 4088 ALOGE("error pushing blank frames: unlock failed: %s (%d)", 4089 strerror(-err), -err); 4090 goto error; 4091 } 4092 4093 err = mNativeWindow->queueBuffer(mNativeWindow.get(), 4094 buf->getNativeBuffer(), -1); 4095 if (err != NO_ERROR) { 4096 ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)", 4097 strerror(-err), -err); 4098 goto error; 4099 } 4100 4101 anb = NULL; 4102 } 4103 4104error: 4105 4106 if (err != NO_ERROR) { 4107 // Clean up after an error. 4108 if (anb != NULL) { 4109 mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1); 4110 } 4111 4112 native_window_api_disconnect(mNativeWindow.get(), 4113 NATIVE_WINDOW_API_CPU); 4114 native_window_api_connect(mNativeWindow.get(), 4115 NATIVE_WINDOW_API_MEDIA); 4116 4117 return err; 4118 } else { 4119 // Clean up after success. 4120 err = native_window_api_disconnect(mNativeWindow.get(), 4121 NATIVE_WINDOW_API_CPU); 4122 if (err != NO_ERROR) { 4123 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", 4124 strerror(-err), -err); 4125 return err; 4126 } 4127 4128 err = native_window_api_connect(mNativeWindow.get(), 4129 NATIVE_WINDOW_API_MEDIA); 4130 if (err != NO_ERROR) { 4131 ALOGE("error pushing blank frames: api_connect failed: %s (%d)", 4132 strerror(-err), -err); 4133 return err; 4134 } 4135 4136 return NO_ERROR; 4137 } 4138} 4139 4140//////////////////////////////////////////////////////////////////////////////// 4141 4142ACodec::PortDescription::PortDescription() { 4143} 4144 4145status_t ACodec::requestIDRFrame() { 4146 if (!mIsEncoder) { 4147 return ERROR_UNSUPPORTED; 4148 } 4149 4150 OMX_CONFIG_INTRAREFRESHVOPTYPE params; 4151 InitOMXParams(¶ms); 4152 4153 params.nPortIndex = kPortIndexOutput; 4154 params.IntraRefreshVOP = OMX_TRUE; 4155 4156 return mOMX->setConfig( 4157 mNode, 4158 OMX_IndexConfigVideoIntraVOPRefresh, 4159 ¶ms, 4160 sizeof(params)); 4161} 4162 4163void ACodec::PortDescription::addBuffer( 4164 IOMX::buffer_id id, const sp<ABuffer> &buffer) { 4165 mBufferIDs.push_back(id); 4166 mBuffers.push_back(buffer); 4167} 4168 4169size_t ACodec::PortDescription::countBuffers() { 4170 return mBufferIDs.size(); 4171} 4172 4173IOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const { 4174 return mBufferIDs.itemAt(index); 4175} 4176 4177sp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const { 4178 return mBuffers.itemAt(index); 4179} 4180 4181//////////////////////////////////////////////////////////////////////////////// 4182 4183ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState) 4184 : AState(parentState), 4185 mCodec(codec) { 4186} 4187 4188ACodec::BaseState::PortMode ACodec::BaseState::getPortMode( 4189 OMX_U32 /* portIndex */) { 4190 return KEEP_BUFFERS; 4191} 4192 4193bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { 4194 switch (msg->what()) { 4195 case kWhatInputBufferFilled: 4196 { 4197 onInputBufferFilled(msg); 4198 break; 4199 } 4200 4201 case kWhatOutputBufferDrained: 4202 { 4203 onOutputBufferDrained(msg); 4204 break; 4205 } 4206 4207 case ACodec::kWhatOMXMessage: 4208 { 4209 return onOMXMessage(msg); 4210 } 4211 4212 case ACodec::kWhatCreateInputSurface: 4213 case ACodec::kWhatUsePersistentInputSurface: 4214 case ACodec::kWhatSignalEndOfInputStream: 4215 { 4216 // This may result in an app illegal state exception. 4217 ALOGE("Message 0x%x was not handled", msg->what()); 4218 mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION); 4219 return true; 4220 } 4221 4222 case ACodec::kWhatOMXDied: 4223 { 4224 // This will result in kFlagSawMediaServerDie handling in MediaCodec. 4225 ALOGE("OMX/mediaserver died, signalling error!"); 4226 mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT); 4227 break; 4228 } 4229 4230 case ACodec::kWhatReleaseCodecInstance: 4231 { 4232 ALOGI("[%s] forcing the release of codec", 4233 mCodec->mComponentName.c_str()); 4234 status_t err = mCodec->mOMX->freeNode(mCodec->mNode); 4235 ALOGE_IF("[%s] failed to release codec instance: err=%d", 4236 mCodec->mComponentName.c_str(), err); 4237 sp<AMessage> notify = mCodec->mNotify->dup(); 4238 notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 4239 notify->post(); 4240 break; 4241 } 4242 4243 default: 4244 return false; 4245 } 4246 4247 return true; 4248} 4249 4250bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { 4251 int32_t type; 4252 CHECK(msg->findInt32("type", &type)); 4253 4254 // there is a possibility that this is an outstanding message for a 4255 // codec that we have already destroyed 4256 if (mCodec->mNode == 0) { 4257 ALOGI("ignoring message as already freed component: %s", 4258 msg->debugString().c_str()); 4259 return true; 4260 } 4261 4262 IOMX::node_id nodeID; 4263 CHECK(msg->findInt32("node", (int32_t*)&nodeID)); 4264 CHECK_EQ(nodeID, mCodec->mNode); 4265 4266 switch (type) { 4267 case omx_message::EVENT: 4268 { 4269 int32_t event, data1, data2; 4270 CHECK(msg->findInt32("event", &event)); 4271 CHECK(msg->findInt32("data1", &data1)); 4272 CHECK(msg->findInt32("data2", &data2)); 4273 4274 if (event == OMX_EventCmdComplete 4275 && data1 == OMX_CommandFlush 4276 && data2 == (int32_t)OMX_ALL) { 4277 // Use of this notification is not consistent across 4278 // implementations. We'll drop this notification and rely 4279 // on flush-complete notifications on the individual port 4280 // indices instead. 4281 4282 return true; 4283 } 4284 4285 return onOMXEvent( 4286 static_cast<OMX_EVENTTYPE>(event), 4287 static_cast<OMX_U32>(data1), 4288 static_cast<OMX_U32>(data2)); 4289 } 4290 4291 case omx_message::EMPTY_BUFFER_DONE: 4292 { 4293 IOMX::buffer_id bufferID; 4294 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 4295 4296 return onOMXEmptyBufferDone(bufferID); 4297 } 4298 4299 case omx_message::FILL_BUFFER_DONE: 4300 { 4301 IOMX::buffer_id bufferID; 4302 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 4303 4304 int32_t rangeOffset, rangeLength, flags; 4305 int64_t timeUs; 4306 4307 CHECK(msg->findInt32("range_offset", &rangeOffset)); 4308 CHECK(msg->findInt32("range_length", &rangeLength)); 4309 CHECK(msg->findInt32("flags", &flags)); 4310 CHECK(msg->findInt64("timestamp", &timeUs)); 4311 4312 return onOMXFillBufferDone( 4313 bufferID, 4314 (size_t)rangeOffset, (size_t)rangeLength, 4315 (OMX_U32)flags, 4316 timeUs); 4317 } 4318 4319 default: 4320 TRESPASS(); 4321 break; 4322 } 4323} 4324 4325bool ACodec::BaseState::onOMXEvent( 4326 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4327 if (event != OMX_EventError) { 4328 ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)", 4329 mCodec->mComponentName.c_str(), event, data1, data2); 4330 4331 return false; 4332 } 4333 4334 ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1); 4335 4336 // verify OMX component sends back an error we expect. 4337 OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1; 4338 if (!isOMXError(omxError)) { 4339 ALOGW("Invalid OMX error %#x", omxError); 4340 omxError = OMX_ErrorUndefined; 4341 } 4342 mCodec->signalError(omxError); 4343 4344 return true; 4345} 4346 4347bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) { 4348 ALOGV("[%s] onOMXEmptyBufferDone %u", 4349 mCodec->mComponentName.c_str(), bufferID); 4350 4351 BufferInfo *info = 4352 mCodec->findBufferByID(kPortIndexInput, bufferID); 4353 4354 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT); 4355 info->mStatus = BufferInfo::OWNED_BY_US; 4356 4357 // We're in "store-metadata-in-buffers" mode, the underlying 4358 // OMX component had access to data that's implicitly refcounted 4359 // by this "MediaBuffer" object. Now that the OMX component has 4360 // told us that it's done with the input buffer, we can decrement 4361 // the mediaBuffer's reference count. 4362 info->mData->setMediaBufferBase(NULL); 4363 4364 PortMode mode = getPortMode(kPortIndexInput); 4365 4366 switch (mode) { 4367 case KEEP_BUFFERS: 4368 break; 4369 4370 case RESUBMIT_BUFFERS: 4371 postFillThisBuffer(info); 4372 break; 4373 4374 default: 4375 { 4376 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 4377 TRESPASS(); // Not currently used 4378 break; 4379 } 4380 } 4381 4382 return true; 4383} 4384 4385void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) { 4386 if (mCodec->mPortEOS[kPortIndexInput]) { 4387 return; 4388 } 4389 4390 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 4391 4392 sp<AMessage> notify = mCodec->mNotify->dup(); 4393 notify->setInt32("what", CodecBase::kWhatFillThisBuffer); 4394 notify->setInt32("buffer-id", info->mBufferID); 4395 4396 info->mData->meta()->clear(); 4397 notify->setBuffer("buffer", info->mData); 4398 4399 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec); 4400 reply->setInt32("buffer-id", info->mBufferID); 4401 4402 notify->setMessage("reply", reply); 4403 4404 notify->post(); 4405 4406 info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 4407} 4408 4409void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { 4410 IOMX::buffer_id bufferID; 4411 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 4412 sp<ABuffer> buffer; 4413 int32_t err = OK; 4414 bool eos = false; 4415 PortMode mode = getPortMode(kPortIndexInput); 4416 4417 if (!msg->findBuffer("buffer", &buffer)) { 4418 /* these are unfilled buffers returned by client */ 4419 CHECK(msg->findInt32("err", &err)); 4420 4421 if (err == OK) { 4422 /* buffers with no errors are returned on MediaCodec.flush */ 4423 mode = KEEP_BUFFERS; 4424 } else { 4425 ALOGV("[%s] saw error %d instead of an input buffer", 4426 mCodec->mComponentName.c_str(), err); 4427 eos = true; 4428 } 4429 4430 buffer.clear(); 4431 } 4432 4433 int32_t tmp; 4434 if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) { 4435 eos = true; 4436 err = ERROR_END_OF_STREAM; 4437 } 4438 4439 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 4440 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM); 4441 4442 info->mStatus = BufferInfo::OWNED_BY_US; 4443 4444 switch (mode) { 4445 case KEEP_BUFFERS: 4446 { 4447 if (eos) { 4448 if (!mCodec->mPortEOS[kPortIndexInput]) { 4449 mCodec->mPortEOS[kPortIndexInput] = true; 4450 mCodec->mInputEOSResult = err; 4451 } 4452 } 4453 break; 4454 } 4455 4456 case RESUBMIT_BUFFERS: 4457 { 4458 if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) { 4459 int64_t timeUs; 4460 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 4461 4462 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 4463 4464 int32_t isCSD; 4465 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) { 4466 flags |= OMX_BUFFERFLAG_CODECCONFIG; 4467 } 4468 4469 if (eos) { 4470 flags |= OMX_BUFFERFLAG_EOS; 4471 } 4472 4473 if (buffer != info->mData) { 4474 ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)", 4475 mCodec->mComponentName.c_str(), 4476 bufferID, 4477 buffer.get(), info->mData.get()); 4478 4479 CHECK_LE(buffer->size(), info->mData->capacity()); 4480 memcpy(info->mData->data(), buffer->data(), buffer->size()); 4481 } 4482 4483 if (flags & OMX_BUFFERFLAG_CODECCONFIG) { 4484 ALOGV("[%s] calling emptyBuffer %u w/ codec specific data", 4485 mCodec->mComponentName.c_str(), bufferID); 4486 } else if (flags & OMX_BUFFERFLAG_EOS) { 4487 ALOGV("[%s] calling emptyBuffer %u w/ EOS", 4488 mCodec->mComponentName.c_str(), bufferID); 4489 } else { 4490#if TRACK_BUFFER_TIMING 4491 ALOGI("[%s] calling emptyBuffer %u w/ time %lld us", 4492 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 4493#else 4494 ALOGV("[%s] calling emptyBuffer %u w/ time %lld us", 4495 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 4496#endif 4497 } 4498 4499#if TRACK_BUFFER_TIMING 4500 ACodec::BufferStats stats; 4501 stats.mEmptyBufferTimeUs = ALooper::GetNowUs(); 4502 stats.mFillBufferDoneTimeUs = -1ll; 4503 mCodec->mBufferStats.add(timeUs, stats); 4504#endif 4505 4506 if (mCodec->mStoreMetaDataInOutputBuffers) { 4507 // try to submit an output buffer for each input buffer 4508 PortMode outputMode = getPortMode(kPortIndexOutput); 4509 4510 ALOGV("MetaDataBuffersToSubmit=%u portMode=%s", 4511 mCodec->mMetaDataBuffersToSubmit, 4512 (outputMode == FREE_BUFFERS ? "FREE" : 4513 outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT")); 4514 if (outputMode == RESUBMIT_BUFFERS) { 4515 mCodec->submitOutputMetaDataBuffer(); 4516 } 4517 } 4518 4519 CHECK_EQ(mCodec->mOMX->emptyBuffer( 4520 mCodec->mNode, 4521 bufferID, 4522 0, 4523 buffer->size(), 4524 flags, 4525 timeUs), 4526 (status_t)OK); 4527 4528 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 4529 4530 if (!eos) { 4531 getMoreInputDataIfPossible(); 4532 } else { 4533 ALOGV("[%s] Signalled EOS on the input port", 4534 mCodec->mComponentName.c_str()); 4535 4536 mCodec->mPortEOS[kPortIndexInput] = true; 4537 mCodec->mInputEOSResult = err; 4538 } 4539 } else if (!mCodec->mPortEOS[kPortIndexInput]) { 4540 if (err != ERROR_END_OF_STREAM) { 4541 ALOGV("[%s] Signalling EOS on the input port " 4542 "due to error %d", 4543 mCodec->mComponentName.c_str(), err); 4544 } else { 4545 ALOGV("[%s] Signalling EOS on the input port", 4546 mCodec->mComponentName.c_str()); 4547 } 4548 4549 ALOGV("[%s] calling emptyBuffer %u signalling EOS", 4550 mCodec->mComponentName.c_str(), bufferID); 4551 4552 CHECK_EQ(mCodec->mOMX->emptyBuffer( 4553 mCodec->mNode, 4554 bufferID, 4555 0, 4556 0, 4557 OMX_BUFFERFLAG_EOS, 4558 0), 4559 (status_t)OK); 4560 4561 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 4562 4563 mCodec->mPortEOS[kPortIndexInput] = true; 4564 mCodec->mInputEOSResult = err; 4565 } 4566 break; 4567 } 4568 4569 default: 4570 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 4571 break; 4572 } 4573} 4574 4575void ACodec::BaseState::getMoreInputDataIfPossible() { 4576 if (mCodec->mPortEOS[kPortIndexInput]) { 4577 return; 4578 } 4579 4580 BufferInfo *eligible = NULL; 4581 4582 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 4583 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 4584 4585#if 0 4586 if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 4587 // There's already a "read" pending. 4588 return; 4589 } 4590#endif 4591 4592 if (info->mStatus == BufferInfo::OWNED_BY_US) { 4593 eligible = info; 4594 } 4595 } 4596 4597 if (eligible == NULL) { 4598 return; 4599 } 4600 4601 postFillThisBuffer(eligible); 4602} 4603 4604bool ACodec::BaseState::onOMXFillBufferDone( 4605 IOMX::buffer_id bufferID, 4606 size_t rangeOffset, size_t rangeLength, 4607 OMX_U32 flags, 4608 int64_t timeUs) { 4609 ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x", 4610 mCodec->mComponentName.c_str(), bufferID, timeUs, flags); 4611 4612 ssize_t index; 4613 4614#if TRACK_BUFFER_TIMING 4615 index = mCodec->mBufferStats.indexOfKey(timeUs); 4616 if (index >= 0) { 4617 ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index); 4618 stats->mFillBufferDoneTimeUs = ALooper::GetNowUs(); 4619 4620 ALOGI("frame PTS %lld: %lld", 4621 timeUs, 4622 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs); 4623 4624 mCodec->mBufferStats.removeItemsAt(index); 4625 stats = NULL; 4626 } 4627#endif 4628 4629 BufferInfo *info = 4630 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 4631 4632 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT); 4633 4634 info->mDequeuedAt = ++mCodec->mDequeueCounter; 4635 info->mStatus = BufferInfo::OWNED_BY_US; 4636 4637 PortMode mode = getPortMode(kPortIndexOutput); 4638 4639 switch (mode) { 4640 case KEEP_BUFFERS: 4641 break; 4642 4643 case RESUBMIT_BUFFERS: 4644 { 4645 if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS) 4646 || mCodec->mPortEOS[kPortIndexOutput])) { 4647 ALOGV("[%s] calling fillBuffer %u", 4648 mCodec->mComponentName.c_str(), info->mBufferID); 4649 4650 CHECK_EQ(mCodec->mOMX->fillBuffer( 4651 mCodec->mNode, info->mBufferID), 4652 (status_t)OK); 4653 4654 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 4655 break; 4656 } 4657 4658 sp<AMessage> reply = 4659 new AMessage(kWhatOutputBufferDrained, mCodec); 4660 4661 if (!mCodec->mSentFormat && rangeLength > 0) { 4662 mCodec->sendFormatChange(reply); 4663 } 4664 4665 if (mCodec->mUseMetadataOnEncoderOutput) { 4666 native_handle_t* handle = 4667 *(native_handle_t**)(info->mData->data() + 4); 4668 info->mData->meta()->setPointer("handle", handle); 4669 info->mData->meta()->setInt32("rangeOffset", rangeOffset); 4670 info->mData->meta()->setInt32("rangeLength", rangeLength); 4671 } else { 4672 info->mData->setRange(rangeOffset, rangeLength); 4673 } 4674#if 0 4675 if (mCodec->mNativeWindow == NULL) { 4676 if (IsIDR(info->mData)) { 4677 ALOGI("IDR frame"); 4678 } 4679 } 4680#endif 4681 4682 if (mCodec->mSkipCutBuffer != NULL) { 4683 mCodec->mSkipCutBuffer->submit(info->mData); 4684 } 4685 info->mData->meta()->setInt64("timeUs", timeUs); 4686 4687 sp<AMessage> notify = mCodec->mNotify->dup(); 4688 notify->setInt32("what", CodecBase::kWhatDrainThisBuffer); 4689 notify->setInt32("buffer-id", info->mBufferID); 4690 notify->setBuffer("buffer", info->mData); 4691 notify->setInt32("flags", flags); 4692 4693 reply->setInt32("buffer-id", info->mBufferID); 4694 4695 notify->setMessage("reply", reply); 4696 4697 notify->post(); 4698 4699 info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 4700 4701 if (flags & OMX_BUFFERFLAG_EOS) { 4702 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str()); 4703 4704 sp<AMessage> notify = mCodec->mNotify->dup(); 4705 notify->setInt32("what", CodecBase::kWhatEOS); 4706 notify->setInt32("err", mCodec->mInputEOSResult); 4707 notify->post(); 4708 4709 mCodec->mPortEOS[kPortIndexOutput] = true; 4710 } 4711 break; 4712 } 4713 4714 default: 4715 { 4716 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 4717 4718 CHECK_EQ((status_t)OK, 4719 mCodec->freeBuffer(kPortIndexOutput, index)); 4720 break; 4721 } 4722 } 4723 4724 return true; 4725} 4726 4727void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 4728 IOMX::buffer_id bufferID; 4729 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 4730 ssize_t index; 4731 BufferInfo *info = 4732 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 4733 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM); 4734 4735 android_native_rect_t crop; 4736 if (msg->findRect("crop", 4737 &crop.left, &crop.top, &crop.right, &crop.bottom)) { 4738 CHECK_EQ(0, native_window_set_crop( 4739 mCodec->mNativeWindow.get(), &crop)); 4740 } 4741 4742 int32_t render; 4743 if (mCodec->mNativeWindow != NULL 4744 && msg->findInt32("render", &render) && render != 0 4745 && info->mData != NULL && info->mData->size() != 0) { 4746 ATRACE_NAME("render"); 4747 // The client wants this buffer to be rendered. 4748 4749 int64_t timestampNs = 0; 4750 if (!msg->findInt64("timestampNs", ×tampNs)) { 4751 // TODO: it seems like we should use the timestamp 4752 // in the (media)buffer as it potentially came from 4753 // an input surface, but we did not propagate it prior to 4754 // API 20. Perhaps check for target SDK version. 4755#if 0 4756 if (info->mData->meta()->findInt64("timeUs", ×tampNs)) { 4757 ALOGV("using buffer PTS of %" PRId64, timestampNs); 4758 timestampNs *= 1000; 4759 } 4760#endif 4761 } 4762 4763 status_t err; 4764 err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs); 4765 if (err != OK) { 4766 ALOGW("failed to set buffer timestamp: %d", err); 4767 } 4768 4769 if ((err = mCodec->mNativeWindow->queueBuffer( 4770 mCodec->mNativeWindow.get(), 4771 info->mGraphicBuffer.get(), -1)) == OK) { 4772 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 4773 } else { 4774 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 4775 info->mStatus = BufferInfo::OWNED_BY_US; 4776 } 4777 } else { 4778 if (mCodec->mNativeWindow != NULL && 4779 (info->mData == NULL || info->mData->size() != 0)) { 4780 ATRACE_NAME("frame-drop"); 4781 } 4782 info->mStatus = BufferInfo::OWNED_BY_US; 4783 } 4784 4785 PortMode mode = getPortMode(kPortIndexOutput); 4786 4787 switch (mode) { 4788 case KEEP_BUFFERS: 4789 { 4790 // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 4791 4792 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 4793 // We cannot resubmit the buffer we just rendered, dequeue 4794 // the spare instead. 4795 4796 info = mCodec->dequeueBufferFromNativeWindow(); 4797 } 4798 break; 4799 } 4800 4801 case RESUBMIT_BUFFERS: 4802 { 4803 if (!mCodec->mPortEOS[kPortIndexOutput]) { 4804 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 4805 // We cannot resubmit the buffer we just rendered, dequeue 4806 // the spare instead. 4807 4808 info = mCodec->dequeueBufferFromNativeWindow(); 4809 } 4810 4811 if (info != NULL) { 4812 ALOGV("[%s] calling fillBuffer %u", 4813 mCodec->mComponentName.c_str(), info->mBufferID); 4814 4815 CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), 4816 (status_t)OK); 4817 4818 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 4819 } 4820 } 4821 break; 4822 } 4823 4824 default: 4825 { 4826 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 4827 4828 CHECK_EQ((status_t)OK, 4829 mCodec->freeBuffer(kPortIndexOutput, index)); 4830 break; 4831 } 4832 } 4833} 4834 4835//////////////////////////////////////////////////////////////////////////////// 4836 4837ACodec::UninitializedState::UninitializedState(ACodec *codec) 4838 : BaseState(codec) { 4839} 4840 4841void ACodec::UninitializedState::stateEntered() { 4842 ALOGV("Now uninitialized"); 4843 4844 if (mDeathNotifier != NULL) { 4845 IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier); 4846 mDeathNotifier.clear(); 4847 } 4848 4849 mCodec->mNativeWindow.clear(); 4850 mCodec->mNode = 0; 4851 mCodec->mOMX.clear(); 4852 mCodec->mQuirks = 0; 4853 mCodec->mFlags = 0; 4854 mCodec->mUseMetadataOnEncoderOutput = 0; 4855 mCodec->mComponentName.clear(); 4856} 4857 4858bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 4859 bool handled = false; 4860 4861 switch (msg->what()) { 4862 case ACodec::kWhatSetup: 4863 { 4864 onSetup(msg); 4865 4866 handled = true; 4867 break; 4868 } 4869 4870 case ACodec::kWhatAllocateComponent: 4871 { 4872 onAllocateComponent(msg); 4873 handled = true; 4874 break; 4875 } 4876 4877 case ACodec::kWhatShutdown: 4878 { 4879 int32_t keepComponentAllocated; 4880 CHECK(msg->findInt32( 4881 "keepComponentAllocated", &keepComponentAllocated)); 4882 ALOGW_IF(keepComponentAllocated, 4883 "cannot keep component allocated on shutdown in Uninitialized state"); 4884 4885 sp<AMessage> notify = mCodec->mNotify->dup(); 4886 notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 4887 notify->post(); 4888 4889 handled = true; 4890 break; 4891 } 4892 4893 case ACodec::kWhatFlush: 4894 { 4895 sp<AMessage> notify = mCodec->mNotify->dup(); 4896 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 4897 notify->post(); 4898 4899 handled = true; 4900 break; 4901 } 4902 4903 case ACodec::kWhatReleaseCodecInstance: 4904 { 4905 // nothing to do, as we have already signaled shutdown 4906 handled = true; 4907 break; 4908 } 4909 4910 default: 4911 return BaseState::onMessageReceived(msg); 4912 } 4913 4914 return handled; 4915} 4916 4917void ACodec::UninitializedState::onSetup( 4918 const sp<AMessage> &msg) { 4919 if (onAllocateComponent(msg) 4920 && mCodec->mLoadedState->onConfigureComponent(msg)) { 4921 mCodec->mLoadedState->onStart(); 4922 } 4923} 4924 4925bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { 4926 ALOGV("onAllocateComponent"); 4927 4928 CHECK(mCodec->mNode == 0); 4929 4930 OMXClient client; 4931 if (client.connect() != OK) { 4932 mCodec->signalError(OMX_ErrorUndefined, NO_INIT); 4933 return false; 4934 } 4935 4936 sp<IOMX> omx = client.interface(); 4937 4938 sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec); 4939 4940 mDeathNotifier = new DeathNotifier(notify); 4941 if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) { 4942 // This was a local binder, if it dies so do we, we won't care 4943 // about any notifications in the afterlife. 4944 mDeathNotifier.clear(); 4945 } 4946 4947 Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs; 4948 4949 AString mime; 4950 4951 AString componentName; 4952 uint32_t quirks = 0; 4953 int32_t encoder = false; 4954 if (msg->findString("componentName", &componentName)) { 4955 ssize_t index = matchingCodecs.add(); 4956 OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index); 4957 entry->mName = String8(componentName.c_str()); 4958 4959 if (!OMXCodec::findCodecQuirks( 4960 componentName.c_str(), &entry->mQuirks)) { 4961 entry->mQuirks = 0; 4962 } 4963 } else { 4964 CHECK(msg->findString("mime", &mime)); 4965 4966 if (!msg->findInt32("encoder", &encoder)) { 4967 encoder = false; 4968 } 4969 4970 OMXCodec::findMatchingCodecs( 4971 mime.c_str(), 4972 encoder, // createEncoder 4973 NULL, // matchComponentName 4974 0, // flags 4975 &matchingCodecs); 4976 } 4977 4978 sp<CodecObserver> observer = new CodecObserver; 4979 IOMX::node_id node = 0; 4980 4981 status_t err = OMX_ErrorComponentNotFound; 4982 for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); 4983 ++matchIndex) { 4984 componentName = matchingCodecs.itemAt(matchIndex).mName.string(); 4985 quirks = matchingCodecs.itemAt(matchIndex).mQuirks; 4986 4987 pid_t tid = gettid(); 4988 int prevPriority = androidGetThreadPriority(tid); 4989 androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); 4990 err = omx->allocateNode(componentName.c_str(), observer, &node); 4991 androidSetThreadPriority(tid, prevPriority); 4992 4993 if (err == OK) { 4994 break; 4995 } else { 4996 ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str()); 4997 } 4998 4999 node = 0; 5000 } 5001 5002 if (node == 0) { 5003 if (!mime.empty()) { 5004 ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.", 5005 encoder ? "en" : "de", mime.c_str(), err); 5006 } else { 5007 ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err); 5008 } 5009 5010 mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err)); 5011 return false; 5012 } 5013 5014 notify = new AMessage(kWhatOMXMessage, mCodec); 5015 observer->setNotificationMessage(notify); 5016 5017 mCodec->mComponentName = componentName; 5018 mCodec->mFlags = 0; 5019 5020 if (componentName.endsWith(".secure")) { 5021 mCodec->mFlags |= kFlagIsSecure; 5022 mCodec->mFlags |= kFlagIsGrallocUsageProtected; 5023 mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 5024 } 5025 5026 mCodec->mQuirks = quirks; 5027 mCodec->mOMX = omx; 5028 mCodec->mNode = node; 5029 5030 { 5031 sp<AMessage> notify = mCodec->mNotify->dup(); 5032 notify->setInt32("what", CodecBase::kWhatComponentAllocated); 5033 notify->setString("componentName", mCodec->mComponentName.c_str()); 5034 notify->post(); 5035 } 5036 5037 mCodec->changeState(mCodec->mLoadedState); 5038 5039 return true; 5040} 5041 5042//////////////////////////////////////////////////////////////////////////////// 5043 5044ACodec::LoadedState::LoadedState(ACodec *codec) 5045 : BaseState(codec) { 5046} 5047 5048void ACodec::LoadedState::stateEntered() { 5049 ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 5050 5051 mCodec->mPortEOS[kPortIndexInput] = 5052 mCodec->mPortEOS[kPortIndexOutput] = false; 5053 5054 mCodec->mInputEOSResult = OK; 5055 5056 mCodec->mDequeueCounter = 0; 5057 mCodec->mMetaDataBuffersToSubmit = 0; 5058 mCodec->mRepeatFrameDelayUs = -1ll; 5059 mCodec->mInputFormat.clear(); 5060 mCodec->mOutputFormat.clear(); 5061 mCodec->mBaseOutputFormat.clear(); 5062 5063 if (mCodec->mShutdownInProgress) { 5064 bool keepComponentAllocated = mCodec->mKeepComponentAllocated; 5065 5066 mCodec->mShutdownInProgress = false; 5067 mCodec->mKeepComponentAllocated = false; 5068 5069 onShutdown(keepComponentAllocated); 5070 } 5071 mCodec->mExplicitShutdown = false; 5072 5073 mCodec->processDeferredMessages(); 5074} 5075 5076void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) { 5077 if (!keepComponentAllocated) { 5078 CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK); 5079 5080 mCodec->changeState(mCodec->mUninitializedState); 5081 } 5082 5083 if (mCodec->mExplicitShutdown) { 5084 sp<AMessage> notify = mCodec->mNotify->dup(); 5085 notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 5086 notify->post(); 5087 mCodec->mExplicitShutdown = false; 5088 } 5089} 5090 5091bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) { 5092 bool handled = false; 5093 5094 switch (msg->what()) { 5095 case ACodec::kWhatConfigureComponent: 5096 { 5097 onConfigureComponent(msg); 5098 handled = true; 5099 break; 5100 } 5101 5102 case ACodec::kWhatCreateInputSurface: 5103 { 5104 onCreateInputSurface(msg); 5105 handled = true; 5106 break; 5107 } 5108 5109 case ACodec::kWhatUsePersistentInputSurface: 5110 { 5111 onUsePersistentInputSurface(msg); 5112 handled = true; 5113 break; 5114 } 5115 5116 case ACodec::kWhatStart: 5117 { 5118 onStart(); 5119 handled = true; 5120 break; 5121 } 5122 5123 case ACodec::kWhatShutdown: 5124 { 5125 int32_t keepComponentAllocated; 5126 CHECK(msg->findInt32( 5127 "keepComponentAllocated", &keepComponentAllocated)); 5128 5129 mCodec->mExplicitShutdown = true; 5130 onShutdown(keepComponentAllocated); 5131 5132 handled = true; 5133 break; 5134 } 5135 5136 case ACodec::kWhatFlush: 5137 { 5138 sp<AMessage> notify = mCodec->mNotify->dup(); 5139 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5140 notify->post(); 5141 5142 handled = true; 5143 break; 5144 } 5145 5146 default: 5147 return BaseState::onMessageReceived(msg); 5148 } 5149 5150 return handled; 5151} 5152 5153bool ACodec::LoadedState::onConfigureComponent( 5154 const sp<AMessage> &msg) { 5155 ALOGV("onConfigureComponent"); 5156 5157 CHECK(mCodec->mNode != 0); 5158 5159 AString mime; 5160 CHECK(msg->findString("mime", &mime)); 5161 5162 status_t err = mCodec->configureCodec(mime.c_str(), msg); 5163 5164 if (err != OK) { 5165 ALOGE("[%s] configureCodec returning error %d", 5166 mCodec->mComponentName.c_str(), err); 5167 5168 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5169 return false; 5170 } 5171 5172 { 5173 sp<AMessage> notify = mCodec->mNotify->dup(); 5174 notify->setInt32("what", CodecBase::kWhatComponentConfigured); 5175 notify->setMessage("input-format", mCodec->mInputFormat); 5176 notify->setMessage("output-format", mCodec->mOutputFormat); 5177 notify->post(); 5178 } 5179 5180 return true; 5181} 5182 5183status_t ACodec::LoadedState::setupInputSurface() { 5184 status_t err = OK; 5185 5186 if (mCodec->mRepeatFrameDelayUs > 0ll) { 5187 err = mCodec->mOMX->setInternalOption( 5188 mCodec->mNode, 5189 kPortIndexInput, 5190 IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY, 5191 &mCodec->mRepeatFrameDelayUs, 5192 sizeof(mCodec->mRepeatFrameDelayUs)); 5193 5194 if (err != OK) { 5195 ALOGE("[%s] Unable to configure option to repeat previous " 5196 "frames (err %d)", 5197 mCodec->mComponentName.c_str(), 5198 err); 5199 return err; 5200 } 5201 } 5202 5203 if (mCodec->mMaxPtsGapUs > 0ll) { 5204 err = mCodec->mOMX->setInternalOption( 5205 mCodec->mNode, 5206 kPortIndexInput, 5207 IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP, 5208 &mCodec->mMaxPtsGapUs, 5209 sizeof(mCodec->mMaxPtsGapUs)); 5210 5211 if (err != OK) { 5212 ALOGE("[%s] Unable to configure max timestamp gap (err %d)", 5213 mCodec->mComponentName.c_str(), 5214 err); 5215 return err; 5216 } 5217 } 5218 5219 if (mCodec->mMaxFps > 0) { 5220 err = mCodec->mOMX->setInternalOption( 5221 mCodec->mNode, 5222 kPortIndexInput, 5223 IOMX::INTERNAL_OPTION_MAX_FPS, 5224 &mCodec->mMaxFps, 5225 sizeof(mCodec->mMaxFps)); 5226 5227 if (err != OK) { 5228 ALOGE("[%s] Unable to configure max fps (err %d)", 5229 mCodec->mComponentName.c_str(), 5230 err); 5231 return err; 5232 } 5233 } 5234 5235 if (mCodec->mTimePerCaptureUs > 0ll 5236 && mCodec->mTimePerFrameUs > 0ll) { 5237 int64_t timeLapse[2]; 5238 timeLapse[0] = mCodec->mTimePerFrameUs; 5239 timeLapse[1] = mCodec->mTimePerCaptureUs; 5240 err = mCodec->mOMX->setInternalOption( 5241 mCodec->mNode, 5242 kPortIndexInput, 5243 IOMX::INTERNAL_OPTION_TIME_LAPSE, 5244 &timeLapse[0], 5245 sizeof(timeLapse)); 5246 5247 if (err != OK) { 5248 ALOGE("[%s] Unable to configure time lapse (err %d)", 5249 mCodec->mComponentName.c_str(), 5250 err); 5251 return err; 5252 } 5253 } 5254 5255 if (mCodec->mCreateInputBuffersSuspended) { 5256 bool suspend = true; 5257 err = mCodec->mOMX->setInternalOption( 5258 mCodec->mNode, 5259 kPortIndexInput, 5260 IOMX::INTERNAL_OPTION_SUSPEND, 5261 &suspend, 5262 sizeof(suspend)); 5263 5264 if (err != OK) { 5265 ALOGE("[%s] Unable to configure option to suspend (err %d)", 5266 mCodec->mComponentName.c_str(), 5267 err); 5268 return err; 5269 } 5270 } 5271 5272 return OK; 5273} 5274 5275void ACodec::LoadedState::onCreateInputSurface( 5276 const sp<AMessage> & /* msg */) { 5277 ALOGV("onCreateInputSurface"); 5278 5279 sp<AMessage> notify = mCodec->mNotify->dup(); 5280 notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated); 5281 5282 sp<IGraphicBufferProducer> bufferProducer; 5283 status_t err = mCodec->mOMX->createInputSurface( 5284 mCodec->mNode, kPortIndexInput, &bufferProducer); 5285 5286 if (err == OK) { 5287 err = setupInputSurface(); 5288 } 5289 5290 if (err == OK) { 5291 notify->setObject("input-surface", 5292 new BufferProducerWrapper(bufferProducer)); 5293 } else { 5294 // Can't use mCodec->signalError() here -- MediaCodec won't forward 5295 // the error through because it's in the "configured" state. We 5296 // send a kWhatInputSurfaceCreated with an error value instead. 5297 ALOGE("[%s] onCreateInputSurface returning error %d", 5298 mCodec->mComponentName.c_str(), err); 5299 notify->setInt32("err", err); 5300 } 5301 notify->post(); 5302} 5303 5304void ACodec::LoadedState::onUsePersistentInputSurface( 5305 const sp<AMessage> &msg) { 5306 ALOGV("onUsePersistentInputSurface"); 5307 5308 sp<AMessage> notify = mCodec->mNotify->dup(); 5309 notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted); 5310 5311 sp<RefBase> obj; 5312 CHECK(msg->findObject("input-surface", &obj)); 5313 sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get()); 5314 5315 status_t err = mCodec->mOMX->usePersistentInputSurface( 5316 mCodec->mNode, kPortIndexInput, surface->getBufferConsumer()); 5317 5318 if (err == OK) { 5319 err = setupInputSurface(); 5320 } 5321 5322 if (err != OK) { 5323 // Can't use mCodec->signalError() here -- MediaCodec won't forward 5324 // the error through because it's in the "configured" state. We 5325 // send a kWhatInputSurfaceAccepted with an error value instead. 5326 ALOGE("[%s] onUsePersistentInputSurface returning error %d", 5327 mCodec->mComponentName.c_str(), err); 5328 notify->setInt32("err", err); 5329 } 5330 notify->post(); 5331} 5332 5333void ACodec::LoadedState::onStart() { 5334 ALOGV("onStart"); 5335 5336 CHECK_EQ(mCodec->mOMX->sendCommand( 5337 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle), 5338 (status_t)OK); 5339 5340 mCodec->changeState(mCodec->mLoadedToIdleState); 5341} 5342 5343//////////////////////////////////////////////////////////////////////////////// 5344 5345ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 5346 : BaseState(codec) { 5347} 5348 5349void ACodec::LoadedToIdleState::stateEntered() { 5350 ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 5351 5352 status_t err; 5353 if ((err = allocateBuffers()) != OK) { 5354 ALOGE("Failed to allocate buffers after transitioning to IDLE state " 5355 "(error 0x%08x)", 5356 err); 5357 5358 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5359 5360 mCodec->changeState(mCodec->mLoadedState); 5361 } 5362} 5363 5364status_t ACodec::LoadedToIdleState::allocateBuffers() { 5365 status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 5366 5367 if (err != OK) { 5368 return err; 5369 } 5370 5371 return mCodec->allocateBuffersOnPort(kPortIndexOutput); 5372} 5373 5374bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 5375 switch (msg->what()) { 5376 case kWhatSetParameters: 5377 case kWhatShutdown: 5378 { 5379 mCodec->deferMessage(msg); 5380 return true; 5381 } 5382 5383 case kWhatSignalEndOfInputStream: 5384 { 5385 mCodec->onSignalEndOfInputStream(); 5386 return true; 5387 } 5388 5389 case kWhatResume: 5390 { 5391 // We'll be active soon enough. 5392 return true; 5393 } 5394 5395 case kWhatFlush: 5396 { 5397 // We haven't even started yet, so we're flushed alright... 5398 sp<AMessage> notify = mCodec->mNotify->dup(); 5399 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5400 notify->post(); 5401 return true; 5402 } 5403 5404 default: 5405 return BaseState::onMessageReceived(msg); 5406 } 5407} 5408 5409bool ACodec::LoadedToIdleState::onOMXEvent( 5410 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5411 switch (event) { 5412 case OMX_EventCmdComplete: 5413 { 5414 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 5415 CHECK_EQ(data2, (OMX_U32)OMX_StateIdle); 5416 5417 CHECK_EQ(mCodec->mOMX->sendCommand( 5418 mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting), 5419 (status_t)OK); 5420 5421 mCodec->changeState(mCodec->mIdleToExecutingState); 5422 5423 return true; 5424 } 5425 5426 default: 5427 return BaseState::onOMXEvent(event, data1, data2); 5428 } 5429} 5430 5431//////////////////////////////////////////////////////////////////////////////// 5432 5433ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 5434 : BaseState(codec) { 5435} 5436 5437void ACodec::IdleToExecutingState::stateEntered() { 5438 ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 5439} 5440 5441bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 5442 switch (msg->what()) { 5443 case kWhatSetParameters: 5444 case kWhatShutdown: 5445 { 5446 mCodec->deferMessage(msg); 5447 return true; 5448 } 5449 5450 case kWhatResume: 5451 { 5452 // We'll be active soon enough. 5453 return true; 5454 } 5455 5456 case kWhatFlush: 5457 { 5458 // We haven't even started yet, so we're flushed alright... 5459 sp<AMessage> notify = mCodec->mNotify->dup(); 5460 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5461 notify->post(); 5462 5463 return true; 5464 } 5465 5466 case kWhatSignalEndOfInputStream: 5467 { 5468 mCodec->onSignalEndOfInputStream(); 5469 return true; 5470 } 5471 5472 default: 5473 return BaseState::onMessageReceived(msg); 5474 } 5475} 5476 5477bool ACodec::IdleToExecutingState::onOMXEvent( 5478 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5479 switch (event) { 5480 case OMX_EventCmdComplete: 5481 { 5482 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 5483 CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting); 5484 5485 mCodec->mExecutingState->resume(); 5486 mCodec->changeState(mCodec->mExecutingState); 5487 5488 return true; 5489 } 5490 5491 default: 5492 return BaseState::onOMXEvent(event, data1, data2); 5493 } 5494} 5495 5496//////////////////////////////////////////////////////////////////////////////// 5497 5498ACodec::ExecutingState::ExecutingState(ACodec *codec) 5499 : BaseState(codec), 5500 mActive(false) { 5501} 5502 5503ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 5504 OMX_U32 /* portIndex */) { 5505 return RESUBMIT_BUFFERS; 5506} 5507 5508void ACodec::ExecutingState::submitOutputMetaBuffers() { 5509 // submit as many buffers as there are input buffers with the codec 5510 // in case we are in port reconfiguring 5511 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 5512 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 5513 5514 if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) { 5515 if (mCodec->submitOutputMetaDataBuffer() != OK) 5516 break; 5517 } 5518 } 5519 5520 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 5521 mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround(); 5522} 5523 5524void ACodec::ExecutingState::submitRegularOutputBuffers() { 5525 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 5526 BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 5527 5528 if (mCodec->mNativeWindow != NULL) { 5529 CHECK(info->mStatus == BufferInfo::OWNED_BY_US 5530 || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW); 5531 5532 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 5533 continue; 5534 } 5535 } else { 5536 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 5537 } 5538 5539 ALOGV("[%s] calling fillBuffer %u", 5540 mCodec->mComponentName.c_str(), info->mBufferID); 5541 5542 CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), 5543 (status_t)OK); 5544 5545 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5546 } 5547} 5548 5549void ACodec::ExecutingState::submitOutputBuffers() { 5550 submitRegularOutputBuffers(); 5551 if (mCodec->mStoreMetaDataInOutputBuffers) { 5552 submitOutputMetaBuffers(); 5553 } 5554} 5555 5556void ACodec::ExecutingState::resume() { 5557 if (mActive) { 5558 ALOGV("[%s] We're already active, no need to resume.", 5559 mCodec->mComponentName.c_str()); 5560 5561 return; 5562 } 5563 5564 submitOutputBuffers(); 5565 5566 // Post all available input buffers 5567 CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u); 5568 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) { 5569 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 5570 if (info->mStatus == BufferInfo::OWNED_BY_US) { 5571 postFillThisBuffer(info); 5572 } 5573 } 5574 5575 mActive = true; 5576} 5577 5578void ACodec::ExecutingState::stateEntered() { 5579 ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 5580 5581 mCodec->processDeferredMessages(); 5582} 5583 5584bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 5585 bool handled = false; 5586 5587 switch (msg->what()) { 5588 case kWhatShutdown: 5589 { 5590 int32_t keepComponentAllocated; 5591 CHECK(msg->findInt32( 5592 "keepComponentAllocated", &keepComponentAllocated)); 5593 5594 mCodec->mShutdownInProgress = true; 5595 mCodec->mExplicitShutdown = true; 5596 mCodec->mKeepComponentAllocated = keepComponentAllocated; 5597 5598 mActive = false; 5599 5600 CHECK_EQ(mCodec->mOMX->sendCommand( 5601 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle), 5602 (status_t)OK); 5603 5604 mCodec->changeState(mCodec->mExecutingToIdleState); 5605 5606 handled = true; 5607 break; 5608 } 5609 5610 case kWhatFlush: 5611 { 5612 ALOGV("[%s] ExecutingState flushing now " 5613 "(codec owns %zu/%zu input, %zu/%zu output).", 5614 mCodec->mComponentName.c_str(), 5615 mCodec->countBuffersOwnedByComponent(kPortIndexInput), 5616 mCodec->mBuffers[kPortIndexInput].size(), 5617 mCodec->countBuffersOwnedByComponent(kPortIndexOutput), 5618 mCodec->mBuffers[kPortIndexOutput].size()); 5619 5620 mActive = false; 5621 5622 CHECK_EQ(mCodec->mOMX->sendCommand( 5623 mCodec->mNode, OMX_CommandFlush, OMX_ALL), 5624 (status_t)OK); 5625 5626 mCodec->changeState(mCodec->mFlushingState); 5627 handled = true; 5628 break; 5629 } 5630 5631 case kWhatResume: 5632 { 5633 resume(); 5634 5635 handled = true; 5636 break; 5637 } 5638 5639 case kWhatRequestIDRFrame: 5640 { 5641 status_t err = mCodec->requestIDRFrame(); 5642 if (err != OK) { 5643 ALOGW("Requesting an IDR frame failed."); 5644 } 5645 5646 handled = true; 5647 break; 5648 } 5649 5650 case kWhatSetParameters: 5651 { 5652 sp<AMessage> params; 5653 CHECK(msg->findMessage("params", ¶ms)); 5654 5655 status_t err = mCodec->setParameters(params); 5656 5657 sp<AMessage> reply; 5658 if (msg->findMessage("reply", &reply)) { 5659 reply->setInt32("err", err); 5660 reply->post(); 5661 } 5662 5663 handled = true; 5664 break; 5665 } 5666 5667 case ACodec::kWhatSignalEndOfInputStream: 5668 { 5669 mCodec->onSignalEndOfInputStream(); 5670 handled = true; 5671 break; 5672 } 5673 5674 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 5675 case kWhatSubmitOutputMetaDataBufferIfEOS: 5676 { 5677 if (mCodec->mPortEOS[kPortIndexInput] && 5678 !mCodec->mPortEOS[kPortIndexOutput]) { 5679 status_t err = mCodec->submitOutputMetaDataBuffer(); 5680 if (err == OK) { 5681 mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround(); 5682 } 5683 } 5684 return true; 5685 } 5686 5687 default: 5688 handled = BaseState::onMessageReceived(msg); 5689 break; 5690 } 5691 5692 return handled; 5693} 5694 5695status_t ACodec::setParameters(const sp<AMessage> ¶ms) { 5696 int32_t videoBitrate; 5697 if (params->findInt32("video-bitrate", &videoBitrate)) { 5698 OMX_VIDEO_CONFIG_BITRATETYPE configParams; 5699 InitOMXParams(&configParams); 5700 configParams.nPortIndex = kPortIndexOutput; 5701 configParams.nEncodeBitrate = videoBitrate; 5702 5703 status_t err = mOMX->setConfig( 5704 mNode, 5705 OMX_IndexConfigVideoBitrate, 5706 &configParams, 5707 sizeof(configParams)); 5708 5709 if (err != OK) { 5710 ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d", 5711 videoBitrate, err); 5712 5713 return err; 5714 } 5715 } 5716 5717 int64_t skipFramesBeforeUs; 5718 if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) { 5719 status_t err = 5720 mOMX->setInternalOption( 5721 mNode, 5722 kPortIndexInput, 5723 IOMX::INTERNAL_OPTION_START_TIME, 5724 &skipFramesBeforeUs, 5725 sizeof(skipFramesBeforeUs)); 5726 5727 if (err != OK) { 5728 ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err); 5729 return err; 5730 } 5731 } 5732 5733 int32_t dropInputFrames; 5734 if (params->findInt32("drop-input-frames", &dropInputFrames)) { 5735 bool suspend = dropInputFrames != 0; 5736 5737 status_t err = 5738 mOMX->setInternalOption( 5739 mNode, 5740 kPortIndexInput, 5741 IOMX::INTERNAL_OPTION_SUSPEND, 5742 &suspend, 5743 sizeof(suspend)); 5744 5745 if (err != OK) { 5746 ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err); 5747 return err; 5748 } 5749 } 5750 5751 int32_t dummy; 5752 if (params->findInt32("request-sync", &dummy)) { 5753 status_t err = requestIDRFrame(); 5754 5755 if (err != OK) { 5756 ALOGE("Requesting a sync frame failed w/ err %d", err); 5757 return err; 5758 } 5759 } 5760 5761 float rate; 5762 if (params->findFloat("operating-rate", &rate) && rate > 0) { 5763 status_t err = setOperatingRate(rate, mIsVideo); 5764 if (err != OK) { 5765 ALOGE("Failed to set parameter 'operating-rate' (err %d)", err); 5766 return err; 5767 } 5768 } 5769 5770 return OK; 5771} 5772 5773void ACodec::onSignalEndOfInputStream() { 5774 sp<AMessage> notify = mNotify->dup(); 5775 notify->setInt32("what", CodecBase::kWhatSignaledInputEOS); 5776 5777 status_t err = mOMX->signalEndOfInputStream(mNode); 5778 if (err != OK) { 5779 notify->setInt32("err", err); 5780 } 5781 notify->post(); 5782} 5783 5784bool ACodec::ExecutingState::onOMXEvent( 5785 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5786 switch (event) { 5787 case OMX_EventPortSettingsChanged: 5788 { 5789 CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 5790 5791 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 5792 mCodec->mMetaDataBuffersToSubmit = 0; 5793 CHECK_EQ(mCodec->mOMX->sendCommand( 5794 mCodec->mNode, 5795 OMX_CommandPortDisable, kPortIndexOutput), 5796 (status_t)OK); 5797 5798 mCodec->freeOutputBuffersNotOwnedByComponent(); 5799 5800 mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 5801 } else if (data2 == OMX_IndexConfigCommonOutputCrop) { 5802 mCodec->mSentFormat = false; 5803 } else { 5804 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x", 5805 mCodec->mComponentName.c_str(), data2); 5806 } 5807 5808 return true; 5809 } 5810 5811 case OMX_EventBufferFlag: 5812 { 5813 return true; 5814 } 5815 5816 default: 5817 return BaseState::onOMXEvent(event, data1, data2); 5818 } 5819} 5820 5821//////////////////////////////////////////////////////////////////////////////// 5822 5823ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 5824 ACodec *codec) 5825 : BaseState(codec) { 5826} 5827 5828ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 5829 OMX_U32 portIndex) { 5830 if (portIndex == kPortIndexOutput) { 5831 return FREE_BUFFERS; 5832 } 5833 5834 CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 5835 5836 return RESUBMIT_BUFFERS; 5837} 5838 5839bool ACodec::OutputPortSettingsChangedState::onMessageReceived( 5840 const sp<AMessage> &msg) { 5841 bool handled = false; 5842 5843 switch (msg->what()) { 5844 case kWhatFlush: 5845 case kWhatShutdown: 5846 case kWhatResume: 5847 case kWhatSetParameters: 5848 { 5849 if (msg->what() == kWhatResume) { 5850 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 5851 } 5852 5853 mCodec->deferMessage(msg); 5854 handled = true; 5855 break; 5856 } 5857 5858 default: 5859 handled = BaseState::onMessageReceived(msg); 5860 break; 5861 } 5862 5863 return handled; 5864} 5865 5866void ACodec::OutputPortSettingsChangedState::stateEntered() { 5867 ALOGV("[%s] Now handling output port settings change", 5868 mCodec->mComponentName.c_str()); 5869} 5870 5871bool ACodec::OutputPortSettingsChangedState::onOMXEvent( 5872 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5873 switch (event) { 5874 case OMX_EventCmdComplete: 5875 { 5876 if (data1 == (OMX_U32)OMX_CommandPortDisable) { 5877 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput); 5878 5879 ALOGV("[%s] Output port now disabled.", 5880 mCodec->mComponentName.c_str()); 5881 5882 CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty()); 5883 mCodec->mDealer[kPortIndexOutput].clear(); 5884 5885 CHECK_EQ(mCodec->mOMX->sendCommand( 5886 mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput), 5887 (status_t)OK); 5888 5889 status_t err; 5890 if ((err = mCodec->allocateBuffersOnPort( 5891 kPortIndexOutput)) != OK) { 5892 ALOGE("Failed to allocate output port buffers after " 5893 "port reconfiguration (error 0x%08x)", 5894 err); 5895 5896 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5897 5898 // This is technically not correct, but appears to be 5899 // the only way to free the component instance. 5900 // Controlled transitioning from excecuting->idle 5901 // and idle->loaded seem impossible probably because 5902 // the output port never finishes re-enabling. 5903 mCodec->mShutdownInProgress = true; 5904 mCodec->mKeepComponentAllocated = false; 5905 mCodec->changeState(mCodec->mLoadedState); 5906 } 5907 5908 return true; 5909 } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 5910 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput); 5911 5912 mCodec->mSentFormat = false; 5913 5914 ALOGV("[%s] Output port now reenabled.", 5915 mCodec->mComponentName.c_str()); 5916 5917 if (mCodec->mExecutingState->active()) { 5918 mCodec->mExecutingState->submitOutputBuffers(); 5919 } 5920 5921 mCodec->changeState(mCodec->mExecutingState); 5922 5923 return true; 5924 } 5925 5926 return false; 5927 } 5928 5929 default: 5930 return false; 5931 } 5932} 5933 5934//////////////////////////////////////////////////////////////////////////////// 5935 5936ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 5937 : BaseState(codec), 5938 mComponentNowIdle(false) { 5939} 5940 5941bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 5942 bool handled = false; 5943 5944 switch (msg->what()) { 5945 case kWhatFlush: 5946 { 5947 // Don't send me a flush request if you previously wanted me 5948 // to shutdown. 5949 TRESPASS(); 5950 break; 5951 } 5952 5953 case kWhatShutdown: 5954 { 5955 // We're already doing that... 5956 5957 handled = true; 5958 break; 5959 } 5960 5961 default: 5962 handled = BaseState::onMessageReceived(msg); 5963 break; 5964 } 5965 5966 return handled; 5967} 5968 5969void ACodec::ExecutingToIdleState::stateEntered() { 5970 ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 5971 5972 mComponentNowIdle = false; 5973 mCodec->mSentFormat = false; 5974} 5975 5976bool ACodec::ExecutingToIdleState::onOMXEvent( 5977 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5978 switch (event) { 5979 case OMX_EventCmdComplete: 5980 { 5981 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 5982 CHECK_EQ(data2, (OMX_U32)OMX_StateIdle); 5983 5984 mComponentNowIdle = true; 5985 5986 changeStateIfWeOwnAllBuffers(); 5987 5988 return true; 5989 } 5990 5991 case OMX_EventPortSettingsChanged: 5992 case OMX_EventBufferFlag: 5993 { 5994 // We're shutting down and don't care about this anymore. 5995 return true; 5996 } 5997 5998 default: 5999 return BaseState::onOMXEvent(event, data1, data2); 6000 } 6001} 6002 6003void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 6004 if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) { 6005 CHECK_EQ(mCodec->mOMX->sendCommand( 6006 mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded), 6007 (status_t)OK); 6008 6009 CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK); 6010 CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK); 6011 6012 if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) 6013 && mCodec->mNativeWindow != NULL) { 6014 // We push enough 1x1 blank buffers to ensure that one of 6015 // them has made it to the display. This allows the OMX 6016 // component teardown to zero out any protected buffers 6017 // without the risk of scanning out one of those buffers. 6018 mCodec->pushBlankBuffersToNativeWindow(); 6019 } 6020 6021 mCodec->changeState(mCodec->mIdleToLoadedState); 6022 } 6023} 6024 6025void ACodec::ExecutingToIdleState::onInputBufferFilled( 6026 const sp<AMessage> &msg) { 6027 BaseState::onInputBufferFilled(msg); 6028 6029 changeStateIfWeOwnAllBuffers(); 6030} 6031 6032void ACodec::ExecutingToIdleState::onOutputBufferDrained( 6033 const sp<AMessage> &msg) { 6034 BaseState::onOutputBufferDrained(msg); 6035 6036 changeStateIfWeOwnAllBuffers(); 6037} 6038 6039//////////////////////////////////////////////////////////////////////////////// 6040 6041ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 6042 : BaseState(codec) { 6043} 6044 6045bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 6046 bool handled = false; 6047 6048 switch (msg->what()) { 6049 case kWhatShutdown: 6050 { 6051 // We're already doing that... 6052 6053 handled = true; 6054 break; 6055 } 6056 6057 case kWhatFlush: 6058 { 6059 // Don't send me a flush request if you previously wanted me 6060 // to shutdown. 6061 TRESPASS(); 6062 break; 6063 } 6064 6065 default: 6066 handled = BaseState::onMessageReceived(msg); 6067 break; 6068 } 6069 6070 return handled; 6071} 6072 6073void ACodec::IdleToLoadedState::stateEntered() { 6074 ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 6075} 6076 6077bool ACodec::IdleToLoadedState::onOMXEvent( 6078 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6079 switch (event) { 6080 case OMX_EventCmdComplete: 6081 { 6082 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 6083 CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded); 6084 6085 mCodec->changeState(mCodec->mLoadedState); 6086 6087 return true; 6088 } 6089 6090 default: 6091 return BaseState::onOMXEvent(event, data1, data2); 6092 } 6093} 6094 6095//////////////////////////////////////////////////////////////////////////////// 6096 6097ACodec::FlushingState::FlushingState(ACodec *codec) 6098 : BaseState(codec) { 6099} 6100 6101void ACodec::FlushingState::stateEntered() { 6102 ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 6103 6104 mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 6105} 6106 6107bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 6108 bool handled = false; 6109 6110 switch (msg->what()) { 6111 case kWhatShutdown: 6112 { 6113 mCodec->deferMessage(msg); 6114 break; 6115 } 6116 6117 case kWhatFlush: 6118 { 6119 // We're already doing this right now. 6120 handled = true; 6121 break; 6122 } 6123 6124 default: 6125 handled = BaseState::onMessageReceived(msg); 6126 break; 6127 } 6128 6129 return handled; 6130} 6131 6132bool ACodec::FlushingState::onOMXEvent( 6133 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6134 ALOGV("[%s] FlushingState onOMXEvent(%u,%d)", 6135 mCodec->mComponentName.c_str(), event, (OMX_S32)data1); 6136 6137 switch (event) { 6138 case OMX_EventCmdComplete: 6139 { 6140 CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush); 6141 6142 if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 6143 CHECK(!mFlushComplete[data2]); 6144 mFlushComplete[data2] = true; 6145 6146 if (mFlushComplete[kPortIndexInput] 6147 && mFlushComplete[kPortIndexOutput]) { 6148 changeStateIfWeOwnAllBuffers(); 6149 } 6150 } else { 6151 CHECK_EQ(data2, OMX_ALL); 6152 CHECK(mFlushComplete[kPortIndexInput]); 6153 CHECK(mFlushComplete[kPortIndexOutput]); 6154 6155 changeStateIfWeOwnAllBuffers(); 6156 } 6157 6158 return true; 6159 } 6160 6161 case OMX_EventPortSettingsChanged: 6162 { 6163 sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec); 6164 msg->setInt32("type", omx_message::EVENT); 6165 msg->setInt32("node", mCodec->mNode); 6166 msg->setInt32("event", event); 6167 msg->setInt32("data1", data1); 6168 msg->setInt32("data2", data2); 6169 6170 ALOGV("[%s] Deferring OMX_EventPortSettingsChanged", 6171 mCodec->mComponentName.c_str()); 6172 6173 mCodec->deferMessage(msg); 6174 6175 return true; 6176 } 6177 6178 default: 6179 return BaseState::onOMXEvent(event, data1, data2); 6180 } 6181 6182 return true; 6183} 6184 6185void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 6186 BaseState::onOutputBufferDrained(msg); 6187 6188 changeStateIfWeOwnAllBuffers(); 6189} 6190 6191void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 6192 BaseState::onInputBufferFilled(msg); 6193 6194 changeStateIfWeOwnAllBuffers(); 6195} 6196 6197void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 6198 if (mFlushComplete[kPortIndexInput] 6199 && mFlushComplete[kPortIndexOutput] 6200 && mCodec->allYourBuffersAreBelongToUs()) { 6201 // We now own all buffers except possibly those still queued with 6202 // the native window for rendering. Let's get those back as well. 6203 mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs(); 6204 6205 sp<AMessage> notify = mCodec->mNotify->dup(); 6206 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 6207 notify->post(); 6208 6209 mCodec->mPortEOS[kPortIndexInput] = 6210 mCodec->mPortEOS[kPortIndexOutput] = false; 6211 6212 mCodec->mInputEOSResult = OK; 6213 6214 if (mCodec->mSkipCutBuffer != NULL) { 6215 mCodec->mSkipCutBuffer->clear(); 6216 } 6217 6218 mCodec->changeState(mCodec->mExecutingState); 6219 } 6220} 6221 6222} // namespace android 6223