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