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