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