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