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