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