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