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