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