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