ACodec.cpp revision f43f2cf4ae771069a86ffeaf732b53eb90191219
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 3534 // TODO: Need OMX structure definition for setting iFrameInterval 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 size_t frameSize = channelCount * sizeof(int16_t); 4449 if (mSkipCutBuffer != NULL) { 4450 size_t prevbufsize = mSkipCutBuffer->size(); 4451 if (prevbufsize != 0) { 4452 ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize); 4453 } 4454 } 4455 mSkipCutBuffer = new SkipCutBuffer( 4456 mEncoderDelay * frameSize, 4457 mEncoderPadding * frameSize); 4458 } 4459 4460 notify->post(); 4461 4462 mSentFormat = true; 4463} 4464 4465void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) { 4466 sp<AMessage> notify = mNotify->dup(); 4467 notify->setInt32("what", CodecBase::kWhatError); 4468 ALOGE("signalError(omxError %#x, internalError %d)", error, internalError); 4469 4470 if (internalError == UNKNOWN_ERROR) { // find better error code 4471 const status_t omxStatus = statusFromOMXError(error); 4472 if (omxStatus != 0) { 4473 internalError = omxStatus; 4474 } else { 4475 ALOGW("Invalid OMX error %#x", error); 4476 } 4477 } 4478 4479 mFatalError = true; 4480 4481 notify->setInt32("err", internalError); 4482 notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error. 4483 notify->post(); 4484} 4485 4486//////////////////////////////////////////////////////////////////////////////// 4487 4488ACodec::PortDescription::PortDescription() { 4489} 4490 4491status_t ACodec::requestIDRFrame() { 4492 if (!mIsEncoder) { 4493 return ERROR_UNSUPPORTED; 4494 } 4495 4496 OMX_CONFIG_INTRAREFRESHVOPTYPE params; 4497 InitOMXParams(¶ms); 4498 4499 params.nPortIndex = kPortIndexOutput; 4500 params.IntraRefreshVOP = OMX_TRUE; 4501 4502 return mOMX->setConfig( 4503 mNode, 4504 OMX_IndexConfigVideoIntraVOPRefresh, 4505 ¶ms, 4506 sizeof(params)); 4507} 4508 4509void ACodec::PortDescription::addBuffer( 4510 IOMX::buffer_id id, const sp<ABuffer> &buffer) { 4511 mBufferIDs.push_back(id); 4512 mBuffers.push_back(buffer); 4513} 4514 4515size_t ACodec::PortDescription::countBuffers() { 4516 return mBufferIDs.size(); 4517} 4518 4519IOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const { 4520 return mBufferIDs.itemAt(index); 4521} 4522 4523sp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const { 4524 return mBuffers.itemAt(index); 4525} 4526 4527//////////////////////////////////////////////////////////////////////////////// 4528 4529ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState) 4530 : AState(parentState), 4531 mCodec(codec) { 4532} 4533 4534ACodec::BaseState::PortMode ACodec::BaseState::getPortMode( 4535 OMX_U32 /* portIndex */) { 4536 return KEEP_BUFFERS; 4537} 4538 4539bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { 4540 switch (msg->what()) { 4541 case kWhatInputBufferFilled: 4542 { 4543 onInputBufferFilled(msg); 4544 break; 4545 } 4546 4547 case kWhatOutputBufferDrained: 4548 { 4549 onOutputBufferDrained(msg); 4550 break; 4551 } 4552 4553 case ACodec::kWhatOMXMessageList: 4554 { 4555 return checkOMXMessage(msg) ? onOMXMessageList(msg) : true; 4556 } 4557 4558 case ACodec::kWhatOMXMessageItem: 4559 { 4560 // no need to check as we already did it for kWhatOMXMessageList 4561 return onOMXMessage(msg); 4562 } 4563 4564 case ACodec::kWhatOMXMessage: 4565 { 4566 return checkOMXMessage(msg) ? onOMXMessage(msg) : true; 4567 } 4568 4569 case ACodec::kWhatSetSurface: 4570 { 4571 sp<AReplyToken> replyID; 4572 CHECK(msg->senderAwaitsResponse(&replyID)); 4573 4574 sp<RefBase> obj; 4575 CHECK(msg->findObject("surface", &obj)); 4576 4577 status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get())); 4578 4579 sp<AMessage> response = new AMessage; 4580 response->setInt32("err", err); 4581 response->postReply(replyID); 4582 break; 4583 } 4584 4585 case ACodec::kWhatCreateInputSurface: 4586 case ACodec::kWhatSetInputSurface: 4587 case ACodec::kWhatSignalEndOfInputStream: 4588 { 4589 // This may result in an app illegal state exception. 4590 ALOGE("Message 0x%x was not handled", msg->what()); 4591 mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION); 4592 return true; 4593 } 4594 4595 case ACodec::kWhatOMXDied: 4596 { 4597 // This will result in kFlagSawMediaServerDie handling in MediaCodec. 4598 ALOGE("OMX/mediaserver died, signalling error!"); 4599 mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT); 4600 break; 4601 } 4602 4603 case ACodec::kWhatReleaseCodecInstance: 4604 { 4605 ALOGI("[%s] forcing the release of codec", 4606 mCodec->mComponentName.c_str()); 4607 status_t err = mCodec->mOMX->freeNode(mCodec->mNode); 4608 ALOGE_IF("[%s] failed to release codec instance: err=%d", 4609 mCodec->mComponentName.c_str(), err); 4610 sp<AMessage> notify = mCodec->mNotify->dup(); 4611 notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 4612 notify->post(); 4613 break; 4614 } 4615 4616 default: 4617 return false; 4618 } 4619 4620 return true; 4621} 4622 4623bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) { 4624 // there is a possibility that this is an outstanding message for a 4625 // codec that we have already destroyed 4626 if (mCodec->mNode == 0) { 4627 ALOGI("ignoring message as already freed component: %s", 4628 msg->debugString().c_str()); 4629 return false; 4630 } 4631 4632 IOMX::node_id nodeID; 4633 CHECK(msg->findInt32("node", (int32_t*)&nodeID)); 4634 if (nodeID != mCodec->mNode) { 4635 ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode); 4636 return false; 4637 } 4638 return true; 4639} 4640 4641bool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) { 4642 sp<RefBase> obj; 4643 CHECK(msg->findObject("messages", &obj)); 4644 sp<MessageList> msgList = static_cast<MessageList *>(obj.get()); 4645 4646 bool receivedRenderedEvents = false; 4647 for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin(); 4648 it != msgList->getList().cend(); ++it) { 4649 (*it)->setWhat(ACodec::kWhatOMXMessageItem); 4650 mCodec->handleMessage(*it); 4651 int32_t type; 4652 CHECK((*it)->findInt32("type", &type)); 4653 if (type == omx_message::FRAME_RENDERED) { 4654 receivedRenderedEvents = true; 4655 } 4656 } 4657 4658 if (receivedRenderedEvents) { 4659 // NOTE: all buffers are rendered in this case 4660 mCodec->notifyOfRenderedFrames(); 4661 } 4662 return true; 4663} 4664 4665bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { 4666 int32_t type; 4667 CHECK(msg->findInt32("type", &type)); 4668 4669 switch (type) { 4670 case omx_message::EVENT: 4671 { 4672 int32_t event, data1, data2; 4673 CHECK(msg->findInt32("event", &event)); 4674 CHECK(msg->findInt32("data1", &data1)); 4675 CHECK(msg->findInt32("data2", &data2)); 4676 4677 if (event == OMX_EventCmdComplete 4678 && data1 == OMX_CommandFlush 4679 && data2 == (int32_t)OMX_ALL) { 4680 // Use of this notification is not consistent across 4681 // implementations. We'll drop this notification and rely 4682 // on flush-complete notifications on the individual port 4683 // indices instead. 4684 4685 return true; 4686 } 4687 4688 return onOMXEvent( 4689 static_cast<OMX_EVENTTYPE>(event), 4690 static_cast<OMX_U32>(data1), 4691 static_cast<OMX_U32>(data2)); 4692 } 4693 4694 case omx_message::EMPTY_BUFFER_DONE: 4695 { 4696 IOMX::buffer_id bufferID; 4697 int32_t fenceFd; 4698 4699 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 4700 CHECK(msg->findInt32("fence_fd", &fenceFd)); 4701 4702 return onOMXEmptyBufferDone(bufferID, fenceFd); 4703 } 4704 4705 case omx_message::FILL_BUFFER_DONE: 4706 { 4707 IOMX::buffer_id bufferID; 4708 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 4709 4710 int32_t rangeOffset, rangeLength, flags, fenceFd; 4711 int64_t timeUs; 4712 4713 CHECK(msg->findInt32("range_offset", &rangeOffset)); 4714 CHECK(msg->findInt32("range_length", &rangeLength)); 4715 CHECK(msg->findInt32("flags", &flags)); 4716 CHECK(msg->findInt64("timestamp", &timeUs)); 4717 CHECK(msg->findInt32("fence_fd", &fenceFd)); 4718 4719 return onOMXFillBufferDone( 4720 bufferID, 4721 (size_t)rangeOffset, (size_t)rangeLength, 4722 (OMX_U32)flags, 4723 timeUs, 4724 fenceFd); 4725 } 4726 4727 case omx_message::FRAME_RENDERED: 4728 { 4729 int64_t mediaTimeUs, systemNano; 4730 4731 CHECK(msg->findInt64("media_time_us", &mediaTimeUs)); 4732 CHECK(msg->findInt64("system_nano", &systemNano)); 4733 4734 return onOMXFrameRendered( 4735 mediaTimeUs, systemNano); 4736 } 4737 4738 default: 4739 ALOGE("Unexpected message type: %d", type); 4740 return false; 4741 } 4742} 4743 4744bool ACodec::BaseState::onOMXFrameRendered( 4745 int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) { 4746 // ignore outside of Executing and PortSettingsChanged states 4747 return true; 4748} 4749 4750bool ACodec::BaseState::onOMXEvent( 4751 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4752 if (event != OMX_EventError) { 4753 ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)", 4754 mCodec->mComponentName.c_str(), event, data1, data2); 4755 4756 return false; 4757 } 4758 4759 ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1); 4760 4761 // verify OMX component sends back an error we expect. 4762 OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1; 4763 if (!isOMXError(omxError)) { 4764 ALOGW("Invalid OMX error %#x", omxError); 4765 omxError = OMX_ErrorUndefined; 4766 } 4767 mCodec->signalError(omxError); 4768 4769 return true; 4770} 4771 4772bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) { 4773 ALOGV("[%s] onOMXEmptyBufferDone %u", 4774 mCodec->mComponentName.c_str(), bufferID); 4775 4776 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 4777 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 4778 if (status != BufferInfo::OWNED_BY_COMPONENT) { 4779 ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 4780 mCodec->dumpBuffers(kPortIndexInput); 4781 if (fenceFd >= 0) { 4782 ::close(fenceFd); 4783 } 4784 return false; 4785 } 4786 info->mStatus = BufferInfo::OWNED_BY_US; 4787 4788 // input buffers cannot take fences, so wait for any fence now 4789 (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone"); 4790 fenceFd = -1; 4791 4792 // still save fence for completeness 4793 info->setWriteFence(fenceFd, "onOMXEmptyBufferDone"); 4794 4795 // We're in "store-metadata-in-buffers" mode, the underlying 4796 // OMX component had access to data that's implicitly refcounted 4797 // by this "MediaBuffer" object. Now that the OMX component has 4798 // told us that it's done with the input buffer, we can decrement 4799 // the mediaBuffer's reference count. 4800 info->mData->setMediaBufferBase(NULL); 4801 4802 PortMode mode = getPortMode(kPortIndexInput); 4803 4804 switch (mode) { 4805 case KEEP_BUFFERS: 4806 break; 4807 4808 case RESUBMIT_BUFFERS: 4809 postFillThisBuffer(info); 4810 break; 4811 4812 case FREE_BUFFERS: 4813 default: 4814 ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers"); 4815 return false; 4816 } 4817 4818 return true; 4819} 4820 4821void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) { 4822 if (mCodec->mPortEOS[kPortIndexInput]) { 4823 return; 4824 } 4825 4826 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 4827 4828 sp<AMessage> notify = mCodec->mNotify->dup(); 4829 notify->setInt32("what", CodecBase::kWhatFillThisBuffer); 4830 notify->setInt32("buffer-id", info->mBufferID); 4831 4832 info->mData->meta()->clear(); 4833 notify->setBuffer("buffer", info->mData); 4834 4835 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec); 4836 reply->setInt32("buffer-id", info->mBufferID); 4837 4838 notify->setMessage("reply", reply); 4839 4840 notify->post(); 4841 4842 info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 4843} 4844 4845void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { 4846 IOMX::buffer_id bufferID; 4847 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 4848 sp<ABuffer> buffer; 4849 int32_t err = OK; 4850 bool eos = false; 4851 PortMode mode = getPortMode(kPortIndexInput); 4852 4853 if (!msg->findBuffer("buffer", &buffer)) { 4854 /* these are unfilled buffers returned by client */ 4855 CHECK(msg->findInt32("err", &err)); 4856 4857 if (err == OK) { 4858 /* buffers with no errors are returned on MediaCodec.flush */ 4859 mode = KEEP_BUFFERS; 4860 } else { 4861 ALOGV("[%s] saw error %d instead of an input buffer", 4862 mCodec->mComponentName.c_str(), err); 4863 eos = true; 4864 } 4865 4866 buffer.clear(); 4867 } 4868 4869 int32_t tmp; 4870 if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) { 4871 eos = true; 4872 err = ERROR_END_OF_STREAM; 4873 } 4874 4875 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 4876 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 4877 if (status != BufferInfo::OWNED_BY_UPSTREAM) { 4878 ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID); 4879 mCodec->dumpBuffers(kPortIndexInput); 4880 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 4881 return; 4882 } 4883 4884 info->mStatus = BufferInfo::OWNED_BY_US; 4885 4886 switch (mode) { 4887 case KEEP_BUFFERS: 4888 { 4889 if (eos) { 4890 if (!mCodec->mPortEOS[kPortIndexInput]) { 4891 mCodec->mPortEOS[kPortIndexInput] = true; 4892 mCodec->mInputEOSResult = err; 4893 } 4894 } 4895 break; 4896 } 4897 4898 case RESUBMIT_BUFFERS: 4899 { 4900 if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) { 4901 // Do not send empty input buffer w/o EOS to the component. 4902 if (buffer->size() == 0 && !eos) { 4903 postFillThisBuffer(info); 4904 break; 4905 } 4906 4907 int64_t timeUs; 4908 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 4909 4910 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 4911 4912 int32_t isCSD; 4913 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) { 4914 flags |= OMX_BUFFERFLAG_CODECCONFIG; 4915 } 4916 4917 if (eos) { 4918 flags |= OMX_BUFFERFLAG_EOS; 4919 } 4920 4921 if (buffer != info->mData) { 4922 ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)", 4923 mCodec->mComponentName.c_str(), 4924 bufferID, 4925 buffer.get(), info->mData.get()); 4926 4927 if (buffer->size() > info->mData->capacity()) { 4928 ALOGE("data size (%zu) is greated than buffer capacity (%zu)", 4929 buffer->size(), // this is the data received 4930 info->mData->capacity()); // this is out buffer size 4931 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 4932 return; 4933 } 4934 memcpy(info->mData->data(), buffer->data(), buffer->size()); 4935 } 4936 4937 if (flags & OMX_BUFFERFLAG_CODECCONFIG) { 4938 ALOGV("[%s] calling emptyBuffer %u w/ codec specific data", 4939 mCodec->mComponentName.c_str(), bufferID); 4940 } else if (flags & OMX_BUFFERFLAG_EOS) { 4941 ALOGV("[%s] calling emptyBuffer %u w/ EOS", 4942 mCodec->mComponentName.c_str(), bufferID); 4943 } else { 4944#if TRACK_BUFFER_TIMING 4945 ALOGI("[%s] calling emptyBuffer %u w/ time %lld us", 4946 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 4947#else 4948 ALOGV("[%s] calling emptyBuffer %u w/ time %lld us", 4949 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 4950#endif 4951 } 4952 4953#if TRACK_BUFFER_TIMING 4954 ACodec::BufferStats stats; 4955 stats.mEmptyBufferTimeUs = ALooper::GetNowUs(); 4956 stats.mFillBufferDoneTimeUs = -1ll; 4957 mCodec->mBufferStats.add(timeUs, stats); 4958#endif 4959 4960 if (mCodec->storingMetadataInDecodedBuffers()) { 4961 // try to submit an output buffer for each input buffer 4962 PortMode outputMode = getPortMode(kPortIndexOutput); 4963 4964 ALOGV("MetadataBuffersToSubmit=%u portMode=%s", 4965 mCodec->mMetadataBuffersToSubmit, 4966 (outputMode == FREE_BUFFERS ? "FREE" : 4967 outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT")); 4968 if (outputMode == RESUBMIT_BUFFERS) { 4969 mCodec->submitOutputMetadataBuffer(); 4970 } 4971 } 4972 info->checkReadFence("onInputBufferFilled"); 4973 status_t err2 = mCodec->mOMX->emptyBuffer( 4974 mCodec->mNode, 4975 bufferID, 4976 0, 4977 buffer->size(), 4978 flags, 4979 timeUs, 4980 info->mFenceFd); 4981 info->mFenceFd = -1; 4982 if (err2 != OK) { 4983 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 4984 return; 4985 } 4986 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 4987 4988 if (!eos && err == OK) { 4989 getMoreInputDataIfPossible(); 4990 } else { 4991 ALOGV("[%s] Signalled EOS (%d) on the input port", 4992 mCodec->mComponentName.c_str(), err); 4993 4994 mCodec->mPortEOS[kPortIndexInput] = true; 4995 mCodec->mInputEOSResult = err; 4996 } 4997 } else if (!mCodec->mPortEOS[kPortIndexInput]) { 4998 if (err != OK && err != ERROR_END_OF_STREAM) { 4999 ALOGV("[%s] Signalling EOS on the input port due to error %d", 5000 mCodec->mComponentName.c_str(), err); 5001 } else { 5002 ALOGV("[%s] Signalling EOS on the input port", 5003 mCodec->mComponentName.c_str()); 5004 } 5005 5006 ALOGV("[%s] calling emptyBuffer %u signalling EOS", 5007 mCodec->mComponentName.c_str(), bufferID); 5008 5009 info->checkReadFence("onInputBufferFilled"); 5010 status_t err2 = mCodec->mOMX->emptyBuffer( 5011 mCodec->mNode, 5012 bufferID, 5013 0, 5014 0, 5015 OMX_BUFFERFLAG_EOS, 5016 0, 5017 info->mFenceFd); 5018 info->mFenceFd = -1; 5019 if (err2 != OK) { 5020 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 5021 return; 5022 } 5023 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5024 5025 mCodec->mPortEOS[kPortIndexInput] = true; 5026 mCodec->mInputEOSResult = err; 5027 } 5028 break; 5029 } 5030 5031 case FREE_BUFFERS: 5032 break; 5033 5034 default: 5035 ALOGE("invalid port mode: %d", mode); 5036 break; 5037 } 5038} 5039 5040void ACodec::BaseState::getMoreInputDataIfPossible() { 5041 if (mCodec->mPortEOS[kPortIndexInput]) { 5042 return; 5043 } 5044 5045 BufferInfo *eligible = NULL; 5046 5047 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 5048 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 5049 5050#if 0 5051 if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 5052 // There's already a "read" pending. 5053 return; 5054 } 5055#endif 5056 5057 if (info->mStatus == BufferInfo::OWNED_BY_US) { 5058 eligible = info; 5059 } 5060 } 5061 5062 if (eligible == NULL) { 5063 return; 5064 } 5065 5066 postFillThisBuffer(eligible); 5067} 5068 5069bool ACodec::BaseState::onOMXFillBufferDone( 5070 IOMX::buffer_id bufferID, 5071 size_t rangeOffset, size_t rangeLength, 5072 OMX_U32 flags, 5073 int64_t timeUs, 5074 int fenceFd) { 5075 ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x", 5076 mCodec->mComponentName.c_str(), bufferID, timeUs, flags); 5077 5078 ssize_t index; 5079 status_t err= OK; 5080 5081#if TRACK_BUFFER_TIMING 5082 index = mCodec->mBufferStats.indexOfKey(timeUs); 5083 if (index >= 0) { 5084 ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index); 5085 stats->mFillBufferDoneTimeUs = ALooper::GetNowUs(); 5086 5087 ALOGI("frame PTS %lld: %lld", 5088 timeUs, 5089 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs); 5090 5091 mCodec->mBufferStats.removeItemsAt(index); 5092 stats = NULL; 5093 } 5094#endif 5095 5096 BufferInfo *info = 5097 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 5098 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5099 if (status != BufferInfo::OWNED_BY_COMPONENT) { 5100 ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5101 mCodec->dumpBuffers(kPortIndexOutput); 5102 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5103 if (fenceFd >= 0) { 5104 ::close(fenceFd); 5105 } 5106 return true; 5107 } 5108 5109 info->mDequeuedAt = ++mCodec->mDequeueCounter; 5110 info->mStatus = BufferInfo::OWNED_BY_US; 5111 5112 if (info->mRenderInfo != NULL) { 5113 // The fence for an emptied buffer must have signaled, but there still could be queued 5114 // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these, 5115 // as we will soon requeue this buffer to the surface. While in theory we could still keep 5116 // track of buffers that are requeued to the surface, it is better to add support to the 5117 // buffer-queue to notify us of released buffers and their fences (in the future). 5118 mCodec->notifyOfRenderedFrames(true /* dropIncomplete */); 5119 } 5120 5121 // byte buffers cannot take fences, so wait for any fence now 5122 if (mCodec->mNativeWindow == NULL) { 5123 (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone"); 5124 fenceFd = -1; 5125 } 5126 info->setReadFence(fenceFd, "onOMXFillBufferDone"); 5127 5128 PortMode mode = getPortMode(kPortIndexOutput); 5129 5130 switch (mode) { 5131 case KEEP_BUFFERS: 5132 break; 5133 5134 case RESUBMIT_BUFFERS: 5135 { 5136 if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS) 5137 || mCodec->mPortEOS[kPortIndexOutput])) { 5138 ALOGV("[%s] calling fillBuffer %u", 5139 mCodec->mComponentName.c_str(), info->mBufferID); 5140 5141 err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd); 5142 info->mFenceFd = -1; 5143 if (err != OK) { 5144 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5145 return true; 5146 } 5147 5148 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5149 break; 5150 } 5151 5152 sp<AMessage> reply = 5153 new AMessage(kWhatOutputBufferDrained, mCodec); 5154 5155 if (!mCodec->mSentFormat && rangeLength > 0) { 5156 mCodec->sendFormatChange(reply); 5157 } 5158 if (mCodec->usingMetadataOnEncoderOutput()) { 5159 native_handle_t *handle = NULL; 5160 VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data(); 5161 VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data(); 5162 if (info->mData->size() >= sizeof(grallocMeta) 5163 && grallocMeta.eType == kMetadataBufferTypeGrallocSource) { 5164 handle = (native_handle_t *)(uintptr_t)grallocMeta.pHandle; 5165 } else if (info->mData->size() >= sizeof(nativeMeta) 5166 && nativeMeta.eType == kMetadataBufferTypeANWBuffer) { 5167#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 5168 // ANativeWindowBuffer is only valid on 32-bit/mediaserver process 5169 handle = NULL; 5170#else 5171 handle = (native_handle_t *)nativeMeta.pBuffer->handle; 5172#endif 5173 } 5174 info->mData->meta()->setPointer("handle", handle); 5175 info->mData->meta()->setInt32("rangeOffset", rangeOffset); 5176 info->mData->meta()->setInt32("rangeLength", rangeLength); 5177 } else { 5178 info->mData->setRange(rangeOffset, rangeLength); 5179 } 5180#if 0 5181 if (mCodec->mNativeWindow == NULL) { 5182 if (IsIDR(info->mData)) { 5183 ALOGI("IDR frame"); 5184 } 5185 } 5186#endif 5187 5188 if (mCodec->mSkipCutBuffer != NULL) { 5189 mCodec->mSkipCutBuffer->submit(info->mData); 5190 } 5191 info->mData->meta()->setInt64("timeUs", timeUs); 5192 5193 sp<AMessage> notify = mCodec->mNotify->dup(); 5194 notify->setInt32("what", CodecBase::kWhatDrainThisBuffer); 5195 notify->setInt32("buffer-id", info->mBufferID); 5196 notify->setBuffer("buffer", info->mData); 5197 notify->setInt32("flags", flags); 5198 5199 reply->setInt32("buffer-id", info->mBufferID); 5200 5201 notify->setMessage("reply", reply); 5202 5203 notify->post(); 5204 5205 info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 5206 5207 if (flags & OMX_BUFFERFLAG_EOS) { 5208 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str()); 5209 5210 sp<AMessage> notify = mCodec->mNotify->dup(); 5211 notify->setInt32("what", CodecBase::kWhatEOS); 5212 notify->setInt32("err", mCodec->mInputEOSResult); 5213 notify->post(); 5214 5215 mCodec->mPortEOS[kPortIndexOutput] = true; 5216 } 5217 break; 5218 } 5219 5220 case FREE_BUFFERS: 5221 err = mCodec->freeBuffer(kPortIndexOutput, index); 5222 if (err != OK) { 5223 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5224 return true; 5225 } 5226 break; 5227 5228 default: 5229 ALOGE("Invalid port mode: %d", mode); 5230 return false; 5231 } 5232 5233 return true; 5234} 5235 5236void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 5237 IOMX::buffer_id bufferID; 5238 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 5239 ssize_t index; 5240 BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 5241 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5242 if (status != BufferInfo::OWNED_BY_DOWNSTREAM) { 5243 ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5244 mCodec->dumpBuffers(kPortIndexOutput); 5245 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5246 return; 5247 } 5248 5249 android_native_rect_t crop; 5250 if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) { 5251 status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop); 5252 ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err); 5253 } 5254 5255 int32_t render; 5256 if (mCodec->mNativeWindow != NULL 5257 && msg->findInt32("render", &render) && render != 0 5258 && info->mData != NULL && info->mData->size() != 0) { 5259 ATRACE_NAME("render"); 5260 // The client wants this buffer to be rendered. 5261 5262 // save buffers sent to the surface so we can get render time when they return 5263 int64_t mediaTimeUs = -1; 5264 info->mData->meta()->findInt64("timeUs", &mediaTimeUs); 5265 if (mediaTimeUs >= 0) { 5266 mCodec->mRenderTracker.onFrameQueued( 5267 mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd))); 5268 } 5269 5270 int64_t timestampNs = 0; 5271 if (!msg->findInt64("timestampNs", ×tampNs)) { 5272 // use media timestamp if client did not request a specific render timestamp 5273 if (info->mData->meta()->findInt64("timeUs", ×tampNs)) { 5274 ALOGV("using buffer PTS of %lld", (long long)timestampNs); 5275 timestampNs *= 1000; 5276 } 5277 } 5278 5279 status_t err; 5280 err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs); 5281 ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err); 5282 5283 info->checkReadFence("onOutputBufferDrained before queueBuffer"); 5284 err = mCodec->mNativeWindow->queueBuffer( 5285 mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd); 5286 info->mFenceFd = -1; 5287 if (err == OK) { 5288 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 5289 } else { 5290 ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err); 5291 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5292 info->mStatus = BufferInfo::OWNED_BY_US; 5293 // keeping read fence as write fence to avoid clobbering 5294 info->mIsReadFence = false; 5295 } 5296 } else { 5297 if (mCodec->mNativeWindow != NULL && 5298 (info->mData == NULL || info->mData->size() != 0)) { 5299 // move read fence into write fence to avoid clobbering 5300 info->mIsReadFence = false; 5301 ATRACE_NAME("frame-drop"); 5302 } 5303 info->mStatus = BufferInfo::OWNED_BY_US; 5304 } 5305 5306 PortMode mode = getPortMode(kPortIndexOutput); 5307 5308 switch (mode) { 5309 case KEEP_BUFFERS: 5310 { 5311 // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 5312 5313 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 5314 // We cannot resubmit the buffer we just rendered, dequeue 5315 // the spare instead. 5316 5317 info = mCodec->dequeueBufferFromNativeWindow(); 5318 } 5319 break; 5320 } 5321 5322 case RESUBMIT_BUFFERS: 5323 { 5324 if (!mCodec->mPortEOS[kPortIndexOutput]) { 5325 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 5326 // We cannot resubmit the buffer we just rendered, dequeue 5327 // the spare instead. 5328 5329 info = mCodec->dequeueBufferFromNativeWindow(); 5330 } 5331 5332 if (info != NULL) { 5333 ALOGV("[%s] calling fillBuffer %u", 5334 mCodec->mComponentName.c_str(), info->mBufferID); 5335 info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS"); 5336 status_t err = mCodec->mOMX->fillBuffer( 5337 mCodec->mNode, info->mBufferID, info->mFenceFd); 5338 info->mFenceFd = -1; 5339 if (err == OK) { 5340 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5341 } else { 5342 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5343 } 5344 } 5345 } 5346 break; 5347 } 5348 5349 case FREE_BUFFERS: 5350 { 5351 status_t err = mCodec->freeBuffer(kPortIndexOutput, index); 5352 if (err != OK) { 5353 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5354 } 5355 break; 5356 } 5357 5358 default: 5359 ALOGE("Invalid port mode: %d", mode); 5360 return; 5361 } 5362} 5363 5364//////////////////////////////////////////////////////////////////////////////// 5365 5366ACodec::UninitializedState::UninitializedState(ACodec *codec) 5367 : BaseState(codec) { 5368} 5369 5370void ACodec::UninitializedState::stateEntered() { 5371 ALOGV("Now uninitialized"); 5372 5373 if (mDeathNotifier != NULL) { 5374 IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier); 5375 mDeathNotifier.clear(); 5376 } 5377 5378 mCodec->mNativeWindow.clear(); 5379 mCodec->mNativeWindowUsageBits = 0; 5380 mCodec->mNode = 0; 5381 mCodec->mOMX.clear(); 5382 mCodec->mQuirks = 0; 5383 mCodec->mFlags = 0; 5384 mCodec->mInputMetadataType = kMetadataBufferTypeInvalid; 5385 mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid; 5386 mCodec->mComponentName.clear(); 5387} 5388 5389bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 5390 bool handled = false; 5391 5392 switch (msg->what()) { 5393 case ACodec::kWhatSetup: 5394 { 5395 onSetup(msg); 5396 5397 handled = true; 5398 break; 5399 } 5400 5401 case ACodec::kWhatAllocateComponent: 5402 { 5403 onAllocateComponent(msg); 5404 handled = true; 5405 break; 5406 } 5407 5408 case ACodec::kWhatShutdown: 5409 { 5410 int32_t keepComponentAllocated; 5411 CHECK(msg->findInt32( 5412 "keepComponentAllocated", &keepComponentAllocated)); 5413 ALOGW_IF(keepComponentAllocated, 5414 "cannot keep component allocated on shutdown in Uninitialized state"); 5415 5416 sp<AMessage> notify = mCodec->mNotify->dup(); 5417 notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 5418 notify->post(); 5419 5420 handled = true; 5421 break; 5422 } 5423 5424 case ACodec::kWhatFlush: 5425 { 5426 sp<AMessage> notify = mCodec->mNotify->dup(); 5427 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5428 notify->post(); 5429 5430 handled = true; 5431 break; 5432 } 5433 5434 case ACodec::kWhatReleaseCodecInstance: 5435 { 5436 // nothing to do, as we have already signaled shutdown 5437 handled = true; 5438 break; 5439 } 5440 5441 default: 5442 return BaseState::onMessageReceived(msg); 5443 } 5444 5445 return handled; 5446} 5447 5448void ACodec::UninitializedState::onSetup( 5449 const sp<AMessage> &msg) { 5450 if (onAllocateComponent(msg) 5451 && mCodec->mLoadedState->onConfigureComponent(msg)) { 5452 mCodec->mLoadedState->onStart(); 5453 } 5454} 5455 5456bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { 5457 ALOGV("onAllocateComponent"); 5458 5459 CHECK(mCodec->mNode == 0); 5460 5461 OMXClient client; 5462 if (client.connect() != OK) { 5463 mCodec->signalError(OMX_ErrorUndefined, NO_INIT); 5464 return false; 5465 } 5466 5467 sp<IOMX> omx = client.interface(); 5468 5469 sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec); 5470 5471 mDeathNotifier = new DeathNotifier(notify); 5472 if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) { 5473 // This was a local binder, if it dies so do we, we won't care 5474 // about any notifications in the afterlife. 5475 mDeathNotifier.clear(); 5476 } 5477 5478 Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs; 5479 5480 AString mime; 5481 5482 AString componentName; 5483 uint32_t quirks = 0; 5484 int32_t encoder = false; 5485 if (msg->findString("componentName", &componentName)) { 5486 ssize_t index = matchingCodecs.add(); 5487 OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index); 5488 entry->mName = String8(componentName.c_str()); 5489 5490 if (!OMXCodec::findCodecQuirks( 5491 componentName.c_str(), &entry->mQuirks)) { 5492 entry->mQuirks = 0; 5493 } 5494 } else { 5495 CHECK(msg->findString("mime", &mime)); 5496 5497 if (!msg->findInt32("encoder", &encoder)) { 5498 encoder = false; 5499 } 5500 5501 OMXCodec::findMatchingCodecs( 5502 mime.c_str(), 5503 encoder, // createEncoder 5504 NULL, // matchComponentName 5505 0, // flags 5506 &matchingCodecs); 5507 } 5508 5509 sp<CodecObserver> observer = new CodecObserver; 5510 IOMX::node_id node = 0; 5511 5512 status_t err = NAME_NOT_FOUND; 5513 for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); 5514 ++matchIndex) { 5515 componentName = matchingCodecs.itemAt(matchIndex).mName.string(); 5516 quirks = matchingCodecs.itemAt(matchIndex).mQuirks; 5517 5518 pid_t tid = gettid(); 5519 int prevPriority = androidGetThreadPriority(tid); 5520 androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); 5521 err = omx->allocateNode(componentName.c_str(), observer, &node); 5522 androidSetThreadPriority(tid, prevPriority); 5523 5524 if (err == OK) { 5525 break; 5526 } else { 5527 ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str()); 5528 } 5529 5530 node = 0; 5531 } 5532 5533 if (node == 0) { 5534 if (!mime.empty()) { 5535 ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.", 5536 encoder ? "en" : "de", mime.c_str(), err); 5537 } else { 5538 ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err); 5539 } 5540 5541 mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err)); 5542 return false; 5543 } 5544 5545 notify = new AMessage(kWhatOMXMessageList, mCodec); 5546 observer->setNotificationMessage(notify); 5547 5548 mCodec->mComponentName = componentName; 5549 mCodec->mRenderTracker.setComponentName(componentName); 5550 mCodec->mFlags = 0; 5551 5552 if (componentName.endsWith(".secure")) { 5553 mCodec->mFlags |= kFlagIsSecure; 5554 mCodec->mFlags |= kFlagIsGrallocUsageProtected; 5555 mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 5556 } 5557 5558 mCodec->mQuirks = quirks; 5559 mCodec->mOMX = omx; 5560 mCodec->mNode = node; 5561 5562 { 5563 sp<AMessage> notify = mCodec->mNotify->dup(); 5564 notify->setInt32("what", CodecBase::kWhatComponentAllocated); 5565 notify->setString("componentName", mCodec->mComponentName.c_str()); 5566 notify->post(); 5567 } 5568 5569 mCodec->changeState(mCodec->mLoadedState); 5570 5571 return true; 5572} 5573 5574//////////////////////////////////////////////////////////////////////////////// 5575 5576ACodec::LoadedState::LoadedState(ACodec *codec) 5577 : BaseState(codec) { 5578} 5579 5580void ACodec::LoadedState::stateEntered() { 5581 ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 5582 5583 mCodec->mPortEOS[kPortIndexInput] = 5584 mCodec->mPortEOS[kPortIndexOutput] = false; 5585 5586 mCodec->mInputEOSResult = OK; 5587 5588 mCodec->mDequeueCounter = 0; 5589 mCodec->mMetadataBuffersToSubmit = 0; 5590 mCodec->mRepeatFrameDelayUs = -1ll; 5591 mCodec->mInputFormat.clear(); 5592 mCodec->mOutputFormat.clear(); 5593 mCodec->mBaseOutputFormat.clear(); 5594 5595 if (mCodec->mShutdownInProgress) { 5596 bool keepComponentAllocated = mCodec->mKeepComponentAllocated; 5597 5598 mCodec->mShutdownInProgress = false; 5599 mCodec->mKeepComponentAllocated = false; 5600 5601 onShutdown(keepComponentAllocated); 5602 } 5603 mCodec->mExplicitShutdown = false; 5604 5605 mCodec->processDeferredMessages(); 5606} 5607 5608void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) { 5609 if (!keepComponentAllocated) { 5610 (void)mCodec->mOMX->freeNode(mCodec->mNode); 5611 5612 mCodec->changeState(mCodec->mUninitializedState); 5613 } 5614 5615 if (mCodec->mExplicitShutdown) { 5616 sp<AMessage> notify = mCodec->mNotify->dup(); 5617 notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 5618 notify->post(); 5619 mCodec->mExplicitShutdown = false; 5620 } 5621} 5622 5623bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) { 5624 bool handled = false; 5625 5626 switch (msg->what()) { 5627 case ACodec::kWhatConfigureComponent: 5628 { 5629 onConfigureComponent(msg); 5630 handled = true; 5631 break; 5632 } 5633 5634 case ACodec::kWhatCreateInputSurface: 5635 { 5636 onCreateInputSurface(msg); 5637 handled = true; 5638 break; 5639 } 5640 5641 case ACodec::kWhatSetInputSurface: 5642 { 5643 onSetInputSurface(msg); 5644 handled = true; 5645 break; 5646 } 5647 5648 case ACodec::kWhatStart: 5649 { 5650 onStart(); 5651 handled = true; 5652 break; 5653 } 5654 5655 case ACodec::kWhatShutdown: 5656 { 5657 int32_t keepComponentAllocated; 5658 CHECK(msg->findInt32( 5659 "keepComponentAllocated", &keepComponentAllocated)); 5660 5661 mCodec->mExplicitShutdown = true; 5662 onShutdown(keepComponentAllocated); 5663 5664 handled = true; 5665 break; 5666 } 5667 5668 case ACodec::kWhatFlush: 5669 { 5670 sp<AMessage> notify = mCodec->mNotify->dup(); 5671 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5672 notify->post(); 5673 5674 handled = true; 5675 break; 5676 } 5677 5678 default: 5679 return BaseState::onMessageReceived(msg); 5680 } 5681 5682 return handled; 5683} 5684 5685bool ACodec::LoadedState::onConfigureComponent( 5686 const sp<AMessage> &msg) { 5687 ALOGV("onConfigureComponent"); 5688 5689 CHECK(mCodec->mNode != 0); 5690 5691 status_t err = OK; 5692 AString mime; 5693 if (!msg->findString("mime", &mime)) { 5694 err = BAD_VALUE; 5695 } else { 5696 err = mCodec->configureCodec(mime.c_str(), msg); 5697 } 5698 if (err != OK) { 5699 ALOGE("[%s] configureCodec returning error %d", 5700 mCodec->mComponentName.c_str(), err); 5701 5702 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5703 return false; 5704 } 5705 5706 { 5707 sp<AMessage> notify = mCodec->mNotify->dup(); 5708 notify->setInt32("what", CodecBase::kWhatComponentConfigured); 5709 notify->setMessage("input-format", mCodec->mInputFormat); 5710 notify->setMessage("output-format", mCodec->mOutputFormat); 5711 notify->post(); 5712 } 5713 5714 return true; 5715} 5716 5717status_t ACodec::LoadedState::setupInputSurface() { 5718 status_t err = OK; 5719 5720 if (mCodec->mRepeatFrameDelayUs > 0ll) { 5721 err = mCodec->mOMX->setInternalOption( 5722 mCodec->mNode, 5723 kPortIndexInput, 5724 IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY, 5725 &mCodec->mRepeatFrameDelayUs, 5726 sizeof(mCodec->mRepeatFrameDelayUs)); 5727 5728 if (err != OK) { 5729 ALOGE("[%s] Unable to configure option to repeat previous " 5730 "frames (err %d)", 5731 mCodec->mComponentName.c_str(), 5732 err); 5733 return err; 5734 } 5735 } 5736 5737 if (mCodec->mMaxPtsGapUs > 0ll) { 5738 err = mCodec->mOMX->setInternalOption( 5739 mCodec->mNode, 5740 kPortIndexInput, 5741 IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP, 5742 &mCodec->mMaxPtsGapUs, 5743 sizeof(mCodec->mMaxPtsGapUs)); 5744 5745 if (err != OK) { 5746 ALOGE("[%s] Unable to configure max timestamp gap (err %d)", 5747 mCodec->mComponentName.c_str(), 5748 err); 5749 return err; 5750 } 5751 } 5752 5753 if (mCodec->mMaxFps > 0) { 5754 err = mCodec->mOMX->setInternalOption( 5755 mCodec->mNode, 5756 kPortIndexInput, 5757 IOMX::INTERNAL_OPTION_MAX_FPS, 5758 &mCodec->mMaxFps, 5759 sizeof(mCodec->mMaxFps)); 5760 5761 if (err != OK) { 5762 ALOGE("[%s] Unable to configure max fps (err %d)", 5763 mCodec->mComponentName.c_str(), 5764 err); 5765 return err; 5766 } 5767 } 5768 5769 if (mCodec->mTimePerCaptureUs > 0ll 5770 && mCodec->mTimePerFrameUs > 0ll) { 5771 int64_t timeLapse[2]; 5772 timeLapse[0] = mCodec->mTimePerFrameUs; 5773 timeLapse[1] = mCodec->mTimePerCaptureUs; 5774 err = mCodec->mOMX->setInternalOption( 5775 mCodec->mNode, 5776 kPortIndexInput, 5777 IOMX::INTERNAL_OPTION_TIME_LAPSE, 5778 &timeLapse[0], 5779 sizeof(timeLapse)); 5780 5781 if (err != OK) { 5782 ALOGE("[%s] Unable to configure time lapse (err %d)", 5783 mCodec->mComponentName.c_str(), 5784 err); 5785 return err; 5786 } 5787 } 5788 5789 if (mCodec->mCreateInputBuffersSuspended) { 5790 bool suspend = true; 5791 err = mCodec->mOMX->setInternalOption( 5792 mCodec->mNode, 5793 kPortIndexInput, 5794 IOMX::INTERNAL_OPTION_SUSPEND, 5795 &suspend, 5796 sizeof(suspend)); 5797 5798 if (err != OK) { 5799 ALOGE("[%s] Unable to configure option to suspend (err %d)", 5800 mCodec->mComponentName.c_str(), 5801 err); 5802 return err; 5803 } 5804 } 5805 5806 uint32_t usageBits; 5807 if (mCodec->mOMX->getParameter( 5808 mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, 5809 &usageBits, sizeof(usageBits)) == OK) { 5810 mCodec->mInputFormat->setInt32( 5811 "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN)); 5812 } 5813 5814 return OK; 5815} 5816 5817void ACodec::LoadedState::onCreateInputSurface( 5818 const sp<AMessage> & /* msg */) { 5819 ALOGV("onCreateInputSurface"); 5820 5821 sp<AMessage> notify = mCodec->mNotify->dup(); 5822 notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated); 5823 5824 sp<IGraphicBufferProducer> bufferProducer; 5825 status_t err = mCodec->mOMX->createInputSurface( 5826 mCodec->mNode, kPortIndexInput, &bufferProducer, &mCodec->mInputMetadataType); 5827 5828 if (err == OK) { 5829 err = setupInputSurface(); 5830 } 5831 5832 if (err == OK) { 5833 notify->setObject("input-surface", 5834 new BufferProducerWrapper(bufferProducer)); 5835 } else { 5836 // Can't use mCodec->signalError() here -- MediaCodec won't forward 5837 // the error through because it's in the "configured" state. We 5838 // send a kWhatInputSurfaceCreated with an error value instead. 5839 ALOGE("[%s] onCreateInputSurface returning error %d", 5840 mCodec->mComponentName.c_str(), err); 5841 notify->setInt32("err", err); 5842 } 5843 notify->post(); 5844} 5845 5846void ACodec::LoadedState::onSetInputSurface( 5847 const sp<AMessage> &msg) { 5848 ALOGV("onSetInputSurface"); 5849 5850 sp<AMessage> notify = mCodec->mNotify->dup(); 5851 notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted); 5852 5853 sp<RefBase> obj; 5854 CHECK(msg->findObject("input-surface", &obj)); 5855 sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get()); 5856 5857 status_t err = mCodec->mOMX->setInputSurface( 5858 mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(), 5859 &mCodec->mInputMetadataType); 5860 5861 if (err == OK) { 5862 err = setupInputSurface(); 5863 } 5864 5865 if (err != OK) { 5866 // Can't use mCodec->signalError() here -- MediaCodec won't forward 5867 // the error through because it's in the "configured" state. We 5868 // send a kWhatInputSurfaceAccepted with an error value instead. 5869 ALOGE("[%s] onSetInputSurface returning error %d", 5870 mCodec->mComponentName.c_str(), err); 5871 notify->setInt32("err", err); 5872 } 5873 notify->post(); 5874} 5875 5876void ACodec::LoadedState::onStart() { 5877 ALOGV("onStart"); 5878 5879 status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle); 5880 if (err != OK) { 5881 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5882 } else { 5883 mCodec->changeState(mCodec->mLoadedToIdleState); 5884 } 5885} 5886 5887//////////////////////////////////////////////////////////////////////////////// 5888 5889ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 5890 : BaseState(codec) { 5891} 5892 5893void ACodec::LoadedToIdleState::stateEntered() { 5894 ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 5895 5896 status_t err; 5897 if ((err = allocateBuffers()) != OK) { 5898 ALOGE("Failed to allocate buffers after transitioning to IDLE state " 5899 "(error 0x%08x)", 5900 err); 5901 5902 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5903 5904 mCodec->changeState(mCodec->mLoadedState); 5905 } 5906} 5907 5908status_t ACodec::LoadedToIdleState::allocateBuffers() { 5909 status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 5910 5911 if (err != OK) { 5912 return err; 5913 } 5914 5915 return mCodec->allocateBuffersOnPort(kPortIndexOutput); 5916} 5917 5918bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 5919 switch (msg->what()) { 5920 case kWhatSetParameters: 5921 case kWhatShutdown: 5922 { 5923 mCodec->deferMessage(msg); 5924 return true; 5925 } 5926 5927 case kWhatSignalEndOfInputStream: 5928 { 5929 mCodec->onSignalEndOfInputStream(); 5930 return true; 5931 } 5932 5933 case kWhatResume: 5934 { 5935 // We'll be active soon enough. 5936 return true; 5937 } 5938 5939 case kWhatFlush: 5940 { 5941 // We haven't even started yet, so we're flushed alright... 5942 sp<AMessage> notify = mCodec->mNotify->dup(); 5943 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5944 notify->post(); 5945 return true; 5946 } 5947 5948 default: 5949 return BaseState::onMessageReceived(msg); 5950 } 5951} 5952 5953bool ACodec::LoadedToIdleState::onOMXEvent( 5954 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5955 switch (event) { 5956 case OMX_EventCmdComplete: 5957 { 5958 status_t err = OK; 5959 if (data1 != (OMX_U32)OMX_CommandStateSet 5960 || data2 != (OMX_U32)OMX_StateIdle) { 5961 ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)", 5962 asString((OMX_COMMANDTYPE)data1), data1, 5963 asString((OMX_STATETYPE)data2), data2); 5964 err = FAILED_TRANSACTION; 5965 } 5966 5967 if (err == OK) { 5968 err = mCodec->mOMX->sendCommand( 5969 mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting); 5970 } 5971 5972 if (err != OK) { 5973 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5974 } else { 5975 mCodec->changeState(mCodec->mIdleToExecutingState); 5976 } 5977 5978 return true; 5979 } 5980 5981 default: 5982 return BaseState::onOMXEvent(event, data1, data2); 5983 } 5984} 5985 5986//////////////////////////////////////////////////////////////////////////////// 5987 5988ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 5989 : BaseState(codec) { 5990} 5991 5992void ACodec::IdleToExecutingState::stateEntered() { 5993 ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 5994} 5995 5996bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 5997 switch (msg->what()) { 5998 case kWhatSetParameters: 5999 case kWhatShutdown: 6000 { 6001 mCodec->deferMessage(msg); 6002 return true; 6003 } 6004 6005 case kWhatResume: 6006 { 6007 // We'll be active soon enough. 6008 return true; 6009 } 6010 6011 case kWhatFlush: 6012 { 6013 // We haven't even started yet, so we're flushed alright... 6014 sp<AMessage> notify = mCodec->mNotify->dup(); 6015 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 6016 notify->post(); 6017 6018 return true; 6019 } 6020 6021 case kWhatSignalEndOfInputStream: 6022 { 6023 mCodec->onSignalEndOfInputStream(); 6024 return true; 6025 } 6026 6027 default: 6028 return BaseState::onMessageReceived(msg); 6029 } 6030} 6031 6032bool ACodec::IdleToExecutingState::onOMXEvent( 6033 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6034 switch (event) { 6035 case OMX_EventCmdComplete: 6036 { 6037 if (data1 != (OMX_U32)OMX_CommandStateSet 6038 || data2 != (OMX_U32)OMX_StateExecuting) { 6039 ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)", 6040 asString((OMX_COMMANDTYPE)data1), data1, 6041 asString((OMX_STATETYPE)data2), data2); 6042 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6043 return true; 6044 } 6045 6046 mCodec->mExecutingState->resume(); 6047 mCodec->changeState(mCodec->mExecutingState); 6048 6049 return true; 6050 } 6051 6052 default: 6053 return BaseState::onOMXEvent(event, data1, data2); 6054 } 6055} 6056 6057//////////////////////////////////////////////////////////////////////////////// 6058 6059ACodec::ExecutingState::ExecutingState(ACodec *codec) 6060 : BaseState(codec), 6061 mActive(false) { 6062} 6063 6064ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 6065 OMX_U32 /* portIndex */) { 6066 return RESUBMIT_BUFFERS; 6067} 6068 6069void ACodec::ExecutingState::submitOutputMetaBuffers() { 6070 // submit as many buffers as there are input buffers with the codec 6071 // in case we are in port reconfiguring 6072 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 6073 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 6074 6075 if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) { 6076 if (mCodec->submitOutputMetadataBuffer() != OK) 6077 break; 6078 } 6079 } 6080 6081 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 6082 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 6083} 6084 6085void ACodec::ExecutingState::submitRegularOutputBuffers() { 6086 bool failed = false; 6087 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 6088 BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 6089 6090 if (mCodec->mNativeWindow != NULL) { 6091 if (info->mStatus != BufferInfo::OWNED_BY_US 6092 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6093 ALOGE("buffers should be owned by us or the surface"); 6094 failed = true; 6095 break; 6096 } 6097 6098 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6099 continue; 6100 } 6101 } else { 6102 if (info->mStatus != BufferInfo::OWNED_BY_US) { 6103 ALOGE("buffers should be owned by us"); 6104 failed = true; 6105 break; 6106 } 6107 } 6108 6109 ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID); 6110 6111 info->checkWriteFence("submitRegularOutputBuffers"); 6112 status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd); 6113 info->mFenceFd = -1; 6114 if (err != OK) { 6115 failed = true; 6116 break; 6117 } 6118 6119 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 6120 } 6121 6122 if (failed) { 6123 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6124 } 6125} 6126 6127void ACodec::ExecutingState::submitOutputBuffers() { 6128 submitRegularOutputBuffers(); 6129 if (mCodec->storingMetadataInDecodedBuffers()) { 6130 submitOutputMetaBuffers(); 6131 } 6132} 6133 6134void ACodec::ExecutingState::resume() { 6135 if (mActive) { 6136 ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str()); 6137 return; 6138 } 6139 6140 submitOutputBuffers(); 6141 6142 // Post all available input buffers 6143 if (mCodec->mBuffers[kPortIndexInput].size() == 0u) { 6144 ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str()); 6145 } 6146 6147 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) { 6148 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 6149 if (info->mStatus == BufferInfo::OWNED_BY_US) { 6150 postFillThisBuffer(info); 6151 } 6152 } 6153 6154 mActive = true; 6155} 6156 6157void ACodec::ExecutingState::stateEntered() { 6158 ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 6159 6160 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 6161 mCodec->processDeferredMessages(); 6162} 6163 6164bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 6165 bool handled = false; 6166 6167 switch (msg->what()) { 6168 case kWhatShutdown: 6169 { 6170 int32_t keepComponentAllocated; 6171 CHECK(msg->findInt32( 6172 "keepComponentAllocated", &keepComponentAllocated)); 6173 6174 mCodec->mShutdownInProgress = true; 6175 mCodec->mExplicitShutdown = true; 6176 mCodec->mKeepComponentAllocated = keepComponentAllocated; 6177 6178 mActive = false; 6179 6180 status_t err = mCodec->mOMX->sendCommand( 6181 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle); 6182 if (err != OK) { 6183 if (keepComponentAllocated) { 6184 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6185 } 6186 // TODO: do some recovery here. 6187 } else { 6188 mCodec->changeState(mCodec->mExecutingToIdleState); 6189 } 6190 6191 handled = true; 6192 break; 6193 } 6194 6195 case kWhatFlush: 6196 { 6197 ALOGV("[%s] ExecutingState flushing now " 6198 "(codec owns %zu/%zu input, %zu/%zu output).", 6199 mCodec->mComponentName.c_str(), 6200 mCodec->countBuffersOwnedByComponent(kPortIndexInput), 6201 mCodec->mBuffers[kPortIndexInput].size(), 6202 mCodec->countBuffersOwnedByComponent(kPortIndexOutput), 6203 mCodec->mBuffers[kPortIndexOutput].size()); 6204 6205 mActive = false; 6206 6207 status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL); 6208 if (err != OK) { 6209 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6210 } else { 6211 mCodec->changeState(mCodec->mFlushingState); 6212 } 6213 6214 handled = true; 6215 break; 6216 } 6217 6218 case kWhatResume: 6219 { 6220 resume(); 6221 6222 handled = true; 6223 break; 6224 } 6225 6226 case kWhatRequestIDRFrame: 6227 { 6228 status_t err = mCodec->requestIDRFrame(); 6229 if (err != OK) { 6230 ALOGW("Requesting an IDR frame failed."); 6231 } 6232 6233 handled = true; 6234 break; 6235 } 6236 6237 case kWhatSetParameters: 6238 { 6239 sp<AMessage> params; 6240 CHECK(msg->findMessage("params", ¶ms)); 6241 6242 status_t err = mCodec->setParameters(params); 6243 6244 sp<AMessage> reply; 6245 if (msg->findMessage("reply", &reply)) { 6246 reply->setInt32("err", err); 6247 reply->post(); 6248 } 6249 6250 handled = true; 6251 break; 6252 } 6253 6254 case ACodec::kWhatSignalEndOfInputStream: 6255 { 6256 mCodec->onSignalEndOfInputStream(); 6257 handled = true; 6258 break; 6259 } 6260 6261 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 6262 case kWhatSubmitOutputMetadataBufferIfEOS: 6263 { 6264 if (mCodec->mPortEOS[kPortIndexInput] && 6265 !mCodec->mPortEOS[kPortIndexOutput]) { 6266 status_t err = mCodec->submitOutputMetadataBuffer(); 6267 if (err == OK) { 6268 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 6269 } 6270 } 6271 return true; 6272 } 6273 6274 default: 6275 handled = BaseState::onMessageReceived(msg); 6276 break; 6277 } 6278 6279 return handled; 6280} 6281 6282status_t ACodec::setParameters(const sp<AMessage> ¶ms) { 6283 int32_t videoBitrate; 6284 if (params->findInt32("video-bitrate", &videoBitrate)) { 6285 OMX_VIDEO_CONFIG_BITRATETYPE configParams; 6286 InitOMXParams(&configParams); 6287 configParams.nPortIndex = kPortIndexOutput; 6288 configParams.nEncodeBitrate = videoBitrate; 6289 6290 status_t err = mOMX->setConfig( 6291 mNode, 6292 OMX_IndexConfigVideoBitrate, 6293 &configParams, 6294 sizeof(configParams)); 6295 6296 if (err != OK) { 6297 ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d", 6298 videoBitrate, err); 6299 6300 return err; 6301 } 6302 } 6303 6304 int64_t skipFramesBeforeUs; 6305 if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) { 6306 status_t err = 6307 mOMX->setInternalOption( 6308 mNode, 6309 kPortIndexInput, 6310 IOMX::INTERNAL_OPTION_START_TIME, 6311 &skipFramesBeforeUs, 6312 sizeof(skipFramesBeforeUs)); 6313 6314 if (err != OK) { 6315 ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err); 6316 return err; 6317 } 6318 } 6319 6320 int32_t dropInputFrames; 6321 if (params->findInt32("drop-input-frames", &dropInputFrames)) { 6322 bool suspend = dropInputFrames != 0; 6323 6324 status_t err = 6325 mOMX->setInternalOption( 6326 mNode, 6327 kPortIndexInput, 6328 IOMX::INTERNAL_OPTION_SUSPEND, 6329 &suspend, 6330 sizeof(suspend)); 6331 6332 if (err != OK) { 6333 ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err); 6334 return err; 6335 } 6336 } 6337 6338 int32_t dummy; 6339 if (params->findInt32("request-sync", &dummy)) { 6340 status_t err = requestIDRFrame(); 6341 6342 if (err != OK) { 6343 ALOGE("Requesting a sync frame failed w/ err %d", err); 6344 return err; 6345 } 6346 } 6347 6348 float rate; 6349 if (params->findFloat("operating-rate", &rate) && rate > 0) { 6350 status_t err = setOperatingRate(rate, mIsVideo); 6351 if (err != OK) { 6352 ALOGE("Failed to set parameter 'operating-rate' (err %d)", err); 6353 return err; 6354 } 6355 } 6356 6357 return OK; 6358} 6359 6360void ACodec::onSignalEndOfInputStream() { 6361 sp<AMessage> notify = mNotify->dup(); 6362 notify->setInt32("what", CodecBase::kWhatSignaledInputEOS); 6363 6364 status_t err = mOMX->signalEndOfInputStream(mNode); 6365 if (err != OK) { 6366 notify->setInt32("err", err); 6367 } 6368 notify->post(); 6369} 6370 6371bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { 6372 mCodec->onFrameRendered(mediaTimeUs, systemNano); 6373 return true; 6374} 6375 6376bool ACodec::ExecutingState::onOMXEvent( 6377 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6378 switch (event) { 6379 case OMX_EventPortSettingsChanged: 6380 { 6381 CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 6382 6383 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 6384 mCodec->mMetadataBuffersToSubmit = 0; 6385 CHECK_EQ(mCodec->mOMX->sendCommand( 6386 mCodec->mNode, 6387 OMX_CommandPortDisable, kPortIndexOutput), 6388 (status_t)OK); 6389 6390 mCodec->freeOutputBuffersNotOwnedByComponent(); 6391 6392 mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 6393 } else if (data2 == OMX_IndexConfigCommonOutputCrop) { 6394 mCodec->mSentFormat = false; 6395 6396 if (mCodec->mTunneled) { 6397 sp<AMessage> dummy = new AMessage(kWhatOutputBufferDrained, mCodec); 6398 mCodec->sendFormatChange(dummy); 6399 } 6400 } else { 6401 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x", 6402 mCodec->mComponentName.c_str(), data2); 6403 } 6404 6405 return true; 6406 } 6407 6408 case OMX_EventBufferFlag: 6409 { 6410 return true; 6411 } 6412 6413 default: 6414 return BaseState::onOMXEvent(event, data1, data2); 6415 } 6416} 6417 6418//////////////////////////////////////////////////////////////////////////////// 6419 6420ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 6421 ACodec *codec) 6422 : BaseState(codec) { 6423} 6424 6425ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 6426 OMX_U32 portIndex) { 6427 if (portIndex == kPortIndexOutput) { 6428 return FREE_BUFFERS; 6429 } 6430 6431 CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 6432 6433 return RESUBMIT_BUFFERS; 6434} 6435 6436bool ACodec::OutputPortSettingsChangedState::onMessageReceived( 6437 const sp<AMessage> &msg) { 6438 bool handled = false; 6439 6440 switch (msg->what()) { 6441 case kWhatFlush: 6442 case kWhatShutdown: 6443 case kWhatResume: 6444 case kWhatSetParameters: 6445 { 6446 if (msg->what() == kWhatResume) { 6447 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 6448 } 6449 6450 mCodec->deferMessage(msg); 6451 handled = true; 6452 break; 6453 } 6454 6455 default: 6456 handled = BaseState::onMessageReceived(msg); 6457 break; 6458 } 6459 6460 return handled; 6461} 6462 6463void ACodec::OutputPortSettingsChangedState::stateEntered() { 6464 ALOGV("[%s] Now handling output port settings change", 6465 mCodec->mComponentName.c_str()); 6466} 6467 6468bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered( 6469 int64_t mediaTimeUs, nsecs_t systemNano) { 6470 mCodec->onFrameRendered(mediaTimeUs, systemNano); 6471 return true; 6472} 6473 6474bool ACodec::OutputPortSettingsChangedState::onOMXEvent( 6475 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6476 switch (event) { 6477 case OMX_EventCmdComplete: 6478 { 6479 if (data1 == (OMX_U32)OMX_CommandPortDisable) { 6480 if (data2 != (OMX_U32)kPortIndexOutput) { 6481 ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2); 6482 return false; 6483 } 6484 6485 ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str()); 6486 6487 status_t err = OK; 6488 if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) { 6489 ALOGE("disabled port should be empty, but has %zu buffers", 6490 mCodec->mBuffers[kPortIndexOutput].size()); 6491 err = FAILED_TRANSACTION; 6492 } else { 6493 mCodec->mDealer[kPortIndexOutput].clear(); 6494 } 6495 6496 if (err == OK) { 6497 err = mCodec->mOMX->sendCommand( 6498 mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput); 6499 } 6500 6501 if (err == OK) { 6502 err = mCodec->allocateBuffersOnPort(kPortIndexOutput); 6503 ALOGE_IF(err != OK, "Failed to allocate output port buffers after port " 6504 "reconfiguration: (%d)", err); 6505 } 6506 6507 if (err != OK) { 6508 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6509 6510 // This is technically not correct, but appears to be 6511 // the only way to free the component instance. 6512 // Controlled transitioning from excecuting->idle 6513 // and idle->loaded seem impossible probably because 6514 // the output port never finishes re-enabling. 6515 mCodec->mShutdownInProgress = true; 6516 mCodec->mKeepComponentAllocated = false; 6517 mCodec->changeState(mCodec->mLoadedState); 6518 } 6519 6520 return true; 6521 } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 6522 if (data2 != (OMX_U32)kPortIndexOutput) { 6523 ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2); 6524 return false; 6525 } 6526 6527 mCodec->mSentFormat = false; 6528 6529 if (mCodec->mTunneled) { 6530 sp<AMessage> dummy = new AMessage(kWhatOutputBufferDrained, mCodec); 6531 mCodec->sendFormatChange(dummy); 6532 } 6533 6534 ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str()); 6535 6536 if (mCodec->mExecutingState->active()) { 6537 mCodec->mExecutingState->submitOutputBuffers(); 6538 } 6539 6540 mCodec->changeState(mCodec->mExecutingState); 6541 6542 return true; 6543 } 6544 6545 return false; 6546 } 6547 6548 default: 6549 return false; 6550 } 6551} 6552 6553//////////////////////////////////////////////////////////////////////////////// 6554 6555ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 6556 : BaseState(codec), 6557 mComponentNowIdle(false) { 6558} 6559 6560bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 6561 bool handled = false; 6562 6563 switch (msg->what()) { 6564 case kWhatFlush: 6565 { 6566 // Don't send me a flush request if you previously wanted me 6567 // to shutdown. 6568 ALOGW("Ignoring flush request in ExecutingToIdleState"); 6569 break; 6570 } 6571 6572 case kWhatShutdown: 6573 { 6574 // We're already doing that... 6575 6576 handled = true; 6577 break; 6578 } 6579 6580 default: 6581 handled = BaseState::onMessageReceived(msg); 6582 break; 6583 } 6584 6585 return handled; 6586} 6587 6588void ACodec::ExecutingToIdleState::stateEntered() { 6589 ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 6590 6591 mComponentNowIdle = false; 6592 mCodec->mSentFormat = false; 6593} 6594 6595bool ACodec::ExecutingToIdleState::onOMXEvent( 6596 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6597 switch (event) { 6598 case OMX_EventCmdComplete: 6599 { 6600 if (data1 != (OMX_U32)OMX_CommandStateSet 6601 || data2 != (OMX_U32)OMX_StateIdle) { 6602 ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)", 6603 asString((OMX_COMMANDTYPE)data1), data1, 6604 asString((OMX_STATETYPE)data2), data2); 6605 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6606 return true; 6607 } 6608 6609 mComponentNowIdle = true; 6610 6611 changeStateIfWeOwnAllBuffers(); 6612 6613 return true; 6614 } 6615 6616 case OMX_EventPortSettingsChanged: 6617 case OMX_EventBufferFlag: 6618 { 6619 // We're shutting down and don't care about this anymore. 6620 return true; 6621 } 6622 6623 default: 6624 return BaseState::onOMXEvent(event, data1, data2); 6625 } 6626} 6627 6628void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 6629 if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) { 6630 status_t err = mCodec->mOMX->sendCommand( 6631 mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded); 6632 if (err == OK) { 6633 err = mCodec->freeBuffersOnPort(kPortIndexInput); 6634 status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput); 6635 if (err == OK) { 6636 err = err2; 6637 } 6638 } 6639 6640 if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) 6641 && mCodec->mNativeWindow != NULL) { 6642 // We push enough 1x1 blank buffers to ensure that one of 6643 // them has made it to the display. This allows the OMX 6644 // component teardown to zero out any protected buffers 6645 // without the risk of scanning out one of those buffers. 6646 pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get()); 6647 } 6648 6649 if (err != OK) { 6650 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6651 return; 6652 } 6653 6654 mCodec->changeState(mCodec->mIdleToLoadedState); 6655 } 6656} 6657 6658void ACodec::ExecutingToIdleState::onInputBufferFilled( 6659 const sp<AMessage> &msg) { 6660 BaseState::onInputBufferFilled(msg); 6661 6662 changeStateIfWeOwnAllBuffers(); 6663} 6664 6665void ACodec::ExecutingToIdleState::onOutputBufferDrained( 6666 const sp<AMessage> &msg) { 6667 BaseState::onOutputBufferDrained(msg); 6668 6669 changeStateIfWeOwnAllBuffers(); 6670} 6671 6672//////////////////////////////////////////////////////////////////////////////// 6673 6674ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 6675 : BaseState(codec) { 6676} 6677 6678bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 6679 bool handled = false; 6680 6681 switch (msg->what()) { 6682 case kWhatShutdown: 6683 { 6684 // We're already doing that... 6685 6686 handled = true; 6687 break; 6688 } 6689 6690 case kWhatFlush: 6691 { 6692 // Don't send me a flush request if you previously wanted me 6693 // to shutdown. 6694 ALOGE("Got flush request in IdleToLoadedState"); 6695 break; 6696 } 6697 6698 default: 6699 handled = BaseState::onMessageReceived(msg); 6700 break; 6701 } 6702 6703 return handled; 6704} 6705 6706void ACodec::IdleToLoadedState::stateEntered() { 6707 ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 6708} 6709 6710bool ACodec::IdleToLoadedState::onOMXEvent( 6711 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6712 switch (event) { 6713 case OMX_EventCmdComplete: 6714 { 6715 if (data1 != (OMX_U32)OMX_CommandStateSet 6716 || data2 != (OMX_U32)OMX_StateLoaded) { 6717 ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)", 6718 asString((OMX_COMMANDTYPE)data1), data1, 6719 asString((OMX_STATETYPE)data2), data2); 6720 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6721 return true; 6722 } 6723 6724 mCodec->changeState(mCodec->mLoadedState); 6725 6726 return true; 6727 } 6728 6729 default: 6730 return BaseState::onOMXEvent(event, data1, data2); 6731 } 6732} 6733 6734//////////////////////////////////////////////////////////////////////////////// 6735 6736ACodec::FlushingState::FlushingState(ACodec *codec) 6737 : BaseState(codec) { 6738} 6739 6740void ACodec::FlushingState::stateEntered() { 6741 ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 6742 6743 mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 6744} 6745 6746bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 6747 bool handled = false; 6748 6749 switch (msg->what()) { 6750 case kWhatShutdown: 6751 { 6752 mCodec->deferMessage(msg); 6753 break; 6754 } 6755 6756 case kWhatFlush: 6757 { 6758 // We're already doing this right now. 6759 handled = true; 6760 break; 6761 } 6762 6763 default: 6764 handled = BaseState::onMessageReceived(msg); 6765 break; 6766 } 6767 6768 return handled; 6769} 6770 6771bool ACodec::FlushingState::onOMXEvent( 6772 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6773 ALOGV("[%s] FlushingState onOMXEvent(%u,%d)", 6774 mCodec->mComponentName.c_str(), event, (OMX_S32)data1); 6775 6776 switch (event) { 6777 case OMX_EventCmdComplete: 6778 { 6779 if (data1 != (OMX_U32)OMX_CommandFlush) { 6780 ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState", 6781 asString((OMX_COMMANDTYPE)data1), data1, data2); 6782 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6783 return true; 6784 } 6785 6786 if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 6787 if (mFlushComplete[data2]) { 6788 ALOGW("Flush already completed for %s port", 6789 data2 == kPortIndexInput ? "input" : "output"); 6790 return true; 6791 } 6792 mFlushComplete[data2] = true; 6793 6794 if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) { 6795 changeStateIfWeOwnAllBuffers(); 6796 } 6797 } else if (data2 == OMX_ALL) { 6798 if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) { 6799 ALOGW("received flush complete event for OMX_ALL before ports have been" 6800 "flushed (%d/%d)", 6801 mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]); 6802 return false; 6803 } 6804 6805 changeStateIfWeOwnAllBuffers(); 6806 } else { 6807 ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2); 6808 } 6809 6810 return true; 6811 } 6812 6813 case OMX_EventPortSettingsChanged: 6814 { 6815 sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec); 6816 msg->setInt32("type", omx_message::EVENT); 6817 msg->setInt32("node", mCodec->mNode); 6818 msg->setInt32("event", event); 6819 msg->setInt32("data1", data1); 6820 msg->setInt32("data2", data2); 6821 6822 ALOGV("[%s] Deferring OMX_EventPortSettingsChanged", 6823 mCodec->mComponentName.c_str()); 6824 6825 mCodec->deferMessage(msg); 6826 6827 return true; 6828 } 6829 6830 default: 6831 return BaseState::onOMXEvent(event, data1, data2); 6832 } 6833 6834 return true; 6835} 6836 6837void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 6838 BaseState::onOutputBufferDrained(msg); 6839 6840 changeStateIfWeOwnAllBuffers(); 6841} 6842 6843void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 6844 BaseState::onInputBufferFilled(msg); 6845 6846 changeStateIfWeOwnAllBuffers(); 6847} 6848 6849void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 6850 if (mFlushComplete[kPortIndexInput] 6851 && mFlushComplete[kPortIndexOutput] 6852 && mCodec->allYourBuffersAreBelongToUs()) { 6853 // We now own all buffers except possibly those still queued with 6854 // the native window for rendering. Let's get those back as well. 6855 mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs(); 6856 6857 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 6858 6859 sp<AMessage> notify = mCodec->mNotify->dup(); 6860 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 6861 notify->post(); 6862 6863 mCodec->mPortEOS[kPortIndexInput] = 6864 mCodec->mPortEOS[kPortIndexOutput] = false; 6865 6866 mCodec->mInputEOSResult = OK; 6867 6868 if (mCodec->mSkipCutBuffer != NULL) { 6869 mCodec->mSkipCutBuffer->clear(); 6870 } 6871 6872 mCodec->changeState(mCodec->mExecutingState); 6873 } 6874} 6875 6876} // namespace android 6877