ACodec.cpp revision 201d8d400eb037547f4f476a838475b13a446007
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 ALOGI("setupVideoEncoder succeeded"); 2861 2862 return err; 2863} 2864 2865status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) { 2866 OMX_VIDEO_PARAM_INTRAREFRESHTYPE params; 2867 InitOMXParams(¶ms); 2868 params.nPortIndex = kPortIndexOutput; 2869 2870 params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode); 2871 2872 if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic || 2873 params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 2874 int32_t mbs; 2875 if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) { 2876 return INVALID_OPERATION; 2877 } 2878 params.nCirMBs = mbs; 2879 } 2880 2881 if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive || 2882 params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 2883 int32_t mbs; 2884 if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) { 2885 return INVALID_OPERATION; 2886 } 2887 params.nAirMBs = mbs; 2888 2889 int32_t ref; 2890 if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) { 2891 return INVALID_OPERATION; 2892 } 2893 params.nAirRef = ref; 2894 } 2895 2896 status_t err = mOMX->setParameter( 2897 mNode, OMX_IndexParamVideoIntraRefresh, 2898 ¶ms, sizeof(params)); 2899 return err; 2900} 2901 2902static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) { 2903 if (iFramesInterval < 0) { 2904 return 0xFFFFFFFF; 2905 } else if (iFramesInterval == 0) { 2906 return 0; 2907 } 2908 OMX_U32 ret = frameRate * iFramesInterval; 2909 return ret; 2910} 2911 2912static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) { 2913 int32_t tmp; 2914 if (!msg->findInt32("bitrate-mode", &tmp)) { 2915 return OMX_Video_ControlRateVariable; 2916 } 2917 2918 return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp); 2919} 2920 2921status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) { 2922 int32_t bitrate, iFrameInterval; 2923 if (!msg->findInt32("bitrate", &bitrate) 2924 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 2925 return INVALID_OPERATION; 2926 } 2927 2928 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 2929 2930 float frameRate; 2931 if (!msg->findFloat("frame-rate", &frameRate)) { 2932 int32_t tmp; 2933 if (!msg->findInt32("frame-rate", &tmp)) { 2934 return INVALID_OPERATION; 2935 } 2936 frameRate = (float)tmp; 2937 } 2938 2939 OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type; 2940 InitOMXParams(&mpeg4type); 2941 mpeg4type.nPortIndex = kPortIndexOutput; 2942 2943 status_t err = mOMX->getParameter( 2944 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 2945 2946 if (err != OK) { 2947 return err; 2948 } 2949 2950 mpeg4type.nSliceHeaderSpacing = 0; 2951 mpeg4type.bSVH = OMX_FALSE; 2952 mpeg4type.bGov = OMX_FALSE; 2953 2954 mpeg4type.nAllowedPictureTypes = 2955 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 2956 2957 mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 2958 if (mpeg4type.nPFrames == 0) { 2959 mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 2960 } 2961 mpeg4type.nBFrames = 0; 2962 mpeg4type.nIDCVLCThreshold = 0; 2963 mpeg4type.bACPred = OMX_TRUE; 2964 mpeg4type.nMaxPacketSize = 256; 2965 mpeg4type.nTimeIncRes = 1000; 2966 mpeg4type.nHeaderExtension = 0; 2967 mpeg4type.bReversibleVLC = OMX_FALSE; 2968 2969 int32_t profile; 2970 if (msg->findInt32("profile", &profile)) { 2971 int32_t level; 2972 if (!msg->findInt32("level", &level)) { 2973 return INVALID_OPERATION; 2974 } 2975 2976 err = verifySupportForProfileAndLevel(profile, level); 2977 2978 if (err != OK) { 2979 return err; 2980 } 2981 2982 mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile); 2983 mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level); 2984 } 2985 2986 err = mOMX->setParameter( 2987 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 2988 2989 if (err != OK) { 2990 return err; 2991 } 2992 2993 err = configureBitrate(bitrate, bitrateMode); 2994 2995 if (err != OK) { 2996 return err; 2997 } 2998 2999 return setupErrorCorrectionParameters(); 3000} 3001 3002status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) { 3003 int32_t bitrate, iFrameInterval; 3004 if (!msg->findInt32("bitrate", &bitrate) 3005 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 3006 return INVALID_OPERATION; 3007 } 3008 3009 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 3010 3011 float frameRate; 3012 if (!msg->findFloat("frame-rate", &frameRate)) { 3013 int32_t tmp; 3014 if (!msg->findInt32("frame-rate", &tmp)) { 3015 return INVALID_OPERATION; 3016 } 3017 frameRate = (float)tmp; 3018 } 3019 3020 OMX_VIDEO_PARAM_H263TYPE h263type; 3021 InitOMXParams(&h263type); 3022 h263type.nPortIndex = kPortIndexOutput; 3023 3024 status_t err = mOMX->getParameter( 3025 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 3026 3027 if (err != OK) { 3028 return err; 3029 } 3030 3031 h263type.nAllowedPictureTypes = 3032 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 3033 3034 h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 3035 if (h263type.nPFrames == 0) { 3036 h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 3037 } 3038 h263type.nBFrames = 0; 3039 3040 int32_t profile; 3041 if (msg->findInt32("profile", &profile)) { 3042 int32_t level; 3043 if (!msg->findInt32("level", &level)) { 3044 return INVALID_OPERATION; 3045 } 3046 3047 err = verifySupportForProfileAndLevel(profile, level); 3048 3049 if (err != OK) { 3050 return err; 3051 } 3052 3053 h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile); 3054 h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level); 3055 } 3056 3057 h263type.bPLUSPTYPEAllowed = OMX_FALSE; 3058 h263type.bForceRoundingTypeToZero = OMX_FALSE; 3059 h263type.nPictureHeaderRepetition = 0; 3060 h263type.nGOBHeaderInterval = 0; 3061 3062 err = mOMX->setParameter( 3063 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 3064 3065 if (err != OK) { 3066 return err; 3067 } 3068 3069 err = configureBitrate(bitrate, bitrateMode); 3070 3071 if (err != OK) { 3072 return err; 3073 } 3074 3075 return setupErrorCorrectionParameters(); 3076} 3077 3078// static 3079int /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor( 3080 int width, int height, int rate, int bitrate, 3081 OMX_VIDEO_AVCPROFILETYPE profile) { 3082 // convert bitrate to main/baseline profile kbps equivalent 3083 switch (profile) { 3084 case OMX_VIDEO_AVCProfileHigh10: 3085 bitrate = divUp(bitrate, 3000); break; 3086 case OMX_VIDEO_AVCProfileHigh: 3087 bitrate = divUp(bitrate, 1250); break; 3088 default: 3089 bitrate = divUp(bitrate, 1000); break; 3090 } 3091 3092 // convert size and rate to MBs 3093 width = divUp(width, 16); 3094 height = divUp(height, 16); 3095 int mbs = width * height; 3096 rate *= mbs; 3097 int maxDimension = max(width, height); 3098 3099 static const int limits[][5] = { 3100 /* MBps MB dim bitrate level */ 3101 { 1485, 99, 28, 64, OMX_VIDEO_AVCLevel1 }, 3102 { 1485, 99, 28, 128, OMX_VIDEO_AVCLevel1b }, 3103 { 3000, 396, 56, 192, OMX_VIDEO_AVCLevel11 }, 3104 { 6000, 396, 56, 384, OMX_VIDEO_AVCLevel12 }, 3105 { 11880, 396, 56, 768, OMX_VIDEO_AVCLevel13 }, 3106 { 11880, 396, 56, 2000, OMX_VIDEO_AVCLevel2 }, 3107 { 19800, 792, 79, 4000, OMX_VIDEO_AVCLevel21 }, 3108 { 20250, 1620, 113, 4000, OMX_VIDEO_AVCLevel22 }, 3109 { 40500, 1620, 113, 10000, OMX_VIDEO_AVCLevel3 }, 3110 { 108000, 3600, 169, 14000, OMX_VIDEO_AVCLevel31 }, 3111 { 216000, 5120, 202, 20000, OMX_VIDEO_AVCLevel32 }, 3112 { 245760, 8192, 256, 20000, OMX_VIDEO_AVCLevel4 }, 3113 { 245760, 8192, 256, 50000, OMX_VIDEO_AVCLevel41 }, 3114 { 522240, 8704, 263, 50000, OMX_VIDEO_AVCLevel42 }, 3115 { 589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5 }, 3116 { 983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 }, 3117 { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 }, 3118 }; 3119 3120 for (size_t i = 0; i < ARRAY_SIZE(limits); i++) { 3121 const int (&limit)[5] = limits[i]; 3122 if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2] 3123 && bitrate <= limit[3]) { 3124 return limit[4]; 3125 } 3126 } 3127 return 0; 3128} 3129 3130status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) { 3131 int32_t bitrate, iFrameInterval; 3132 if (!msg->findInt32("bitrate", &bitrate) 3133 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 3134 return INVALID_OPERATION; 3135 } 3136 3137 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 3138 3139 float frameRate; 3140 if (!msg->findFloat("frame-rate", &frameRate)) { 3141 int32_t tmp; 3142 if (!msg->findInt32("frame-rate", &tmp)) { 3143 return INVALID_OPERATION; 3144 } 3145 frameRate = (float)tmp; 3146 } 3147 3148 status_t err = OK; 3149 int32_t intraRefreshMode = 0; 3150 if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) { 3151 err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode); 3152 if (err != OK) { 3153 ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x", 3154 err, intraRefreshMode); 3155 return err; 3156 } 3157 } 3158 3159 OMX_VIDEO_PARAM_AVCTYPE h264type; 3160 InitOMXParams(&h264type); 3161 h264type.nPortIndex = kPortIndexOutput; 3162 3163 err = mOMX->getParameter( 3164 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 3165 3166 if (err != OK) { 3167 return err; 3168 } 3169 3170 h264type.nAllowedPictureTypes = 3171 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 3172 3173 int32_t profile; 3174 if (msg->findInt32("profile", &profile)) { 3175 int32_t level; 3176 if (!msg->findInt32("level", &level)) { 3177 return INVALID_OPERATION; 3178 } 3179 3180 err = verifySupportForProfileAndLevel(profile, level); 3181 3182 if (err != OK) { 3183 return err; 3184 } 3185 3186 h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile); 3187 h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level); 3188 } 3189 3190 // XXX 3191 if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) { 3192 ALOGW("Use baseline profile instead of %d for AVC recording", 3193 h264type.eProfile); 3194 h264type.eProfile = OMX_VIDEO_AVCProfileBaseline; 3195 } 3196 3197 if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) { 3198 h264type.nSliceHeaderSpacing = 0; 3199 h264type.bUseHadamard = OMX_TRUE; 3200 h264type.nRefFrames = 1; 3201 h264type.nBFrames = 0; 3202 h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 3203 if (h264type.nPFrames == 0) { 3204 h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 3205 } 3206 h264type.nRefIdx10ActiveMinus1 = 0; 3207 h264type.nRefIdx11ActiveMinus1 = 0; 3208 h264type.bEntropyCodingCABAC = OMX_FALSE; 3209 h264type.bWeightedPPrediction = OMX_FALSE; 3210 h264type.bconstIpred = OMX_FALSE; 3211 h264type.bDirect8x8Inference = OMX_FALSE; 3212 h264type.bDirectSpatialTemporal = OMX_FALSE; 3213 h264type.nCabacInitIdc = 0; 3214 } 3215 3216 if (h264type.nBFrames != 0) { 3217 h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; 3218 } 3219 3220 h264type.bEnableUEP = OMX_FALSE; 3221 h264type.bEnableFMO = OMX_FALSE; 3222 h264type.bEnableASO = OMX_FALSE; 3223 h264type.bEnableRS = OMX_FALSE; 3224 h264type.bFrameMBsOnly = OMX_TRUE; 3225 h264type.bMBAFF = OMX_FALSE; 3226 h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; 3227 3228 err = mOMX->setParameter( 3229 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 3230 3231 if (err != OK) { 3232 return err; 3233 } 3234 3235 return configureBitrate(bitrate, bitrateMode); 3236} 3237 3238status_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) { 3239 int32_t bitrate, iFrameInterval; 3240 if (!msg->findInt32("bitrate", &bitrate) 3241 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 3242 return INVALID_OPERATION; 3243 } 3244 3245 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 3246 3247 float frameRate; 3248 if (!msg->findFloat("frame-rate", &frameRate)) { 3249 int32_t tmp; 3250 if (!msg->findInt32("frame-rate", &tmp)) { 3251 return INVALID_OPERATION; 3252 } 3253 frameRate = (float)tmp; 3254 } 3255 3256 OMX_VIDEO_PARAM_HEVCTYPE hevcType; 3257 InitOMXParams(&hevcType); 3258 hevcType.nPortIndex = kPortIndexOutput; 3259 3260 status_t err = OK; 3261 err = mOMX->getParameter( 3262 mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType)); 3263 if (err != OK) { 3264 return err; 3265 } 3266 3267 int32_t profile; 3268 if (msg->findInt32("profile", &profile)) { 3269 int32_t level; 3270 if (!msg->findInt32("level", &level)) { 3271 return INVALID_OPERATION; 3272 } 3273 3274 err = verifySupportForProfileAndLevel(profile, level); 3275 if (err != OK) { 3276 return err; 3277 } 3278 3279 hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile); 3280 hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level); 3281 } 3282 3283 // TODO: Need OMX structure definition for setting iFrameInterval 3284 3285 err = mOMX->setParameter( 3286 mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType)); 3287 if (err != OK) { 3288 return err; 3289 } 3290 3291 return configureBitrate(bitrate, bitrateMode); 3292} 3293 3294status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) { 3295 int32_t bitrate; 3296 int32_t iFrameInterval = 0; 3297 size_t tsLayers = 0; 3298 OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern = 3299 OMX_VIDEO_VPXTemporalLayerPatternNone; 3300 static const uint32_t kVp8LayerRateAlloction 3301 [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] 3302 [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = { 3303 {100, 100, 100}, // 1 layer 3304 { 60, 100, 100}, // 2 layers {60%, 40%} 3305 { 40, 60, 100}, // 3 layers {40%, 20%, 40%} 3306 }; 3307 if (!msg->findInt32("bitrate", &bitrate)) { 3308 return INVALID_OPERATION; 3309 } 3310 msg->findInt32("i-frame-interval", &iFrameInterval); 3311 3312 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 3313 3314 float frameRate; 3315 if (!msg->findFloat("frame-rate", &frameRate)) { 3316 int32_t tmp; 3317 if (!msg->findInt32("frame-rate", &tmp)) { 3318 return INVALID_OPERATION; 3319 } 3320 frameRate = (float)tmp; 3321 } 3322 3323 AString tsSchema; 3324 if (msg->findString("ts-schema", &tsSchema)) { 3325 if (tsSchema == "webrtc.vp8.1-layer") { 3326 pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 3327 tsLayers = 1; 3328 } else if (tsSchema == "webrtc.vp8.2-layer") { 3329 pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 3330 tsLayers = 2; 3331 } else if (tsSchema == "webrtc.vp8.3-layer") { 3332 pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 3333 tsLayers = 3; 3334 } else { 3335 ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str()); 3336 } 3337 } 3338 3339 OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; 3340 InitOMXParams(&vp8type); 3341 vp8type.nPortIndex = kPortIndexOutput; 3342 status_t err = mOMX->getParameter( 3343 mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 3344 &vp8type, sizeof(vp8type)); 3345 3346 if (err == OK) { 3347 if (iFrameInterval > 0) { 3348 vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate); 3349 } 3350 vp8type.eTemporalPattern = pattern; 3351 vp8type.nTemporalLayerCount = tsLayers; 3352 if (tsLayers > 0) { 3353 for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) { 3354 vp8type.nTemporalLayerBitrateRatio[i] = 3355 kVp8LayerRateAlloction[tsLayers - 1][i]; 3356 } 3357 } 3358 if (bitrateMode == OMX_Video_ControlRateConstant) { 3359 vp8type.nMinQuantizer = 2; 3360 vp8type.nMaxQuantizer = 63; 3361 } 3362 3363 err = mOMX->setParameter( 3364 mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 3365 &vp8type, sizeof(vp8type)); 3366 if (err != OK) { 3367 ALOGW("Extended VP8 parameters set failed: %d", err); 3368 } 3369 } 3370 3371 return configureBitrate(bitrate, bitrateMode); 3372} 3373 3374status_t ACodec::verifySupportForProfileAndLevel( 3375 int32_t profile, int32_t level) { 3376 OMX_VIDEO_PARAM_PROFILELEVELTYPE params; 3377 InitOMXParams(¶ms); 3378 params.nPortIndex = kPortIndexOutput; 3379 3380 for (params.nProfileIndex = 0;; ++params.nProfileIndex) { 3381 status_t err = mOMX->getParameter( 3382 mNode, 3383 OMX_IndexParamVideoProfileLevelQuerySupported, 3384 ¶ms, 3385 sizeof(params)); 3386 3387 if (err != OK) { 3388 return err; 3389 } 3390 3391 int32_t supportedProfile = static_cast<int32_t>(params.eProfile); 3392 int32_t supportedLevel = static_cast<int32_t>(params.eLevel); 3393 3394 if (profile == supportedProfile && level <= supportedLevel) { 3395 return OK; 3396 } 3397 } 3398} 3399 3400status_t ACodec::configureBitrate( 3401 int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) { 3402 OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 3403 InitOMXParams(&bitrateType); 3404 bitrateType.nPortIndex = kPortIndexOutput; 3405 3406 status_t err = mOMX->getParameter( 3407 mNode, OMX_IndexParamVideoBitrate, 3408 &bitrateType, sizeof(bitrateType)); 3409 3410 if (err != OK) { 3411 return err; 3412 } 3413 3414 bitrateType.eControlRate = bitrateMode; 3415 bitrateType.nTargetBitrate = bitrate; 3416 3417 return mOMX->setParameter( 3418 mNode, OMX_IndexParamVideoBitrate, 3419 &bitrateType, sizeof(bitrateType)); 3420} 3421 3422status_t ACodec::setupErrorCorrectionParameters() { 3423 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; 3424 InitOMXParams(&errorCorrectionType); 3425 errorCorrectionType.nPortIndex = kPortIndexOutput; 3426 3427 status_t err = mOMX->getParameter( 3428 mNode, OMX_IndexParamVideoErrorCorrection, 3429 &errorCorrectionType, sizeof(errorCorrectionType)); 3430 3431 if (err != OK) { 3432 return OK; // Optional feature. Ignore this failure 3433 } 3434 3435 errorCorrectionType.bEnableHEC = OMX_FALSE; 3436 errorCorrectionType.bEnableResync = OMX_TRUE; 3437 errorCorrectionType.nResynchMarkerSpacing = 256; 3438 errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; 3439 errorCorrectionType.bEnableRVLC = OMX_FALSE; 3440 3441 return mOMX->setParameter( 3442 mNode, OMX_IndexParamVideoErrorCorrection, 3443 &errorCorrectionType, sizeof(errorCorrectionType)); 3444} 3445 3446status_t ACodec::setVideoFormatOnPort( 3447 OMX_U32 portIndex, 3448 int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat, 3449 float frameRate) { 3450 OMX_PARAM_PORTDEFINITIONTYPE def; 3451 InitOMXParams(&def); 3452 def.nPortIndex = portIndex; 3453 3454 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 3455 3456 status_t err = mOMX->getParameter( 3457 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3458 if (err != OK) { 3459 return err; 3460 } 3461 3462 if (portIndex == kPortIndexInput) { 3463 // XXX Need a (much) better heuristic to compute input buffer sizes. 3464 const size_t X = 64 * 1024; 3465 if (def.nBufferSize < X) { 3466 def.nBufferSize = X; 3467 } 3468 } 3469 3470 if (def.eDomain != OMX_PortDomainVideo) { 3471 ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain); 3472 return FAILED_TRANSACTION; 3473 } 3474 3475 video_def->nFrameWidth = width; 3476 video_def->nFrameHeight = height; 3477 3478 if (portIndex == kPortIndexInput) { 3479 video_def->eCompressionFormat = compressionFormat; 3480 video_def->eColorFormat = OMX_COLOR_FormatUnused; 3481 if (frameRate >= 0) { 3482 video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f); 3483 } 3484 } 3485 3486 err = mOMX->setParameter( 3487 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3488 3489 return err; 3490} 3491 3492status_t ACodec::initNativeWindow() { 3493 if (mNativeWindow != NULL) { 3494 return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE); 3495 } 3496 3497 mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE); 3498 return OK; 3499} 3500 3501size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const { 3502 size_t n = 0; 3503 3504 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 3505 const BufferInfo &info = mBuffers[portIndex].itemAt(i); 3506 3507 if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) { 3508 ++n; 3509 } 3510 } 3511 3512 return n; 3513} 3514 3515size_t ACodec::countBuffersOwnedByNativeWindow() const { 3516 size_t n = 0; 3517 3518 for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) { 3519 const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i); 3520 3521 if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 3522 ++n; 3523 } 3524 } 3525 3526 return n; 3527} 3528 3529void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() { 3530 if (mNativeWindow == NULL) { 3531 return; 3532 } 3533 3534 while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers 3535 && dequeueBufferFromNativeWindow() != NULL) { 3536 // these buffers will be submitted as regular buffers; account for this 3537 if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) { 3538 --mMetaDataBuffersToSubmit; 3539 } 3540 } 3541} 3542 3543bool ACodec::allYourBuffersAreBelongToUs( 3544 OMX_U32 portIndex) { 3545 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 3546 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 3547 3548 if (info->mStatus != BufferInfo::OWNED_BY_US 3549 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 3550 ALOGV("[%s] Buffer %u on port %u still has status %d", 3551 mComponentName.c_str(), 3552 info->mBufferID, portIndex, info->mStatus); 3553 return false; 3554 } 3555 } 3556 3557 return true; 3558} 3559 3560bool ACodec::allYourBuffersAreBelongToUs() { 3561 return allYourBuffersAreBelongToUs(kPortIndexInput) 3562 && allYourBuffersAreBelongToUs(kPortIndexOutput); 3563} 3564 3565void ACodec::deferMessage(const sp<AMessage> &msg) { 3566 mDeferredQueue.push_back(msg); 3567} 3568 3569void ACodec::processDeferredMessages() { 3570 List<sp<AMessage> > queue = mDeferredQueue; 3571 mDeferredQueue.clear(); 3572 3573 List<sp<AMessage> >::iterator it = queue.begin(); 3574 while (it != queue.end()) { 3575 onMessageReceived(*it++); 3576 } 3577} 3578 3579// static 3580bool ACodec::describeDefaultColorFormat(DescribeColorFormatParams ¶ms) { 3581 MediaImage &image = params.sMediaImage; 3582 memset(&image, 0, sizeof(image)); 3583 3584 image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN; 3585 image.mNumPlanes = 0; 3586 3587 const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat; 3588 image.mWidth = params.nFrameWidth; 3589 image.mHeight = params.nFrameHeight; 3590 3591 // only supporting YUV420 3592 if (fmt != OMX_COLOR_FormatYUV420Planar && 3593 fmt != OMX_COLOR_FormatYUV420PackedPlanar && 3594 fmt != OMX_COLOR_FormatYUV420SemiPlanar && 3595 fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar && 3596 fmt != HAL_PIXEL_FORMAT_YV12) { 3597 ALOGW("do not know color format 0x%x = %d", fmt, fmt); 3598 return false; 3599 } 3600 3601 // TEMPORARY FIX for some vendors that advertise sliceHeight as 0 3602 if (params.nStride != 0 && params.nSliceHeight == 0) { 3603 ALOGW("using sliceHeight=%u instead of what codec advertised (=0)", 3604 params.nFrameHeight); 3605 params.nSliceHeight = params.nFrameHeight; 3606 } 3607 3608 // we need stride and slice-height to be non-zero 3609 if (params.nStride == 0 || params.nSliceHeight == 0) { 3610 ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u", 3611 fmt, fmt, params.nStride, params.nSliceHeight); 3612 return false; 3613 } 3614 3615 // set-up YUV format 3616 image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV; 3617 image.mNumPlanes = 3; 3618 image.mBitDepth = 8; 3619 image.mPlane[image.Y].mOffset = 0; 3620 image.mPlane[image.Y].mColInc = 1; 3621 image.mPlane[image.Y].mRowInc = params.nStride; 3622 image.mPlane[image.Y].mHorizSubsampling = 1; 3623 image.mPlane[image.Y].mVertSubsampling = 1; 3624 3625 switch ((int)fmt) { 3626 case HAL_PIXEL_FORMAT_YV12: 3627 if (params.bUsingNativeBuffers) { 3628 size_t ystride = align(params.nStride, 16); 3629 size_t cstride = align(params.nStride / 2, 16); 3630 image.mPlane[image.Y].mRowInc = ystride; 3631 3632 image.mPlane[image.V].mOffset = ystride * params.nSliceHeight; 3633 image.mPlane[image.V].mColInc = 1; 3634 image.mPlane[image.V].mRowInc = cstride; 3635 image.mPlane[image.V].mHorizSubsampling = 2; 3636 image.mPlane[image.V].mVertSubsampling = 2; 3637 3638 image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset 3639 + (cstride * params.nSliceHeight / 2); 3640 image.mPlane[image.U].mColInc = 1; 3641 image.mPlane[image.U].mRowInc = cstride; 3642 image.mPlane[image.U].mHorizSubsampling = 2; 3643 image.mPlane[image.U].mVertSubsampling = 2; 3644 break; 3645 } else { 3646 // fall through as YV12 is used for YUV420Planar by some codecs 3647 } 3648 3649 case OMX_COLOR_FormatYUV420Planar: 3650 case OMX_COLOR_FormatYUV420PackedPlanar: 3651 image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight; 3652 image.mPlane[image.U].mColInc = 1; 3653 image.mPlane[image.U].mRowInc = params.nStride / 2; 3654 image.mPlane[image.U].mHorizSubsampling = 2; 3655 image.mPlane[image.U].mVertSubsampling = 2; 3656 3657 image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset 3658 + (params.nStride * params.nSliceHeight / 4); 3659 image.mPlane[image.V].mColInc = 1; 3660 image.mPlane[image.V].mRowInc = params.nStride / 2; 3661 image.mPlane[image.V].mHorizSubsampling = 2; 3662 image.mPlane[image.V].mVertSubsampling = 2; 3663 break; 3664 3665 case OMX_COLOR_FormatYUV420SemiPlanar: 3666 // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder 3667 case OMX_COLOR_FormatYUV420PackedSemiPlanar: 3668 // NV12 3669 image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight; 3670 image.mPlane[image.U].mColInc = 2; 3671 image.mPlane[image.U].mRowInc = params.nStride; 3672 image.mPlane[image.U].mHorizSubsampling = 2; 3673 image.mPlane[image.U].mVertSubsampling = 2; 3674 3675 image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1; 3676 image.mPlane[image.V].mColInc = 2; 3677 image.mPlane[image.V].mRowInc = params.nStride; 3678 image.mPlane[image.V].mHorizSubsampling = 2; 3679 image.mPlane[image.V].mVertSubsampling = 2; 3680 break; 3681 3682 default: 3683 TRESPASS(); 3684 } 3685 return true; 3686} 3687 3688// static 3689bool ACodec::describeColorFormat( 3690 const sp<IOMX> &omx, IOMX::node_id node, 3691 DescribeColorFormatParams &describeParams) 3692{ 3693 OMX_INDEXTYPE describeColorFormatIndex; 3694 if (omx->getExtensionIndex( 3695 node, "OMX.google.android.index.describeColorFormat", 3696 &describeColorFormatIndex) != OK || 3697 omx->getParameter( 3698 node, describeColorFormatIndex, 3699 &describeParams, sizeof(describeParams)) != OK) { 3700 return describeDefaultColorFormat(describeParams); 3701 } 3702 return describeParams.sMediaImage.mType != 3703 MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN; 3704} 3705 3706// static 3707bool ACodec::isFlexibleColorFormat( 3708 const sp<IOMX> &omx, IOMX::node_id node, 3709 uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) { 3710 DescribeColorFormatParams describeParams; 3711 InitOMXParams(&describeParams); 3712 describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat; 3713 // reasonable dummy values 3714 describeParams.nFrameWidth = 128; 3715 describeParams.nFrameHeight = 128; 3716 describeParams.nStride = 128; 3717 describeParams.nSliceHeight = 128; 3718 describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers; 3719 3720 CHECK(flexibleEquivalent != NULL); 3721 3722 if (!describeColorFormat(omx, node, describeParams)) { 3723 return false; 3724 } 3725 3726 const MediaImage &img = describeParams.sMediaImage; 3727 if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) { 3728 if (img.mNumPlanes != 3 || 3729 img.mPlane[img.Y].mHorizSubsampling != 1 || 3730 img.mPlane[img.Y].mVertSubsampling != 1) { 3731 return false; 3732 } 3733 3734 // YUV 420 3735 if (img.mPlane[img.U].mHorizSubsampling == 2 3736 && img.mPlane[img.U].mVertSubsampling == 2 3737 && img.mPlane[img.V].mHorizSubsampling == 2 3738 && img.mPlane[img.V].mVertSubsampling == 2) { 3739 // possible flexible YUV420 format 3740 if (img.mBitDepth <= 8) { 3741 *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible; 3742 return true; 3743 } 3744 } 3745 } 3746 return false; 3747} 3748 3749status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) { 3750 const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output"; 3751 OMX_PARAM_PORTDEFINITIONTYPE def; 3752 InitOMXParams(&def); 3753 def.nPortIndex = portIndex; 3754 3755 status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3756 if (err != OK) { 3757 return err; 3758 } 3759 3760 if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) { 3761 ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex); 3762 return BAD_VALUE; 3763 } 3764 3765 switch (def.eDomain) { 3766 case OMX_PortDomainVideo: 3767 { 3768 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 3769 switch ((int)videoDef->eCompressionFormat) { 3770 case OMX_VIDEO_CodingUnused: 3771 { 3772 CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput)); 3773 notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW); 3774 3775 notify->setInt32("stride", videoDef->nStride); 3776 notify->setInt32("slice-height", videoDef->nSliceHeight); 3777 notify->setInt32("color-format", videoDef->eColorFormat); 3778 3779 if (mNativeWindow == NULL) { 3780 DescribeColorFormatParams describeParams; 3781 InitOMXParams(&describeParams); 3782 describeParams.eColorFormat = videoDef->eColorFormat; 3783 describeParams.nFrameWidth = videoDef->nFrameWidth; 3784 describeParams.nFrameHeight = videoDef->nFrameHeight; 3785 describeParams.nStride = videoDef->nStride; 3786 describeParams.nSliceHeight = videoDef->nSliceHeight; 3787 describeParams.bUsingNativeBuffers = OMX_FALSE; 3788 3789 if (describeColorFormat(mOMX, mNode, describeParams)) { 3790 notify->setBuffer( 3791 "image-data", 3792 ABuffer::CreateAsCopy( 3793 &describeParams.sMediaImage, 3794 sizeof(describeParams.sMediaImage))); 3795 3796 MediaImage *img = &describeParams.sMediaImage; 3797 ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }", 3798 mComponentName.c_str(), img->mWidth, img->mHeight, 3799 img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc, 3800 img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc, 3801 img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc); 3802 } 3803 } 3804 3805 if (portIndex != kPortIndexOutput) { 3806 // TODO: also get input crop 3807 break; 3808 } 3809 3810 OMX_CONFIG_RECTTYPE rect; 3811 InitOMXParams(&rect); 3812 rect.nPortIndex = portIndex; 3813 3814 if (mOMX->getConfig( 3815 mNode, 3816 (portIndex == kPortIndexOutput ? 3817 OMX_IndexConfigCommonOutputCrop : 3818 OMX_IndexConfigCommonInputCrop), 3819 &rect, sizeof(rect)) != OK) { 3820 rect.nLeft = 0; 3821 rect.nTop = 0; 3822 rect.nWidth = videoDef->nFrameWidth; 3823 rect.nHeight = videoDef->nFrameHeight; 3824 } 3825 3826 if (rect.nLeft < 0 || 3827 rect.nTop < 0 || 3828 rect.nLeft + rect.nWidth > videoDef->nFrameWidth || 3829 rect.nTop + rect.nHeight > videoDef->nFrameHeight) { 3830 ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)", 3831 rect.nLeft, rect.nTop, 3832 rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight, 3833 videoDef->nFrameWidth, videoDef->nFrameHeight); 3834 return BAD_VALUE; 3835 } 3836 3837 notify->setRect( 3838 "crop", 3839 rect.nLeft, 3840 rect.nTop, 3841 rect.nLeft + rect.nWidth - 1, 3842 rect.nTop + rect.nHeight - 1); 3843 3844 break; 3845 } 3846 3847 case OMX_VIDEO_CodingVP8: 3848 case OMX_VIDEO_CodingVP9: 3849 { 3850 OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; 3851 InitOMXParams(&vp8type); 3852 vp8type.nPortIndex = kPortIndexOutput; 3853 status_t err = mOMX->getParameter( 3854 mNode, 3855 (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 3856 &vp8type, 3857 sizeof(vp8type)); 3858 3859 if (err == OK) { 3860 AString tsSchema = "none"; 3861 if (vp8type.eTemporalPattern 3862 == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) { 3863 switch (vp8type.nTemporalLayerCount) { 3864 case 1: 3865 { 3866 tsSchema = "webrtc.vp8.1-layer"; 3867 break; 3868 } 3869 case 2: 3870 { 3871 tsSchema = "webrtc.vp8.2-layer"; 3872 break; 3873 } 3874 case 3: 3875 { 3876 tsSchema = "webrtc.vp8.3-layer"; 3877 break; 3878 } 3879 default: 3880 { 3881 break; 3882 } 3883 } 3884 } 3885 notify->setString("ts-schema", tsSchema); 3886 } 3887 // Fall through to set up mime. 3888 } 3889 3890 default: 3891 { 3892 if (mIsEncoder ^ (portIndex == kPortIndexOutput)) { 3893 // should be CodingUnused 3894 ALOGE("Raw port video compression format is %s(%d)", 3895 asString(videoDef->eCompressionFormat), 3896 videoDef->eCompressionFormat); 3897 return BAD_VALUE; 3898 } 3899 AString mime; 3900 if (GetMimeTypeForVideoCoding( 3901 videoDef->eCompressionFormat, &mime) != OK) { 3902 notify->setString("mime", "application/octet-stream"); 3903 } else { 3904 notify->setString("mime", mime.c_str()); 3905 } 3906 break; 3907 } 3908 } 3909 notify->setInt32("width", videoDef->nFrameWidth); 3910 notify->setInt32("height", videoDef->nFrameHeight); 3911 ALOGV("[%s] %s format is %s", mComponentName.c_str(), 3912 portIndex == kPortIndexInput ? "input" : "output", 3913 notify->debugString().c_str()); 3914 3915 break; 3916 } 3917 3918 case OMX_PortDomainAudio: 3919 { 3920 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 3921 3922 switch ((int)audioDef->eEncoding) { 3923 case OMX_AUDIO_CodingPCM: 3924 { 3925 OMX_AUDIO_PARAM_PCMMODETYPE params; 3926 InitOMXParams(¶ms); 3927 params.nPortIndex = portIndex; 3928 3929 err = mOMX->getParameter( 3930 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 3931 if (err != OK) { 3932 return err; 3933 } 3934 3935 if (params.nChannels <= 0 3936 || (params.nChannels != 1 && !params.bInterleaved) 3937 || params.nBitPerSample != 16u 3938 || params.eNumData != OMX_NumericalDataSigned 3939 || params.ePCMMode != OMX_AUDIO_PCMModeLinear) { 3940 ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ", 3941 params.nChannels, 3942 params.bInterleaved ? " interleaved" : "", 3943 params.nBitPerSample, 3944 asString(params.eNumData), params.eNumData, 3945 asString(params.ePCMMode), params.ePCMMode); 3946 return FAILED_TRANSACTION; 3947 } 3948 3949 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW); 3950 notify->setInt32("channel-count", params.nChannels); 3951 notify->setInt32("sample-rate", params.nSamplingRate); 3952 3953 if (mChannelMaskPresent) { 3954 notify->setInt32("channel-mask", mChannelMask); 3955 } 3956 break; 3957 } 3958 3959 case OMX_AUDIO_CodingAAC: 3960 { 3961 OMX_AUDIO_PARAM_AACPROFILETYPE params; 3962 InitOMXParams(¶ms); 3963 params.nPortIndex = portIndex; 3964 3965 err = mOMX->getParameter( 3966 mNode, OMX_IndexParamAudioAac, ¶ms, sizeof(params)); 3967 if (err != OK) { 3968 return err; 3969 } 3970 3971 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 3972 notify->setInt32("channel-count", params.nChannels); 3973 notify->setInt32("sample-rate", params.nSampleRate); 3974 break; 3975 } 3976 3977 case OMX_AUDIO_CodingAMR: 3978 { 3979 OMX_AUDIO_PARAM_AMRTYPE params; 3980 InitOMXParams(¶ms); 3981 params.nPortIndex = portIndex; 3982 3983 err = mOMX->getParameter( 3984 mNode, OMX_IndexParamAudioAmr, ¶ms, sizeof(params)); 3985 if (err != OK) { 3986 return err; 3987 } 3988 3989 notify->setInt32("channel-count", 1); 3990 if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) { 3991 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB); 3992 notify->setInt32("sample-rate", 16000); 3993 } else { 3994 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB); 3995 notify->setInt32("sample-rate", 8000); 3996 } 3997 break; 3998 } 3999 4000 case OMX_AUDIO_CodingFLAC: 4001 { 4002 OMX_AUDIO_PARAM_FLACTYPE params; 4003 InitOMXParams(¶ms); 4004 params.nPortIndex = portIndex; 4005 4006 err = mOMX->getParameter( 4007 mNode, OMX_IndexParamAudioFlac, ¶ms, sizeof(params)); 4008 if (err != OK) { 4009 return err; 4010 } 4011 4012 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC); 4013 notify->setInt32("channel-count", params.nChannels); 4014 notify->setInt32("sample-rate", params.nSampleRate); 4015 break; 4016 } 4017 4018 case OMX_AUDIO_CodingMP3: 4019 { 4020 OMX_AUDIO_PARAM_MP3TYPE params; 4021 InitOMXParams(¶ms); 4022 params.nPortIndex = portIndex; 4023 4024 err = mOMX->getParameter( 4025 mNode, OMX_IndexParamAudioMp3, ¶ms, sizeof(params)); 4026 if (err != OK) { 4027 return err; 4028 } 4029 4030 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG); 4031 notify->setInt32("channel-count", params.nChannels); 4032 notify->setInt32("sample-rate", params.nSampleRate); 4033 break; 4034 } 4035 4036 case OMX_AUDIO_CodingVORBIS: 4037 { 4038 OMX_AUDIO_PARAM_VORBISTYPE params; 4039 InitOMXParams(¶ms); 4040 params.nPortIndex = portIndex; 4041 4042 err = mOMX->getParameter( 4043 mNode, OMX_IndexParamAudioVorbis, ¶ms, sizeof(params)); 4044 if (err != OK) { 4045 return err; 4046 } 4047 4048 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS); 4049 notify->setInt32("channel-count", params.nChannels); 4050 notify->setInt32("sample-rate", params.nSampleRate); 4051 break; 4052 } 4053 4054 case OMX_AUDIO_CodingAndroidAC3: 4055 { 4056 OMX_AUDIO_PARAM_ANDROID_AC3TYPE params; 4057 InitOMXParams(¶ms); 4058 params.nPortIndex = portIndex; 4059 4060 err = mOMX->getParameter( 4061 mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 4062 ¶ms, sizeof(params)); 4063 if (err != OK) { 4064 return err; 4065 } 4066 4067 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3); 4068 notify->setInt32("channel-count", params.nChannels); 4069 notify->setInt32("sample-rate", params.nSampleRate); 4070 break; 4071 } 4072 4073 case OMX_AUDIO_CodingAndroidEAC3: 4074 { 4075 OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params; 4076 InitOMXParams(¶ms); 4077 params.nPortIndex = portIndex; 4078 4079 err = mOMX->getParameter( 4080 mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, 4081 ¶ms, sizeof(params)); 4082 if (err != OK) { 4083 return err; 4084 } 4085 4086 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3); 4087 notify->setInt32("channel-count", params.nChannels); 4088 notify->setInt32("sample-rate", params.nSampleRate); 4089 break; 4090 } 4091 4092 case OMX_AUDIO_CodingAndroidOPUS: 4093 { 4094 OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params; 4095 InitOMXParams(¶ms); 4096 params.nPortIndex = portIndex; 4097 4098 err = mOMX->getParameter( 4099 mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, 4100 ¶ms, sizeof(params)); 4101 if (err != OK) { 4102 return err; 4103 } 4104 4105 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS); 4106 notify->setInt32("channel-count", params.nChannels); 4107 notify->setInt32("sample-rate", params.nSampleRate); 4108 break; 4109 } 4110 4111 case OMX_AUDIO_CodingG711: 4112 { 4113 OMX_AUDIO_PARAM_PCMMODETYPE params; 4114 InitOMXParams(¶ms); 4115 params.nPortIndex = portIndex; 4116 4117 err = mOMX->getParameter( 4118 mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4119 if (err != OK) { 4120 return err; 4121 } 4122 4123 const char *mime = NULL; 4124 if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) { 4125 mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW; 4126 } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) { 4127 mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW; 4128 } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear 4129 mime = MEDIA_MIMETYPE_AUDIO_RAW; 4130 } 4131 notify->setString("mime", mime); 4132 notify->setInt32("channel-count", params.nChannels); 4133 notify->setInt32("sample-rate", params.nSamplingRate); 4134 break; 4135 } 4136 4137 case OMX_AUDIO_CodingGSMFR: 4138 { 4139 OMX_AUDIO_PARAM_PCMMODETYPE params; 4140 InitOMXParams(¶ms); 4141 params.nPortIndex = portIndex; 4142 4143 err = mOMX->getParameter( 4144 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4145 if (err != OK) { 4146 return err; 4147 } 4148 4149 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM); 4150 notify->setInt32("channel-count", params.nChannels); 4151 notify->setInt32("sample-rate", params.nSamplingRate); 4152 break; 4153 } 4154 4155 default: 4156 ALOGE("Unsupported audio coding: %s(%d)\n", 4157 asString(audioDef->eEncoding), audioDef->eEncoding); 4158 return BAD_TYPE; 4159 } 4160 break; 4161 } 4162 4163 default: 4164 ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain); 4165 return BAD_TYPE; 4166 } 4167 4168 return OK; 4169} 4170 4171void ACodec::sendFormatChange(const sp<AMessage> &reply) { 4172 sp<AMessage> notify = mBaseOutputFormat->dup(); 4173 notify->setInt32("what", kWhatOutputFormatChanged); 4174 4175 if (getPortFormat(kPortIndexOutput, notify) != OK) { 4176 ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str()); 4177 return; 4178 } 4179 4180 AString mime; 4181 CHECK(notify->findString("mime", &mime)); 4182 4183 int32_t left, top, right, bottom; 4184 if (mime == MEDIA_MIMETYPE_VIDEO_RAW && 4185 mNativeWindow != NULL && 4186 notify->findRect("crop", &left, &top, &right, &bottom)) { 4187 // notify renderer of the crop change 4188 // NOTE: native window uses extended right-bottom coordinate 4189 reply->setRect("crop", left, top, right + 1, bottom + 1); 4190 } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW && 4191 (mEncoderDelay || mEncoderPadding)) { 4192 int32_t channelCount; 4193 CHECK(notify->findInt32("channel-count", &channelCount)); 4194 size_t frameSize = channelCount * sizeof(int16_t); 4195 if (mSkipCutBuffer != NULL) { 4196 size_t prevbufsize = mSkipCutBuffer->size(); 4197 if (prevbufsize != 0) { 4198 ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize); 4199 } 4200 } 4201 mSkipCutBuffer = new SkipCutBuffer( 4202 mEncoderDelay * frameSize, 4203 mEncoderPadding * frameSize); 4204 } 4205 4206 notify->post(); 4207 4208 mSentFormat = true; 4209} 4210 4211void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) { 4212 sp<AMessage> notify = mNotify->dup(); 4213 notify->setInt32("what", CodecBase::kWhatError); 4214 ALOGE("signalError(omxError %#x, internalError %d)", error, internalError); 4215 4216 if (internalError == UNKNOWN_ERROR) { // find better error code 4217 const status_t omxStatus = statusFromOMXError(error); 4218 if (omxStatus != 0) { 4219 internalError = omxStatus; 4220 } else { 4221 ALOGW("Invalid OMX error %#x", error); 4222 } 4223 } 4224 notify->setInt32("err", internalError); 4225 notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error. 4226 notify->post(); 4227} 4228 4229//////////////////////////////////////////////////////////////////////////////// 4230 4231ACodec::PortDescription::PortDescription() { 4232} 4233 4234status_t ACodec::requestIDRFrame() { 4235 if (!mIsEncoder) { 4236 return ERROR_UNSUPPORTED; 4237 } 4238 4239 OMX_CONFIG_INTRAREFRESHVOPTYPE params; 4240 InitOMXParams(¶ms); 4241 4242 params.nPortIndex = kPortIndexOutput; 4243 params.IntraRefreshVOP = OMX_TRUE; 4244 4245 return mOMX->setConfig( 4246 mNode, 4247 OMX_IndexConfigVideoIntraVOPRefresh, 4248 ¶ms, 4249 sizeof(params)); 4250} 4251 4252void ACodec::PortDescription::addBuffer( 4253 IOMX::buffer_id id, const sp<ABuffer> &buffer) { 4254 mBufferIDs.push_back(id); 4255 mBuffers.push_back(buffer); 4256} 4257 4258size_t ACodec::PortDescription::countBuffers() { 4259 return mBufferIDs.size(); 4260} 4261 4262IOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const { 4263 return mBufferIDs.itemAt(index); 4264} 4265 4266sp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const { 4267 return mBuffers.itemAt(index); 4268} 4269 4270//////////////////////////////////////////////////////////////////////////////// 4271 4272ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState) 4273 : AState(parentState), 4274 mCodec(codec) { 4275} 4276 4277ACodec::BaseState::PortMode ACodec::BaseState::getPortMode( 4278 OMX_U32 /* portIndex */) { 4279 return KEEP_BUFFERS; 4280} 4281 4282bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { 4283 switch (msg->what()) { 4284 case kWhatInputBufferFilled: 4285 { 4286 onInputBufferFilled(msg); 4287 break; 4288 } 4289 4290 case kWhatOutputBufferDrained: 4291 { 4292 onOutputBufferDrained(msg); 4293 break; 4294 } 4295 4296 case ACodec::kWhatOMXMessage: 4297 { 4298 return onOMXMessage(msg); 4299 } 4300 4301 case ACodec::kWhatSetSurface: 4302 { 4303 sp<AReplyToken> replyID; 4304 CHECK(msg->senderAwaitsResponse(&replyID)); 4305 4306 sp<RefBase> obj; 4307 CHECK(msg->findObject("surface", &obj)); 4308 4309 status_t err = 4310 ADebug::isExperimentEnabled("legacy-setsurface") ? BAD_VALUE : 4311 mCodec->handleSetSurface(static_cast<Surface *>(obj.get())); 4312 4313 sp<AMessage> response = new AMessage; 4314 response->setInt32("err", err); 4315 response->postReply(replyID); 4316 break; 4317 } 4318 4319 case ACodec::kWhatCreateInputSurface: 4320 case ACodec::kWhatSetInputSurface: 4321 case ACodec::kWhatSignalEndOfInputStream: 4322 { 4323 // This may result in an app illegal state exception. 4324 ALOGE("Message 0x%x was not handled", msg->what()); 4325 mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION); 4326 return true; 4327 } 4328 4329 case ACodec::kWhatOMXDied: 4330 { 4331 // This will result in kFlagSawMediaServerDie handling in MediaCodec. 4332 ALOGE("OMX/mediaserver died, signalling error!"); 4333 mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT); 4334 break; 4335 } 4336 4337 case ACodec::kWhatReleaseCodecInstance: 4338 { 4339 ALOGI("[%s] forcing the release of codec", 4340 mCodec->mComponentName.c_str()); 4341 status_t err = mCodec->mOMX->freeNode(mCodec->mNode); 4342 ALOGE_IF("[%s] failed to release codec instance: err=%d", 4343 mCodec->mComponentName.c_str(), err); 4344 sp<AMessage> notify = mCodec->mNotify->dup(); 4345 notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 4346 notify->post(); 4347 break; 4348 } 4349 4350 default: 4351 return false; 4352 } 4353 4354 return true; 4355} 4356 4357bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { 4358 int32_t type; 4359 CHECK(msg->findInt32("type", &type)); 4360 4361 // there is a possibility that this is an outstanding message for a 4362 // codec that we have already destroyed 4363 if (mCodec->mNode == 0) { 4364 ALOGI("ignoring message as already freed component: %s", 4365 msg->debugString().c_str()); 4366 return true; 4367 } 4368 4369 IOMX::node_id nodeID; 4370 CHECK(msg->findInt32("node", (int32_t*)&nodeID)); 4371 if (nodeID != mCodec->mNode) { 4372 ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode); 4373 return false; 4374 } 4375 4376 switch (type) { 4377 case omx_message::EVENT: 4378 { 4379 int32_t event, data1, data2; 4380 CHECK(msg->findInt32("event", &event)); 4381 CHECK(msg->findInt32("data1", &data1)); 4382 CHECK(msg->findInt32("data2", &data2)); 4383 4384 if (event == OMX_EventCmdComplete 4385 && data1 == OMX_CommandFlush 4386 && data2 == (int32_t)OMX_ALL) { 4387 // Use of this notification is not consistent across 4388 // implementations. We'll drop this notification and rely 4389 // on flush-complete notifications on the individual port 4390 // indices instead. 4391 4392 return true; 4393 } 4394 4395 return onOMXEvent( 4396 static_cast<OMX_EVENTTYPE>(event), 4397 static_cast<OMX_U32>(data1), 4398 static_cast<OMX_U32>(data2)); 4399 } 4400 4401 case omx_message::EMPTY_BUFFER_DONE: 4402 { 4403 IOMX::buffer_id bufferID; 4404 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 4405 4406 return onOMXEmptyBufferDone(bufferID); 4407 } 4408 4409 case omx_message::FILL_BUFFER_DONE: 4410 { 4411 IOMX::buffer_id bufferID; 4412 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 4413 4414 int32_t rangeOffset, rangeLength, flags; 4415 int64_t timeUs; 4416 4417 CHECK(msg->findInt32("range_offset", &rangeOffset)); 4418 CHECK(msg->findInt32("range_length", &rangeLength)); 4419 CHECK(msg->findInt32("flags", &flags)); 4420 CHECK(msg->findInt64("timestamp", &timeUs)); 4421 4422 return onOMXFillBufferDone( 4423 bufferID, 4424 (size_t)rangeOffset, (size_t)rangeLength, 4425 (OMX_U32)flags, 4426 timeUs); 4427 } 4428 4429 default: 4430 ALOGE("Unexpected message type: %d", type); 4431 return false; 4432 } 4433} 4434 4435bool ACodec::BaseState::onOMXEvent( 4436 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4437 if (event != OMX_EventError) { 4438 ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)", 4439 mCodec->mComponentName.c_str(), event, data1, data2); 4440 4441 return false; 4442 } 4443 4444 ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1); 4445 4446 // verify OMX component sends back an error we expect. 4447 OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1; 4448 if (!isOMXError(omxError)) { 4449 ALOGW("Invalid OMX error %#x", omxError); 4450 omxError = OMX_ErrorUndefined; 4451 } 4452 mCodec->signalError(omxError); 4453 4454 return true; 4455} 4456 4457bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) { 4458 ALOGV("[%s] onOMXEmptyBufferDone %u", 4459 mCodec->mComponentName.c_str(), bufferID); 4460 4461 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 4462 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 4463 if (status != BufferInfo::OWNED_BY_COMPONENT) { 4464 ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 4465 mCodec->dumpBuffers(kPortIndexInput); 4466 return false; 4467 } 4468 info->mStatus = BufferInfo::OWNED_BY_US; 4469 4470 // We're in "store-metadata-in-buffers" mode, the underlying 4471 // OMX component had access to data that's implicitly refcounted 4472 // by this "MediaBuffer" object. Now that the OMX component has 4473 // told us that it's done with the input buffer, we can decrement 4474 // the mediaBuffer's reference count. 4475 info->mData->setMediaBufferBase(NULL); 4476 4477 PortMode mode = getPortMode(kPortIndexInput); 4478 4479 switch (mode) { 4480 case KEEP_BUFFERS: 4481 break; 4482 4483 case RESUBMIT_BUFFERS: 4484 postFillThisBuffer(info); 4485 break; 4486 4487 case FREE_BUFFERS: 4488 default: 4489 ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers"); 4490 return false; 4491 } 4492 4493 return true; 4494} 4495 4496void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) { 4497 if (mCodec->mPortEOS[kPortIndexInput]) { 4498 return; 4499 } 4500 4501 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 4502 4503 sp<AMessage> notify = mCodec->mNotify->dup(); 4504 notify->setInt32("what", CodecBase::kWhatFillThisBuffer); 4505 notify->setInt32("buffer-id", info->mBufferID); 4506 4507 info->mData->meta()->clear(); 4508 notify->setBuffer("buffer", info->mData); 4509 4510 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec); 4511 reply->setInt32("buffer-id", info->mBufferID); 4512 4513 notify->setMessage("reply", reply); 4514 4515 notify->post(); 4516 4517 info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 4518} 4519 4520void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { 4521 IOMX::buffer_id bufferID; 4522 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 4523 sp<ABuffer> buffer; 4524 int32_t err = OK; 4525 bool eos = false; 4526 PortMode mode = getPortMode(kPortIndexInput); 4527 4528 if (!msg->findBuffer("buffer", &buffer)) { 4529 /* these are unfilled buffers returned by client */ 4530 CHECK(msg->findInt32("err", &err)); 4531 4532 if (err == OK) { 4533 /* buffers with no errors are returned on MediaCodec.flush */ 4534 mode = KEEP_BUFFERS; 4535 } else { 4536 ALOGV("[%s] saw error %d instead of an input buffer", 4537 mCodec->mComponentName.c_str(), err); 4538 eos = true; 4539 } 4540 4541 buffer.clear(); 4542 } 4543 4544 int32_t tmp; 4545 if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) { 4546 eos = true; 4547 err = ERROR_END_OF_STREAM; 4548 } 4549 4550 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 4551 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 4552 if (status != BufferInfo::OWNED_BY_UPSTREAM) { 4553 ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID); 4554 mCodec->dumpBuffers(kPortIndexInput); 4555 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 4556 return; 4557 } 4558 4559 info->mStatus = BufferInfo::OWNED_BY_US; 4560 4561 switch (mode) { 4562 case KEEP_BUFFERS: 4563 { 4564 if (eos) { 4565 if (!mCodec->mPortEOS[kPortIndexInput]) { 4566 mCodec->mPortEOS[kPortIndexInput] = true; 4567 mCodec->mInputEOSResult = err; 4568 } 4569 } 4570 break; 4571 } 4572 4573 case RESUBMIT_BUFFERS: 4574 { 4575 if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) { 4576 int64_t timeUs; 4577 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 4578 4579 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 4580 4581 int32_t isCSD; 4582 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) { 4583 flags |= OMX_BUFFERFLAG_CODECCONFIG; 4584 } 4585 4586 if (eos) { 4587 flags |= OMX_BUFFERFLAG_EOS; 4588 } 4589 4590 if (buffer != info->mData) { 4591 ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)", 4592 mCodec->mComponentName.c_str(), 4593 bufferID, 4594 buffer.get(), info->mData.get()); 4595 4596 if (buffer->size() > info->mData->capacity()) { 4597 ALOGE("data size (%zu) is greated than buffer capacity (%zu)", 4598 buffer->size(), // this is the data received 4599 info->mData->capacity()); // this is out buffer size 4600 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 4601 return; 4602 } 4603 memcpy(info->mData->data(), buffer->data(), buffer->size()); 4604 } 4605 4606 if (flags & OMX_BUFFERFLAG_CODECCONFIG) { 4607 ALOGV("[%s] calling emptyBuffer %u w/ codec specific data", 4608 mCodec->mComponentName.c_str(), bufferID); 4609 } else if (flags & OMX_BUFFERFLAG_EOS) { 4610 ALOGV("[%s] calling emptyBuffer %u w/ EOS", 4611 mCodec->mComponentName.c_str(), bufferID); 4612 } else { 4613#if TRACK_BUFFER_TIMING 4614 ALOGI("[%s] calling emptyBuffer %u w/ time %lld us", 4615 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 4616#else 4617 ALOGV("[%s] calling emptyBuffer %u w/ time %lld us", 4618 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 4619#endif 4620 } 4621 4622#if TRACK_BUFFER_TIMING 4623 ACodec::BufferStats stats; 4624 stats.mEmptyBufferTimeUs = ALooper::GetNowUs(); 4625 stats.mFillBufferDoneTimeUs = -1ll; 4626 mCodec->mBufferStats.add(timeUs, stats); 4627#endif 4628 4629 if (mCodec->mStoreMetaDataInOutputBuffers) { 4630 // try to submit an output buffer for each input buffer 4631 PortMode outputMode = getPortMode(kPortIndexOutput); 4632 4633 ALOGV("MetaDataBuffersToSubmit=%u portMode=%s", 4634 mCodec->mMetaDataBuffersToSubmit, 4635 (outputMode == FREE_BUFFERS ? "FREE" : 4636 outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT")); 4637 if (outputMode == RESUBMIT_BUFFERS) { 4638 mCodec->submitOutputMetaDataBuffer(); 4639 } 4640 } 4641 status_t err2 = mCodec->mOMX->emptyBuffer( 4642 mCodec->mNode, 4643 bufferID, 4644 0, 4645 buffer->size(), 4646 flags, 4647 timeUs); 4648 if (err2 != OK) { 4649 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 4650 return; 4651 } 4652 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 4653 4654 if (!eos && err == OK) { 4655 getMoreInputDataIfPossible(); 4656 } else { 4657 ALOGV("[%s] Signalled EOS (%d) on the input port", 4658 mCodec->mComponentName.c_str(), err); 4659 4660 mCodec->mPortEOS[kPortIndexInput] = true; 4661 mCodec->mInputEOSResult = err; 4662 } 4663 } else if (!mCodec->mPortEOS[kPortIndexInput]) { 4664 if (err != OK && err != ERROR_END_OF_STREAM) { 4665 ALOGV("[%s] Signalling EOS on the input port due to error %d", 4666 mCodec->mComponentName.c_str(), err); 4667 } else { 4668 ALOGV("[%s] Signalling EOS on the input port", 4669 mCodec->mComponentName.c_str()); 4670 } 4671 4672 ALOGV("[%s] calling emptyBuffer %u signalling EOS", 4673 mCodec->mComponentName.c_str(), bufferID); 4674 4675 status_t err2 = mCodec->mOMX->emptyBuffer( 4676 mCodec->mNode, 4677 bufferID, 4678 0, 4679 0, 4680 OMX_BUFFERFLAG_EOS, 4681 0); 4682 if (err2 != OK) { 4683 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 4684 return; 4685 } 4686 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 4687 4688 mCodec->mPortEOS[kPortIndexInput] = true; 4689 mCodec->mInputEOSResult = err; 4690 } 4691 break; 4692 } 4693 4694 case FREE_BUFFERS: 4695 break; 4696 4697 default: 4698 ALOGE("invalid port mode: %d", mode); 4699 break; 4700 } 4701} 4702 4703void ACodec::BaseState::getMoreInputDataIfPossible() { 4704 if (mCodec->mPortEOS[kPortIndexInput]) { 4705 return; 4706 } 4707 4708 BufferInfo *eligible = NULL; 4709 4710 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 4711 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 4712 4713#if 0 4714 if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 4715 // There's already a "read" pending. 4716 return; 4717 } 4718#endif 4719 4720 if (info->mStatus == BufferInfo::OWNED_BY_US) { 4721 eligible = info; 4722 } 4723 } 4724 4725 if (eligible == NULL) { 4726 return; 4727 } 4728 4729 postFillThisBuffer(eligible); 4730} 4731 4732bool ACodec::BaseState::onOMXFillBufferDone( 4733 IOMX::buffer_id bufferID, 4734 size_t rangeOffset, size_t rangeLength, 4735 OMX_U32 flags, 4736 int64_t timeUs) { 4737 ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x", 4738 mCodec->mComponentName.c_str(), bufferID, timeUs, flags); 4739 4740 ssize_t index; 4741 status_t err= OK; 4742 4743#if TRACK_BUFFER_TIMING 4744 index = mCodec->mBufferStats.indexOfKey(timeUs); 4745 if (index >= 0) { 4746 ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index); 4747 stats->mFillBufferDoneTimeUs = ALooper::GetNowUs(); 4748 4749 ALOGI("frame PTS %lld: %lld", 4750 timeUs, 4751 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs); 4752 4753 mCodec->mBufferStats.removeItemsAt(index); 4754 stats = NULL; 4755 } 4756#endif 4757 4758 BufferInfo *info = 4759 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 4760 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 4761 if (status != BufferInfo::OWNED_BY_COMPONENT) { 4762 ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 4763 mCodec->dumpBuffers(kPortIndexOutput); 4764 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 4765 return true; 4766 } 4767 4768 info->mDequeuedAt = ++mCodec->mDequeueCounter; 4769 info->mStatus = BufferInfo::OWNED_BY_US; 4770 4771 PortMode mode = getPortMode(kPortIndexOutput); 4772 4773 switch (mode) { 4774 case KEEP_BUFFERS: 4775 break; 4776 4777 case RESUBMIT_BUFFERS: 4778 { 4779 if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS) 4780 || mCodec->mPortEOS[kPortIndexOutput])) { 4781 ALOGV("[%s] calling fillBuffer %u", 4782 mCodec->mComponentName.c_str(), info->mBufferID); 4783 4784 err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID); 4785 if (err != OK) { 4786 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 4787 return true; 4788 } 4789 4790 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 4791 break; 4792 } 4793 4794 sp<AMessage> reply = 4795 new AMessage(kWhatOutputBufferDrained, mCodec); 4796 4797 if (!mCodec->mSentFormat && rangeLength > 0) { 4798 mCodec->sendFormatChange(reply); 4799 } 4800 4801 if (mCodec->mUseMetadataOnEncoderOutput) { 4802 native_handle_t* handle = 4803 *(native_handle_t**)(info->mData->data() + 4); 4804 info->mData->meta()->setPointer("handle", handle); 4805 info->mData->meta()->setInt32("rangeOffset", rangeOffset); 4806 info->mData->meta()->setInt32("rangeLength", rangeLength); 4807 } else { 4808 info->mData->setRange(rangeOffset, rangeLength); 4809 } 4810#if 0 4811 if (mCodec->mNativeWindow == NULL) { 4812 if (IsIDR(info->mData)) { 4813 ALOGI("IDR frame"); 4814 } 4815 } 4816#endif 4817 4818 if (mCodec->mSkipCutBuffer != NULL) { 4819 mCodec->mSkipCutBuffer->submit(info->mData); 4820 } 4821 info->mData->meta()->setInt64("timeUs", timeUs); 4822 4823 sp<AMessage> notify = mCodec->mNotify->dup(); 4824 notify->setInt32("what", CodecBase::kWhatDrainThisBuffer); 4825 notify->setInt32("buffer-id", info->mBufferID); 4826 notify->setBuffer("buffer", info->mData); 4827 notify->setInt32("flags", flags); 4828 4829 reply->setInt32("buffer-id", info->mBufferID); 4830 4831 notify->setMessage("reply", reply); 4832 4833 notify->post(); 4834 4835 info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 4836 4837 if (flags & OMX_BUFFERFLAG_EOS) { 4838 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str()); 4839 4840 sp<AMessage> notify = mCodec->mNotify->dup(); 4841 notify->setInt32("what", CodecBase::kWhatEOS); 4842 notify->setInt32("err", mCodec->mInputEOSResult); 4843 notify->post(); 4844 4845 mCodec->mPortEOS[kPortIndexOutput] = true; 4846 } 4847 break; 4848 } 4849 4850 case FREE_BUFFERS: 4851 err = mCodec->freeBuffer(kPortIndexOutput, index); 4852 if (err != OK) { 4853 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 4854 return true; 4855 } 4856 break; 4857 4858 default: 4859 ALOGE("Invalid port mode: %d", mode); 4860 return false; 4861 } 4862 4863 return true; 4864} 4865 4866void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 4867 IOMX::buffer_id bufferID; 4868 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 4869 ssize_t index; 4870 BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 4871 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 4872 if (status != BufferInfo::OWNED_BY_DOWNSTREAM) { 4873 ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 4874 mCodec->dumpBuffers(kPortIndexOutput); 4875 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 4876 return; 4877 } 4878 4879 android_native_rect_t crop; 4880 if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) { 4881 status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop); 4882 ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err); 4883 } 4884 4885 int32_t render; 4886 if (mCodec->mNativeWindow != NULL 4887 && msg->findInt32("render", &render) && render != 0 4888 && info->mData != NULL && info->mData->size() != 0) { 4889 ATRACE_NAME("render"); 4890 // The client wants this buffer to be rendered. 4891 4892 int64_t timestampNs = 0; 4893 if (!msg->findInt64("timestampNs", ×tampNs)) { 4894 // TODO: it seems like we should use the timestamp 4895 // in the (media)buffer as it potentially came from 4896 // an input surface, but we did not propagate it prior to 4897 // API 20. Perhaps check for target SDK version. 4898#if 0 4899 if (info->mData->meta()->findInt64("timeUs", ×tampNs)) { 4900 ALOGV("using buffer PTS of %" PRId64, timestampNs); 4901 timestampNs *= 1000; 4902 } 4903#endif 4904 } 4905 4906 status_t err; 4907 err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs); 4908 ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err); 4909 4910 err = mCodec->mNativeWindow->queueBuffer( 4911 mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), -1); 4912 if (err == OK) { 4913 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 4914 } else { 4915 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 4916 info->mStatus = BufferInfo::OWNED_BY_US; 4917 } 4918 } else { 4919 if (mCodec->mNativeWindow != NULL && 4920 (info->mData == NULL || info->mData->size() != 0)) { 4921 ATRACE_NAME("frame-drop"); 4922 } 4923 info->mStatus = BufferInfo::OWNED_BY_US; 4924 } 4925 4926 PortMode mode = getPortMode(kPortIndexOutput); 4927 4928 switch (mode) { 4929 case KEEP_BUFFERS: 4930 { 4931 // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 4932 4933 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 4934 // We cannot resubmit the buffer we just rendered, dequeue 4935 // the spare instead. 4936 4937 info = mCodec->dequeueBufferFromNativeWindow(); 4938 } 4939 break; 4940 } 4941 4942 case RESUBMIT_BUFFERS: 4943 { 4944 if (!mCodec->mPortEOS[kPortIndexOutput]) { 4945 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 4946 // We cannot resubmit the buffer we just rendered, dequeue 4947 // the spare instead. 4948 4949 info = mCodec->dequeueBufferFromNativeWindow(); 4950 } 4951 4952 if (info != NULL) { 4953 ALOGV("[%s] calling fillBuffer %u", 4954 mCodec->mComponentName.c_str(), info->mBufferID); 4955 status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID); 4956 if (err == OK) { 4957 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 4958 } else { 4959 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 4960 } 4961 } 4962 } 4963 break; 4964 } 4965 4966 case FREE_BUFFERS: 4967 { 4968 status_t err = mCodec->freeBuffer(kPortIndexOutput, index); 4969 if (err != OK) { 4970 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 4971 } 4972 break; 4973 } 4974 4975 default: 4976 ALOGE("Invalid port mode: %d", mode); 4977 return; 4978 } 4979} 4980 4981//////////////////////////////////////////////////////////////////////////////// 4982 4983ACodec::UninitializedState::UninitializedState(ACodec *codec) 4984 : BaseState(codec) { 4985} 4986 4987void ACodec::UninitializedState::stateEntered() { 4988 ALOGV("Now uninitialized"); 4989 4990 if (mDeathNotifier != NULL) { 4991 IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier); 4992 mDeathNotifier.clear(); 4993 } 4994 4995 mCodec->mNativeWindow.clear(); 4996 mCodec->mNode = 0; 4997 mCodec->mOMX.clear(); 4998 mCodec->mQuirks = 0; 4999 mCodec->mFlags = 0; 5000 mCodec->mUseMetadataOnEncoderOutput = 0; 5001 mCodec->mComponentName.clear(); 5002} 5003 5004bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 5005 bool handled = false; 5006 5007 switch (msg->what()) { 5008 case ACodec::kWhatSetup: 5009 { 5010 onSetup(msg); 5011 5012 handled = true; 5013 break; 5014 } 5015 5016 case ACodec::kWhatAllocateComponent: 5017 { 5018 onAllocateComponent(msg); 5019 handled = true; 5020 break; 5021 } 5022 5023 case ACodec::kWhatShutdown: 5024 { 5025 int32_t keepComponentAllocated; 5026 CHECK(msg->findInt32( 5027 "keepComponentAllocated", &keepComponentAllocated)); 5028 ALOGW_IF(keepComponentAllocated, 5029 "cannot keep component allocated on shutdown in Uninitialized state"); 5030 5031 sp<AMessage> notify = mCodec->mNotify->dup(); 5032 notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 5033 notify->post(); 5034 5035 handled = true; 5036 break; 5037 } 5038 5039 case ACodec::kWhatFlush: 5040 { 5041 sp<AMessage> notify = mCodec->mNotify->dup(); 5042 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5043 notify->post(); 5044 5045 handled = true; 5046 break; 5047 } 5048 5049 case ACodec::kWhatReleaseCodecInstance: 5050 { 5051 // nothing to do, as we have already signaled shutdown 5052 handled = true; 5053 break; 5054 } 5055 5056 default: 5057 return BaseState::onMessageReceived(msg); 5058 } 5059 5060 return handled; 5061} 5062 5063void ACodec::UninitializedState::onSetup( 5064 const sp<AMessage> &msg) { 5065 if (onAllocateComponent(msg) 5066 && mCodec->mLoadedState->onConfigureComponent(msg)) { 5067 mCodec->mLoadedState->onStart(); 5068 } 5069} 5070 5071bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { 5072 ALOGV("onAllocateComponent"); 5073 5074 CHECK(mCodec->mNode == 0); 5075 5076 OMXClient client; 5077 if (client.connect() != OK) { 5078 mCodec->signalError(OMX_ErrorUndefined, NO_INIT); 5079 return false; 5080 } 5081 5082 sp<IOMX> omx = client.interface(); 5083 5084 sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec); 5085 5086 mDeathNotifier = new DeathNotifier(notify); 5087 if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) { 5088 // This was a local binder, if it dies so do we, we won't care 5089 // about any notifications in the afterlife. 5090 mDeathNotifier.clear(); 5091 } 5092 5093 Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs; 5094 5095 AString mime; 5096 5097 AString componentName; 5098 uint32_t quirks = 0; 5099 int32_t encoder = false; 5100 if (msg->findString("componentName", &componentName)) { 5101 ssize_t index = matchingCodecs.add(); 5102 OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index); 5103 entry->mName = String8(componentName.c_str()); 5104 5105 if (!OMXCodec::findCodecQuirks( 5106 componentName.c_str(), &entry->mQuirks)) { 5107 entry->mQuirks = 0; 5108 } 5109 } else { 5110 CHECK(msg->findString("mime", &mime)); 5111 5112 if (!msg->findInt32("encoder", &encoder)) { 5113 encoder = false; 5114 } 5115 5116 OMXCodec::findMatchingCodecs( 5117 mime.c_str(), 5118 encoder, // createEncoder 5119 NULL, // matchComponentName 5120 0, // flags 5121 &matchingCodecs); 5122 } 5123 5124 sp<CodecObserver> observer = new CodecObserver; 5125 IOMX::node_id node = 0; 5126 5127 status_t err = NAME_NOT_FOUND; 5128 for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); 5129 ++matchIndex) { 5130 componentName = matchingCodecs.itemAt(matchIndex).mName.string(); 5131 quirks = matchingCodecs.itemAt(matchIndex).mQuirks; 5132 5133 pid_t tid = gettid(); 5134 int prevPriority = androidGetThreadPriority(tid); 5135 androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); 5136 err = omx->allocateNode(componentName.c_str(), observer, &node); 5137 androidSetThreadPriority(tid, prevPriority); 5138 5139 if (err == OK) { 5140 break; 5141 } else { 5142 ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str()); 5143 } 5144 5145 node = 0; 5146 } 5147 5148 if (node == 0) { 5149 if (!mime.empty()) { 5150 ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.", 5151 encoder ? "en" : "de", mime.c_str(), err); 5152 } else { 5153 ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err); 5154 } 5155 5156 mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err)); 5157 return false; 5158 } 5159 5160 notify = new AMessage(kWhatOMXMessage, mCodec); 5161 observer->setNotificationMessage(notify); 5162 5163 mCodec->mComponentName = componentName; 5164 mCodec->mFlags = 0; 5165 5166 if (componentName.endsWith(".secure")) { 5167 mCodec->mFlags |= kFlagIsSecure; 5168 mCodec->mFlags |= kFlagIsGrallocUsageProtected; 5169 mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 5170 } 5171 5172 mCodec->mQuirks = quirks; 5173 mCodec->mOMX = omx; 5174 mCodec->mNode = node; 5175 5176 { 5177 sp<AMessage> notify = mCodec->mNotify->dup(); 5178 notify->setInt32("what", CodecBase::kWhatComponentAllocated); 5179 notify->setString("componentName", mCodec->mComponentName.c_str()); 5180 notify->post(); 5181 } 5182 5183 mCodec->changeState(mCodec->mLoadedState); 5184 5185 return true; 5186} 5187 5188//////////////////////////////////////////////////////////////////////////////// 5189 5190ACodec::LoadedState::LoadedState(ACodec *codec) 5191 : BaseState(codec) { 5192} 5193 5194void ACodec::LoadedState::stateEntered() { 5195 ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 5196 5197 mCodec->mPortEOS[kPortIndexInput] = 5198 mCodec->mPortEOS[kPortIndexOutput] = false; 5199 5200 mCodec->mInputEOSResult = OK; 5201 5202 mCodec->mDequeueCounter = 0; 5203 mCodec->mMetaDataBuffersToSubmit = 0; 5204 mCodec->mRepeatFrameDelayUs = -1ll; 5205 mCodec->mInputFormat.clear(); 5206 mCodec->mOutputFormat.clear(); 5207 mCodec->mBaseOutputFormat.clear(); 5208 5209 if (mCodec->mShutdownInProgress) { 5210 bool keepComponentAllocated = mCodec->mKeepComponentAllocated; 5211 5212 mCodec->mShutdownInProgress = false; 5213 mCodec->mKeepComponentAllocated = false; 5214 5215 onShutdown(keepComponentAllocated); 5216 } 5217 mCodec->mExplicitShutdown = false; 5218 5219 mCodec->processDeferredMessages(); 5220} 5221 5222void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) { 5223 if (!keepComponentAllocated) { 5224 (void)mCodec->mOMX->freeNode(mCodec->mNode); 5225 5226 mCodec->changeState(mCodec->mUninitializedState); 5227 } 5228 5229 if (mCodec->mExplicitShutdown) { 5230 sp<AMessage> notify = mCodec->mNotify->dup(); 5231 notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 5232 notify->post(); 5233 mCodec->mExplicitShutdown = false; 5234 } 5235} 5236 5237bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) { 5238 bool handled = false; 5239 5240 switch (msg->what()) { 5241 case ACodec::kWhatConfigureComponent: 5242 { 5243 onConfigureComponent(msg); 5244 handled = true; 5245 break; 5246 } 5247 5248 case ACodec::kWhatCreateInputSurface: 5249 { 5250 onCreateInputSurface(msg); 5251 handled = true; 5252 break; 5253 } 5254 5255 case ACodec::kWhatSetInputSurface: 5256 { 5257 onSetInputSurface(msg); 5258 handled = true; 5259 break; 5260 } 5261 5262 case ACodec::kWhatStart: 5263 { 5264 onStart(); 5265 handled = true; 5266 break; 5267 } 5268 5269 case ACodec::kWhatShutdown: 5270 { 5271 int32_t keepComponentAllocated; 5272 CHECK(msg->findInt32( 5273 "keepComponentAllocated", &keepComponentAllocated)); 5274 5275 mCodec->mExplicitShutdown = true; 5276 onShutdown(keepComponentAllocated); 5277 5278 handled = true; 5279 break; 5280 } 5281 5282 case ACodec::kWhatFlush: 5283 { 5284 sp<AMessage> notify = mCodec->mNotify->dup(); 5285 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5286 notify->post(); 5287 5288 handled = true; 5289 break; 5290 } 5291 5292 default: 5293 return BaseState::onMessageReceived(msg); 5294 } 5295 5296 return handled; 5297} 5298 5299bool ACodec::LoadedState::onConfigureComponent( 5300 const sp<AMessage> &msg) { 5301 ALOGV("onConfigureComponent"); 5302 5303 CHECK(mCodec->mNode != 0); 5304 5305 status_t err = OK; 5306 AString mime; 5307 if (!msg->findString("mime", &mime)) { 5308 err = BAD_VALUE; 5309 } else { 5310 err = mCodec->configureCodec(mime.c_str(), msg); 5311 } 5312 if (err != OK) { 5313 ALOGE("[%s] configureCodec returning error %d", 5314 mCodec->mComponentName.c_str(), err); 5315 5316 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5317 return false; 5318 } 5319 5320 { 5321 sp<AMessage> notify = mCodec->mNotify->dup(); 5322 notify->setInt32("what", CodecBase::kWhatComponentConfigured); 5323 notify->setMessage("input-format", mCodec->mInputFormat); 5324 notify->setMessage("output-format", mCodec->mOutputFormat); 5325 notify->post(); 5326 } 5327 5328 return true; 5329} 5330 5331status_t ACodec::LoadedState::setupInputSurface() { 5332 status_t err = OK; 5333 5334 if (mCodec->mRepeatFrameDelayUs > 0ll) { 5335 err = mCodec->mOMX->setInternalOption( 5336 mCodec->mNode, 5337 kPortIndexInput, 5338 IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY, 5339 &mCodec->mRepeatFrameDelayUs, 5340 sizeof(mCodec->mRepeatFrameDelayUs)); 5341 5342 if (err != OK) { 5343 ALOGE("[%s] Unable to configure option to repeat previous " 5344 "frames (err %d)", 5345 mCodec->mComponentName.c_str(), 5346 err); 5347 return err; 5348 } 5349 } 5350 5351 if (mCodec->mMaxPtsGapUs > 0ll) { 5352 err = mCodec->mOMX->setInternalOption( 5353 mCodec->mNode, 5354 kPortIndexInput, 5355 IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP, 5356 &mCodec->mMaxPtsGapUs, 5357 sizeof(mCodec->mMaxPtsGapUs)); 5358 5359 if (err != OK) { 5360 ALOGE("[%s] Unable to configure max timestamp gap (err %d)", 5361 mCodec->mComponentName.c_str(), 5362 err); 5363 return err; 5364 } 5365 } 5366 5367 if (mCodec->mMaxFps > 0) { 5368 err = mCodec->mOMX->setInternalOption( 5369 mCodec->mNode, 5370 kPortIndexInput, 5371 IOMX::INTERNAL_OPTION_MAX_FPS, 5372 &mCodec->mMaxFps, 5373 sizeof(mCodec->mMaxFps)); 5374 5375 if (err != OK) { 5376 ALOGE("[%s] Unable to configure max fps (err %d)", 5377 mCodec->mComponentName.c_str(), 5378 err); 5379 return err; 5380 } 5381 } 5382 5383 if (mCodec->mTimePerCaptureUs > 0ll 5384 && mCodec->mTimePerFrameUs > 0ll) { 5385 int64_t timeLapse[2]; 5386 timeLapse[0] = mCodec->mTimePerFrameUs; 5387 timeLapse[1] = mCodec->mTimePerCaptureUs; 5388 err = mCodec->mOMX->setInternalOption( 5389 mCodec->mNode, 5390 kPortIndexInput, 5391 IOMX::INTERNAL_OPTION_TIME_LAPSE, 5392 &timeLapse[0], 5393 sizeof(timeLapse)); 5394 5395 if (err != OK) { 5396 ALOGE("[%s] Unable to configure time lapse (err %d)", 5397 mCodec->mComponentName.c_str(), 5398 err); 5399 return err; 5400 } 5401 } 5402 5403 if (mCodec->mCreateInputBuffersSuspended) { 5404 bool suspend = true; 5405 err = mCodec->mOMX->setInternalOption( 5406 mCodec->mNode, 5407 kPortIndexInput, 5408 IOMX::INTERNAL_OPTION_SUSPEND, 5409 &suspend, 5410 sizeof(suspend)); 5411 5412 if (err != OK) { 5413 ALOGE("[%s] Unable to configure option to suspend (err %d)", 5414 mCodec->mComponentName.c_str(), 5415 err); 5416 return err; 5417 } 5418 } 5419 5420 return OK; 5421} 5422 5423void ACodec::LoadedState::onCreateInputSurface( 5424 const sp<AMessage> & /* msg */) { 5425 ALOGV("onCreateInputSurface"); 5426 5427 sp<AMessage> notify = mCodec->mNotify->dup(); 5428 notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated); 5429 5430 sp<IGraphicBufferProducer> bufferProducer; 5431 status_t err = mCodec->mOMX->createInputSurface( 5432 mCodec->mNode, kPortIndexInput, &bufferProducer); 5433 5434 if (err == OK) { 5435 err = setupInputSurface(); 5436 } 5437 5438 if (err == OK) { 5439 notify->setObject("input-surface", 5440 new BufferProducerWrapper(bufferProducer)); 5441 } else { 5442 // Can't use mCodec->signalError() here -- MediaCodec won't forward 5443 // the error through because it's in the "configured" state. We 5444 // send a kWhatInputSurfaceCreated with an error value instead. 5445 ALOGE("[%s] onCreateInputSurface returning error %d", 5446 mCodec->mComponentName.c_str(), err); 5447 notify->setInt32("err", err); 5448 } 5449 notify->post(); 5450} 5451 5452void ACodec::LoadedState::onSetInputSurface( 5453 const sp<AMessage> &msg) { 5454 ALOGV("onSetInputSurface"); 5455 5456 sp<AMessage> notify = mCodec->mNotify->dup(); 5457 notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted); 5458 5459 sp<RefBase> obj; 5460 CHECK(msg->findObject("input-surface", &obj)); 5461 sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get()); 5462 5463 status_t err = mCodec->mOMX->setInputSurface( 5464 mCodec->mNode, kPortIndexInput, surface->getBufferConsumer()); 5465 5466 if (err == OK) { 5467 err = setupInputSurface(); 5468 } 5469 5470 if (err != OK) { 5471 // Can't use mCodec->signalError() here -- MediaCodec won't forward 5472 // the error through because it's in the "configured" state. We 5473 // send a kWhatInputSurfaceAccepted with an error value instead. 5474 ALOGE("[%s] onSetInputSurface returning error %d", 5475 mCodec->mComponentName.c_str(), err); 5476 notify->setInt32("err", err); 5477 } 5478 notify->post(); 5479} 5480 5481void ACodec::LoadedState::onStart() { 5482 ALOGV("onStart"); 5483 5484 status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle); 5485 if (err != OK) { 5486 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5487 } else { 5488 mCodec->changeState(mCodec->mLoadedToIdleState); 5489 } 5490} 5491 5492//////////////////////////////////////////////////////////////////////////////// 5493 5494ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 5495 : BaseState(codec) { 5496} 5497 5498void ACodec::LoadedToIdleState::stateEntered() { 5499 ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 5500 5501 status_t err; 5502 if ((err = allocateBuffers()) != OK) { 5503 ALOGE("Failed to allocate buffers after transitioning to IDLE state " 5504 "(error 0x%08x)", 5505 err); 5506 5507 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5508 5509 mCodec->changeState(mCodec->mLoadedState); 5510 } 5511} 5512 5513status_t ACodec::LoadedToIdleState::allocateBuffers() { 5514 status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 5515 5516 if (err != OK) { 5517 return err; 5518 } 5519 5520 return mCodec->allocateBuffersOnPort(kPortIndexOutput); 5521} 5522 5523bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 5524 switch (msg->what()) { 5525 case kWhatSetParameters: 5526 case kWhatShutdown: 5527 { 5528 mCodec->deferMessage(msg); 5529 return true; 5530 } 5531 5532 case kWhatSignalEndOfInputStream: 5533 { 5534 mCodec->onSignalEndOfInputStream(); 5535 return true; 5536 } 5537 5538 case kWhatResume: 5539 { 5540 // We'll be active soon enough. 5541 return true; 5542 } 5543 5544 case kWhatFlush: 5545 { 5546 // We haven't even started yet, so we're flushed alright... 5547 sp<AMessage> notify = mCodec->mNotify->dup(); 5548 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5549 notify->post(); 5550 return true; 5551 } 5552 5553 default: 5554 return BaseState::onMessageReceived(msg); 5555 } 5556} 5557 5558bool ACodec::LoadedToIdleState::onOMXEvent( 5559 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5560 switch (event) { 5561 case OMX_EventCmdComplete: 5562 { 5563 status_t err = OK; 5564 if (data1 != (OMX_U32)OMX_CommandStateSet 5565 || data2 != (OMX_U32)OMX_StateIdle) { 5566 ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)", 5567 asString((OMX_COMMANDTYPE)data1), data1, 5568 asString((OMX_STATETYPE)data2), data2); 5569 err = FAILED_TRANSACTION; 5570 } 5571 5572 if (err == OK) { 5573 err = mCodec->mOMX->sendCommand( 5574 mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting); 5575 } 5576 5577 if (err != OK) { 5578 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5579 } else { 5580 mCodec->changeState(mCodec->mIdleToExecutingState); 5581 } 5582 5583 return true; 5584 } 5585 5586 default: 5587 return BaseState::onOMXEvent(event, data1, data2); 5588 } 5589} 5590 5591//////////////////////////////////////////////////////////////////////////////// 5592 5593ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 5594 : BaseState(codec) { 5595} 5596 5597void ACodec::IdleToExecutingState::stateEntered() { 5598 ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 5599} 5600 5601bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 5602 switch (msg->what()) { 5603 case kWhatSetParameters: 5604 case kWhatShutdown: 5605 { 5606 mCodec->deferMessage(msg); 5607 return true; 5608 } 5609 5610 case kWhatResume: 5611 { 5612 // We'll be active soon enough. 5613 return true; 5614 } 5615 5616 case kWhatFlush: 5617 { 5618 // We haven't even started yet, so we're flushed alright... 5619 sp<AMessage> notify = mCodec->mNotify->dup(); 5620 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5621 notify->post(); 5622 5623 return true; 5624 } 5625 5626 case kWhatSignalEndOfInputStream: 5627 { 5628 mCodec->onSignalEndOfInputStream(); 5629 return true; 5630 } 5631 5632 default: 5633 return BaseState::onMessageReceived(msg); 5634 } 5635} 5636 5637bool ACodec::IdleToExecutingState::onOMXEvent( 5638 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5639 switch (event) { 5640 case OMX_EventCmdComplete: 5641 { 5642 if (data1 != (OMX_U32)OMX_CommandStateSet 5643 || data2 != (OMX_U32)OMX_StateExecuting) { 5644 ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)", 5645 asString((OMX_COMMANDTYPE)data1), data1, 5646 asString((OMX_STATETYPE)data2), data2); 5647 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5648 return true; 5649 } 5650 5651 mCodec->mExecutingState->resume(); 5652 mCodec->changeState(mCodec->mExecutingState); 5653 5654 return true; 5655 } 5656 5657 default: 5658 return BaseState::onOMXEvent(event, data1, data2); 5659 } 5660} 5661 5662//////////////////////////////////////////////////////////////////////////////// 5663 5664ACodec::ExecutingState::ExecutingState(ACodec *codec) 5665 : BaseState(codec), 5666 mActive(false) { 5667} 5668 5669ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 5670 OMX_U32 /* portIndex */) { 5671 return RESUBMIT_BUFFERS; 5672} 5673 5674void ACodec::ExecutingState::submitOutputMetaBuffers() { 5675 // submit as many buffers as there are input buffers with the codec 5676 // in case we are in port reconfiguring 5677 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 5678 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 5679 5680 if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) { 5681 if (mCodec->submitOutputMetaDataBuffer() != OK) 5682 break; 5683 } 5684 } 5685 5686 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 5687 mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround(); 5688} 5689 5690void ACodec::ExecutingState::submitRegularOutputBuffers() { 5691 bool failed = false; 5692 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 5693 BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 5694 5695 if (mCodec->mNativeWindow != NULL) { 5696 if (info->mStatus != BufferInfo::OWNED_BY_US 5697 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 5698 ALOGE("buffers should be owned by us or the surface"); 5699 failed = true; 5700 break; 5701 } 5702 5703 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 5704 continue; 5705 } 5706 } else { 5707 if (info->mStatus != BufferInfo::OWNED_BY_US) { 5708 ALOGE("buffers should be owned by us"); 5709 failed = true; 5710 break; 5711 } 5712 } 5713 5714 ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID); 5715 5716 status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID); 5717 if (err != OK) { 5718 failed = true; 5719 break; 5720 } 5721 5722 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5723 } 5724 5725 if (failed) { 5726 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5727 } 5728} 5729 5730void ACodec::ExecutingState::submitOutputBuffers() { 5731 submitRegularOutputBuffers(); 5732 if (mCodec->mStoreMetaDataInOutputBuffers) { 5733 submitOutputMetaBuffers(); 5734 } 5735} 5736 5737void ACodec::ExecutingState::resume() { 5738 if (mActive) { 5739 ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str()); 5740 return; 5741 } 5742 5743 submitOutputBuffers(); 5744 5745 // Post all available input buffers 5746 if (mCodec->mBuffers[kPortIndexInput].size() == 0u) { 5747 ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str()); 5748 } 5749 5750 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) { 5751 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 5752 if (info->mStatus == BufferInfo::OWNED_BY_US) { 5753 postFillThisBuffer(info); 5754 } 5755 } 5756 5757 mActive = true; 5758} 5759 5760void ACodec::ExecutingState::stateEntered() { 5761 ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 5762 5763 mCodec->processDeferredMessages(); 5764} 5765 5766bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 5767 bool handled = false; 5768 5769 switch (msg->what()) { 5770 case kWhatShutdown: 5771 { 5772 int32_t keepComponentAllocated; 5773 CHECK(msg->findInt32( 5774 "keepComponentAllocated", &keepComponentAllocated)); 5775 5776 mCodec->mShutdownInProgress = true; 5777 mCodec->mExplicitShutdown = true; 5778 mCodec->mKeepComponentAllocated = keepComponentAllocated; 5779 5780 mActive = false; 5781 5782 status_t err = mCodec->mOMX->sendCommand( 5783 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle); 5784 if (err != OK) { 5785 if (keepComponentAllocated) { 5786 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5787 } 5788 // TODO: do some recovery here. 5789 } else { 5790 mCodec->changeState(mCodec->mExecutingToIdleState); 5791 } 5792 5793 handled = true; 5794 break; 5795 } 5796 5797 case kWhatFlush: 5798 { 5799 ALOGV("[%s] ExecutingState flushing now " 5800 "(codec owns %zu/%zu input, %zu/%zu output).", 5801 mCodec->mComponentName.c_str(), 5802 mCodec->countBuffersOwnedByComponent(kPortIndexInput), 5803 mCodec->mBuffers[kPortIndexInput].size(), 5804 mCodec->countBuffersOwnedByComponent(kPortIndexOutput), 5805 mCodec->mBuffers[kPortIndexOutput].size()); 5806 5807 mActive = false; 5808 5809 status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL); 5810 if (err != OK) { 5811 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5812 } else { 5813 mCodec->changeState(mCodec->mFlushingState); 5814 } 5815 5816 handled = true; 5817 break; 5818 } 5819 5820 case kWhatResume: 5821 { 5822 resume(); 5823 5824 handled = true; 5825 break; 5826 } 5827 5828 case kWhatRequestIDRFrame: 5829 { 5830 status_t err = mCodec->requestIDRFrame(); 5831 if (err != OK) { 5832 ALOGW("Requesting an IDR frame failed."); 5833 } 5834 5835 handled = true; 5836 break; 5837 } 5838 5839 case kWhatSetParameters: 5840 { 5841 sp<AMessage> params; 5842 CHECK(msg->findMessage("params", ¶ms)); 5843 5844 status_t err = mCodec->setParameters(params); 5845 5846 sp<AMessage> reply; 5847 if (msg->findMessage("reply", &reply)) { 5848 reply->setInt32("err", err); 5849 reply->post(); 5850 } 5851 5852 handled = true; 5853 break; 5854 } 5855 5856 case ACodec::kWhatSignalEndOfInputStream: 5857 { 5858 mCodec->onSignalEndOfInputStream(); 5859 handled = true; 5860 break; 5861 } 5862 5863 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 5864 case kWhatSubmitOutputMetaDataBufferIfEOS: 5865 { 5866 if (mCodec->mPortEOS[kPortIndexInput] && 5867 !mCodec->mPortEOS[kPortIndexOutput]) { 5868 status_t err = mCodec->submitOutputMetaDataBuffer(); 5869 if (err == OK) { 5870 mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround(); 5871 } 5872 } 5873 return true; 5874 } 5875 5876 default: 5877 handled = BaseState::onMessageReceived(msg); 5878 break; 5879 } 5880 5881 return handled; 5882} 5883 5884status_t ACodec::setParameters(const sp<AMessage> ¶ms) { 5885 int32_t videoBitrate; 5886 if (params->findInt32("video-bitrate", &videoBitrate)) { 5887 OMX_VIDEO_CONFIG_BITRATETYPE configParams; 5888 InitOMXParams(&configParams); 5889 configParams.nPortIndex = kPortIndexOutput; 5890 configParams.nEncodeBitrate = videoBitrate; 5891 5892 status_t err = mOMX->setConfig( 5893 mNode, 5894 OMX_IndexConfigVideoBitrate, 5895 &configParams, 5896 sizeof(configParams)); 5897 5898 if (err != OK) { 5899 ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d", 5900 videoBitrate, err); 5901 5902 return err; 5903 } 5904 } 5905 5906 int64_t skipFramesBeforeUs; 5907 if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) { 5908 status_t err = 5909 mOMX->setInternalOption( 5910 mNode, 5911 kPortIndexInput, 5912 IOMX::INTERNAL_OPTION_START_TIME, 5913 &skipFramesBeforeUs, 5914 sizeof(skipFramesBeforeUs)); 5915 5916 if (err != OK) { 5917 ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err); 5918 return err; 5919 } 5920 } 5921 5922 int32_t dropInputFrames; 5923 if (params->findInt32("drop-input-frames", &dropInputFrames)) { 5924 bool suspend = dropInputFrames != 0; 5925 5926 status_t err = 5927 mOMX->setInternalOption( 5928 mNode, 5929 kPortIndexInput, 5930 IOMX::INTERNAL_OPTION_SUSPEND, 5931 &suspend, 5932 sizeof(suspend)); 5933 5934 if (err != OK) { 5935 ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err); 5936 return err; 5937 } 5938 } 5939 5940 int32_t dummy; 5941 if (params->findInt32("request-sync", &dummy)) { 5942 status_t err = requestIDRFrame(); 5943 5944 if (err != OK) { 5945 ALOGE("Requesting a sync frame failed w/ err %d", err); 5946 return err; 5947 } 5948 } 5949 5950 float rate; 5951 if (params->findFloat("operating-rate", &rate) && rate > 0) { 5952 status_t err = setOperatingRate(rate, mIsVideo); 5953 if (err != OK) { 5954 ALOGE("Failed to set parameter 'operating-rate' (err %d)", err); 5955 return err; 5956 } 5957 } 5958 5959 return OK; 5960} 5961 5962void ACodec::onSignalEndOfInputStream() { 5963 sp<AMessage> notify = mNotify->dup(); 5964 notify->setInt32("what", CodecBase::kWhatSignaledInputEOS); 5965 5966 status_t err = mOMX->signalEndOfInputStream(mNode); 5967 if (err != OK) { 5968 notify->setInt32("err", err); 5969 } 5970 notify->post(); 5971} 5972 5973bool ACodec::ExecutingState::onOMXEvent( 5974 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5975 switch (event) { 5976 case OMX_EventPortSettingsChanged: 5977 { 5978 CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 5979 5980 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 5981 mCodec->mMetaDataBuffersToSubmit = 0; 5982 CHECK_EQ(mCodec->mOMX->sendCommand( 5983 mCodec->mNode, 5984 OMX_CommandPortDisable, kPortIndexOutput), 5985 (status_t)OK); 5986 5987 mCodec->freeOutputBuffersNotOwnedByComponent(); 5988 5989 mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 5990 } else if (data2 == OMX_IndexConfigCommonOutputCrop) { 5991 mCodec->mSentFormat = false; 5992 } else { 5993 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x", 5994 mCodec->mComponentName.c_str(), data2); 5995 } 5996 5997 return true; 5998 } 5999 6000 case OMX_EventBufferFlag: 6001 { 6002 return true; 6003 } 6004 6005 default: 6006 return BaseState::onOMXEvent(event, data1, data2); 6007 } 6008} 6009 6010//////////////////////////////////////////////////////////////////////////////// 6011 6012ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 6013 ACodec *codec) 6014 : BaseState(codec) { 6015} 6016 6017ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 6018 OMX_U32 portIndex) { 6019 if (portIndex == kPortIndexOutput) { 6020 return FREE_BUFFERS; 6021 } 6022 6023 CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 6024 6025 return RESUBMIT_BUFFERS; 6026} 6027 6028bool ACodec::OutputPortSettingsChangedState::onMessageReceived( 6029 const sp<AMessage> &msg) { 6030 bool handled = false; 6031 6032 switch (msg->what()) { 6033 case kWhatFlush: 6034 case kWhatShutdown: 6035 case kWhatResume: 6036 case kWhatSetParameters: 6037 { 6038 if (msg->what() == kWhatResume) { 6039 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 6040 } 6041 6042 mCodec->deferMessage(msg); 6043 handled = true; 6044 break; 6045 } 6046 6047 default: 6048 handled = BaseState::onMessageReceived(msg); 6049 break; 6050 } 6051 6052 return handled; 6053} 6054 6055void ACodec::OutputPortSettingsChangedState::stateEntered() { 6056 ALOGV("[%s] Now handling output port settings change", 6057 mCodec->mComponentName.c_str()); 6058} 6059 6060bool ACodec::OutputPortSettingsChangedState::onOMXEvent( 6061 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6062 switch (event) { 6063 case OMX_EventCmdComplete: 6064 { 6065 if (data1 == (OMX_U32)OMX_CommandPortDisable) { 6066 if (data2 != (OMX_U32)kPortIndexOutput) { 6067 ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2); 6068 return false; 6069 } 6070 6071 ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str()); 6072 6073 status_t err = OK; 6074 if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) { 6075 ALOGE("disabled port should be empty, but has %zu buffers", 6076 mCodec->mBuffers[kPortIndexOutput].size()); 6077 err = FAILED_TRANSACTION; 6078 } else { 6079 mCodec->mDealer[kPortIndexOutput].clear(); 6080 } 6081 6082 if (err == OK) { 6083 err = mCodec->mOMX->sendCommand( 6084 mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput); 6085 } 6086 6087 if (err == OK) { 6088 err = mCodec->allocateBuffersOnPort(kPortIndexOutput); 6089 ALOGE_IF(err != OK, "Failed to allocate output port buffers after port " 6090 "reconfiguration: (%d)", err); 6091 } 6092 6093 if (err != OK) { 6094 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6095 6096 // This is technically not correct, but appears to be 6097 // the only way to free the component instance. 6098 // Controlled transitioning from excecuting->idle 6099 // and idle->loaded seem impossible probably because 6100 // the output port never finishes re-enabling. 6101 mCodec->mShutdownInProgress = true; 6102 mCodec->mKeepComponentAllocated = false; 6103 mCodec->changeState(mCodec->mLoadedState); 6104 } 6105 6106 return true; 6107 } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 6108 if (data2 != (OMX_U32)kPortIndexOutput) { 6109 ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2); 6110 return false; 6111 } 6112 6113 mCodec->mSentFormat = false; 6114 6115 ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str()); 6116 6117 if (mCodec->mExecutingState->active()) { 6118 mCodec->mExecutingState->submitOutputBuffers(); 6119 } 6120 6121 mCodec->changeState(mCodec->mExecutingState); 6122 6123 return true; 6124 } 6125 6126 return false; 6127 } 6128 6129 default: 6130 return false; 6131 } 6132} 6133 6134//////////////////////////////////////////////////////////////////////////////// 6135 6136ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 6137 : BaseState(codec), 6138 mComponentNowIdle(false) { 6139} 6140 6141bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 6142 bool handled = false; 6143 6144 switch (msg->what()) { 6145 case kWhatFlush: 6146 { 6147 // Don't send me a flush request if you previously wanted me 6148 // to shutdown. 6149 ALOGW("Ignoring flush request in ExecutingToIdleState"); 6150 break; 6151 } 6152 6153 case kWhatShutdown: 6154 { 6155 // We're already doing that... 6156 6157 handled = true; 6158 break; 6159 } 6160 6161 default: 6162 handled = BaseState::onMessageReceived(msg); 6163 break; 6164 } 6165 6166 return handled; 6167} 6168 6169void ACodec::ExecutingToIdleState::stateEntered() { 6170 ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 6171 6172 mComponentNowIdle = false; 6173 mCodec->mSentFormat = false; 6174} 6175 6176bool ACodec::ExecutingToIdleState::onOMXEvent( 6177 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6178 switch (event) { 6179 case OMX_EventCmdComplete: 6180 { 6181 if (data1 != (OMX_U32)OMX_CommandStateSet 6182 || data2 != (OMX_U32)OMX_StateIdle) { 6183 ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)", 6184 asString((OMX_COMMANDTYPE)data1), data1, 6185 asString((OMX_STATETYPE)data2), data2); 6186 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6187 return true; 6188 } 6189 6190 mComponentNowIdle = true; 6191 6192 changeStateIfWeOwnAllBuffers(); 6193 6194 return true; 6195 } 6196 6197 case OMX_EventPortSettingsChanged: 6198 case OMX_EventBufferFlag: 6199 { 6200 // We're shutting down and don't care about this anymore. 6201 return true; 6202 } 6203 6204 default: 6205 return BaseState::onOMXEvent(event, data1, data2); 6206 } 6207} 6208 6209void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 6210 if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) { 6211 status_t err = mCodec->mOMX->sendCommand( 6212 mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded); 6213 if (err == OK) { 6214 err = mCodec->freeBuffersOnPort(kPortIndexInput); 6215 status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput); 6216 if (err == OK) { 6217 err = err2; 6218 } 6219 } 6220 6221 if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) 6222 && mCodec->mNativeWindow != NULL) { 6223 // We push enough 1x1 blank buffers to ensure that one of 6224 // them has made it to the display. This allows the OMX 6225 // component teardown to zero out any protected buffers 6226 // without the risk of scanning out one of those buffers. 6227 pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get()); 6228 } 6229 6230 if (err != OK) { 6231 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6232 return; 6233 } 6234 6235 mCodec->changeState(mCodec->mIdleToLoadedState); 6236 } 6237} 6238 6239void ACodec::ExecutingToIdleState::onInputBufferFilled( 6240 const sp<AMessage> &msg) { 6241 BaseState::onInputBufferFilled(msg); 6242 6243 changeStateIfWeOwnAllBuffers(); 6244} 6245 6246void ACodec::ExecutingToIdleState::onOutputBufferDrained( 6247 const sp<AMessage> &msg) { 6248 BaseState::onOutputBufferDrained(msg); 6249 6250 changeStateIfWeOwnAllBuffers(); 6251} 6252 6253//////////////////////////////////////////////////////////////////////////////// 6254 6255ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 6256 : BaseState(codec) { 6257} 6258 6259bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 6260 bool handled = false; 6261 6262 switch (msg->what()) { 6263 case kWhatShutdown: 6264 { 6265 // We're already doing that... 6266 6267 handled = true; 6268 break; 6269 } 6270 6271 case kWhatFlush: 6272 { 6273 // Don't send me a flush request if you previously wanted me 6274 // to shutdown. 6275 ALOGE("Got flush request in IdleToLoadedState"); 6276 break; 6277 } 6278 6279 default: 6280 handled = BaseState::onMessageReceived(msg); 6281 break; 6282 } 6283 6284 return handled; 6285} 6286 6287void ACodec::IdleToLoadedState::stateEntered() { 6288 ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 6289} 6290 6291bool ACodec::IdleToLoadedState::onOMXEvent( 6292 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6293 switch (event) { 6294 case OMX_EventCmdComplete: 6295 { 6296 if (data1 != (OMX_U32)OMX_CommandStateSet 6297 || data2 != (OMX_U32)OMX_StateLoaded) { 6298 ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)", 6299 asString((OMX_COMMANDTYPE)data1), data1, 6300 asString((OMX_STATETYPE)data2), data2); 6301 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6302 return true; 6303 } 6304 6305 mCodec->changeState(mCodec->mLoadedState); 6306 6307 return true; 6308 } 6309 6310 default: 6311 return BaseState::onOMXEvent(event, data1, data2); 6312 } 6313} 6314 6315//////////////////////////////////////////////////////////////////////////////// 6316 6317ACodec::FlushingState::FlushingState(ACodec *codec) 6318 : BaseState(codec) { 6319} 6320 6321void ACodec::FlushingState::stateEntered() { 6322 ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 6323 6324 mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 6325} 6326 6327bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 6328 bool handled = false; 6329 6330 switch (msg->what()) { 6331 case kWhatShutdown: 6332 { 6333 mCodec->deferMessage(msg); 6334 break; 6335 } 6336 6337 case kWhatFlush: 6338 { 6339 // We're already doing this right now. 6340 handled = true; 6341 break; 6342 } 6343 6344 default: 6345 handled = BaseState::onMessageReceived(msg); 6346 break; 6347 } 6348 6349 return handled; 6350} 6351 6352bool ACodec::FlushingState::onOMXEvent( 6353 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6354 ALOGV("[%s] FlushingState onOMXEvent(%u,%d)", 6355 mCodec->mComponentName.c_str(), event, (OMX_S32)data1); 6356 6357 switch (event) { 6358 case OMX_EventCmdComplete: 6359 { 6360 if (data1 != (OMX_U32)OMX_CommandFlush) { 6361 ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState", 6362 asString((OMX_COMMANDTYPE)data1), data1, data2); 6363 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6364 return true; 6365 } 6366 6367 if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 6368 if (mFlushComplete[data2]) { 6369 ALOGW("Flush already completed for %s port", 6370 data2 == kPortIndexInput ? "input" : "output"); 6371 return true; 6372 } 6373 mFlushComplete[data2] = true; 6374 6375 if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) { 6376 changeStateIfWeOwnAllBuffers(); 6377 } 6378 } else if (data2 == OMX_ALL) { 6379 if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) { 6380 ALOGW("received flush complete event for OMX_ALL before ports have been" 6381 "flushed (%d/%d)", 6382 mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]); 6383 return false; 6384 } 6385 6386 changeStateIfWeOwnAllBuffers(); 6387 } else { 6388 ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2); 6389 } 6390 6391 return true; 6392 } 6393 6394 case OMX_EventPortSettingsChanged: 6395 { 6396 sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec); 6397 msg->setInt32("type", omx_message::EVENT); 6398 msg->setInt32("node", mCodec->mNode); 6399 msg->setInt32("event", event); 6400 msg->setInt32("data1", data1); 6401 msg->setInt32("data2", data2); 6402 6403 ALOGV("[%s] Deferring OMX_EventPortSettingsChanged", 6404 mCodec->mComponentName.c_str()); 6405 6406 mCodec->deferMessage(msg); 6407 6408 return true; 6409 } 6410 6411 default: 6412 return BaseState::onOMXEvent(event, data1, data2); 6413 } 6414 6415 return true; 6416} 6417 6418void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 6419 BaseState::onOutputBufferDrained(msg); 6420 6421 changeStateIfWeOwnAllBuffers(); 6422} 6423 6424void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 6425 BaseState::onInputBufferFilled(msg); 6426 6427 changeStateIfWeOwnAllBuffers(); 6428} 6429 6430void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 6431 if (mFlushComplete[kPortIndexInput] 6432 && mFlushComplete[kPortIndexOutput] 6433 && mCodec->allYourBuffersAreBelongToUs()) { 6434 // We now own all buffers except possibly those still queued with 6435 // the native window for rendering. Let's get those back as well. 6436 mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs(); 6437 6438 sp<AMessage> notify = mCodec->mNotify->dup(); 6439 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 6440 notify->post(); 6441 6442 mCodec->mPortEOS[kPortIndexInput] = 6443 mCodec->mPortEOS[kPortIndexOutput] = false; 6444 6445 mCodec->mInputEOSResult = OK; 6446 6447 if (mCodec->mSkipCutBuffer != NULL) { 6448 mCodec->mSkipCutBuffer->clear(); 6449 } 6450 6451 mCodec->changeState(mCodec->mExecutingState); 6452 } 6453} 6454 6455} // namespace android 6456