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