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