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