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