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