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