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