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