ACodec.cpp revision 86b997dcf1101cdd259460fb4f82204200a9a993
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "ACodec" 19 20#ifdef __LP64__ 21#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 22#endif 23 24#include <inttypes.h> 25#include <utils/Trace.h> 26 27#include <gui/Surface.h> 28 29#include <media/stagefright/ACodec.h> 30 31#include <binder/MemoryDealer.h> 32 33#include <media/stagefright/foundation/hexdump.h> 34#include <media/stagefright/foundation/ABuffer.h> 35#include <media/stagefright/foundation/ADebug.h> 36#include <media/stagefright/foundation/AMessage.h> 37#include <media/stagefright/foundation/AUtils.h> 38 39#include <media/stagefright/BufferProducerWrapper.h> 40#include <media/stagefright/MediaCodec.h> 41#include <media/stagefright/MediaCodecList.h> 42#include <media/stagefright/MediaDefs.h> 43#include <media/stagefright/OMXClient.h> 44#include <media/stagefright/OMXCodec.h> 45#include <media/stagefright/PersistentSurface.h> 46#include <media/stagefright/SurfaceUtils.h> 47#include <media/hardware/HardwareAPI.h> 48 49#include <OMX_AudioExt.h> 50#include <OMX_VideoExt.h> 51#include <OMX_Component.h> 52#include <OMX_IndexExt.h> 53#include <OMX_AsString.h> 54 55#include "include/avc_utils.h" 56 57namespace android { 58 59// OMX errors are directly mapped into status_t range if 60// there is no corresponding MediaError status code. 61// Use the statusFromOMXError(int32_t omxError) function. 62// 63// Currently this is a direct map. 64// See frameworks/native/include/media/openmax/OMX_Core.h 65// 66// Vendor OMX errors from 0x90000000 - 0x9000FFFF 67// Extension OMX errors from 0x8F000000 - 0x90000000 68// Standard OMX errors from 0x80001000 - 0x80001024 (0x80001024 current) 69// 70 71// returns true if err is a recognized OMX error code. 72// as OMX error is OMX_S32, this is an int32_t type 73static inline bool isOMXError(int32_t err) { 74 return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX); 75} 76 77// converts an OMX error to a status_t 78static inline status_t statusFromOMXError(int32_t omxError) { 79 switch (omxError) { 80 case OMX_ErrorInvalidComponentName: 81 case OMX_ErrorComponentNotFound: 82 return NAME_NOT_FOUND; // can trigger illegal argument error for provided names. 83 default: 84 return isOMXError(omxError) ? omxError : 0; // no translation required 85 } 86} 87 88// checks and converts status_t to a non-side-effect status_t 89static inline status_t makeNoSideEffectStatus(status_t err) { 90 switch (err) { 91 // the following errors have side effects and may come 92 // from other code modules. Remap for safety reasons. 93 case INVALID_OPERATION: 94 case DEAD_OBJECT: 95 return UNKNOWN_ERROR; 96 default: 97 return err; 98 } 99} 100 101template<class T> 102static void InitOMXParams(T *params) { 103 params->nSize = sizeof(T); 104 params->nVersion.s.nVersionMajor = 1; 105 params->nVersion.s.nVersionMinor = 0; 106 params->nVersion.s.nRevision = 0; 107 params->nVersion.s.nStep = 0; 108} 109 110struct MessageList : public RefBase { 111 MessageList() { 112 } 113 virtual ~MessageList() { 114 } 115 std::list<sp<AMessage> > &getList() { return mList; } 116private: 117 std::list<sp<AMessage> > mList; 118 119 DISALLOW_EVIL_CONSTRUCTORS(MessageList); 120}; 121 122struct CodecObserver : public BnOMXObserver { 123 CodecObserver() {} 124 125 void setNotificationMessage(const sp<AMessage> &msg) { 126 mNotify = msg; 127 } 128 129 // from IOMXObserver 130 virtual void onMessages(const std::list<omx_message> &messages) { 131 if (messages.empty()) { 132 return; 133 } 134 135 sp<AMessage> notify = mNotify->dup(); 136 bool first = true; 137 sp<MessageList> msgList = new MessageList(); 138 for (std::list<omx_message>::const_iterator it = messages.cbegin(); 139 it != messages.cend(); ++it) { 140 const omx_message &omx_msg = *it; 141 if (first) { 142 notify->setInt32("node", omx_msg.node); 143 first = false; 144 } 145 146 sp<AMessage> msg = new AMessage; 147 msg->setInt32("type", omx_msg.type); 148 switch (omx_msg.type) { 149 case omx_message::EVENT: 150 { 151 msg->setInt32("event", omx_msg.u.event_data.event); 152 msg->setInt32("data1", omx_msg.u.event_data.data1); 153 msg->setInt32("data2", omx_msg.u.event_data.data2); 154 break; 155 } 156 157 case omx_message::EMPTY_BUFFER_DONE: 158 { 159 msg->setInt32("buffer", omx_msg.u.buffer_data.buffer); 160 msg->setInt32("fence_fd", omx_msg.fenceFd); 161 break; 162 } 163 164 case omx_message::FILL_BUFFER_DONE: 165 { 166 msg->setInt32( 167 "buffer", omx_msg.u.extended_buffer_data.buffer); 168 msg->setInt32( 169 "range_offset", 170 omx_msg.u.extended_buffer_data.range_offset); 171 msg->setInt32( 172 "range_length", 173 omx_msg.u.extended_buffer_data.range_length); 174 msg->setInt32( 175 "flags", 176 omx_msg.u.extended_buffer_data.flags); 177 msg->setInt64( 178 "timestamp", 179 omx_msg.u.extended_buffer_data.timestamp); 180 msg->setInt32( 181 "fence_fd", omx_msg.fenceFd); 182 break; 183 } 184 185 case omx_message::FRAME_RENDERED: 186 { 187 msg->setInt64( 188 "media_time_us", omx_msg.u.render_data.timestamp); 189 msg->setInt64( 190 "system_nano", omx_msg.u.render_data.nanoTime); 191 break; 192 } 193 194 default: 195 ALOGE("Unrecognized message type: %d", omx_msg.type); 196 break; 197 } 198 msgList->getList().push_back(msg); 199 } 200 notify->setObject("messages", msgList); 201 notify->post(); 202 } 203 204protected: 205 virtual ~CodecObserver() {} 206 207private: 208 sp<AMessage> mNotify; 209 210 DISALLOW_EVIL_CONSTRUCTORS(CodecObserver); 211}; 212 213//////////////////////////////////////////////////////////////////////////////// 214 215struct ACodec::BaseState : public AState { 216 BaseState(ACodec *codec, const sp<AState> &parentState = NULL); 217 218protected: 219 enum PortMode { 220 KEEP_BUFFERS, 221 RESUBMIT_BUFFERS, 222 FREE_BUFFERS, 223 }; 224 225 ACodec *mCodec; 226 227 virtual PortMode getPortMode(OMX_U32 portIndex); 228 229 virtual bool onMessageReceived(const sp<AMessage> &msg); 230 231 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 232 233 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 234 virtual void onInputBufferFilled(const sp<AMessage> &msg); 235 236 void postFillThisBuffer(BufferInfo *info); 237 238private: 239 // Handles an OMX message. Returns true iff message was handled. 240 bool onOMXMessage(const sp<AMessage> &msg); 241 242 // Handles a list of messages. Returns true iff messages were handled. 243 bool onOMXMessageList(const sp<AMessage> &msg); 244 245 // returns true iff this message is for this component and the component is alive 246 bool checkOMXMessage(const sp<AMessage> &msg); 247 248 bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd); 249 250 bool onOMXFillBufferDone( 251 IOMX::buffer_id bufferID, 252 size_t rangeOffset, size_t rangeLength, 253 OMX_U32 flags, 254 int64_t timeUs, 255 int fenceFd); 256 257 virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); 258 259 void getMoreInputDataIfPossible(); 260 261 DISALLOW_EVIL_CONSTRUCTORS(BaseState); 262}; 263 264//////////////////////////////////////////////////////////////////////////////// 265 266struct ACodec::DeathNotifier : public IBinder::DeathRecipient { 267 DeathNotifier(const sp<AMessage> ¬ify) 268 : mNotify(notify) { 269 } 270 271 virtual void binderDied(const wp<IBinder> &) { 272 mNotify->post(); 273 } 274 275protected: 276 virtual ~DeathNotifier() {} 277 278private: 279 sp<AMessage> mNotify; 280 281 DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier); 282}; 283 284struct ACodec::UninitializedState : public ACodec::BaseState { 285 UninitializedState(ACodec *codec); 286 287protected: 288 virtual bool onMessageReceived(const sp<AMessage> &msg); 289 virtual void stateEntered(); 290 291private: 292 void onSetup(const sp<AMessage> &msg); 293 bool onAllocateComponent(const sp<AMessage> &msg); 294 295 sp<DeathNotifier> mDeathNotifier; 296 297 DISALLOW_EVIL_CONSTRUCTORS(UninitializedState); 298}; 299 300//////////////////////////////////////////////////////////////////////////////// 301 302struct ACodec::LoadedState : public ACodec::BaseState { 303 LoadedState(ACodec *codec); 304 305protected: 306 virtual bool onMessageReceived(const sp<AMessage> &msg); 307 virtual void stateEntered(); 308 309private: 310 friend struct ACodec::UninitializedState; 311 312 bool onConfigureComponent(const sp<AMessage> &msg); 313 void onCreateInputSurface(const sp<AMessage> &msg); 314 void onSetInputSurface(const sp<AMessage> &msg); 315 void onStart(); 316 void onShutdown(bool keepComponentAllocated); 317 318 status_t setupInputSurface(); 319 320 DISALLOW_EVIL_CONSTRUCTORS(LoadedState); 321}; 322 323//////////////////////////////////////////////////////////////////////////////// 324 325struct ACodec::LoadedToIdleState : public ACodec::BaseState { 326 LoadedToIdleState(ACodec *codec); 327 328protected: 329 virtual bool onMessageReceived(const sp<AMessage> &msg); 330 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 331 virtual void stateEntered(); 332 333private: 334 status_t allocateBuffers(); 335 336 DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState); 337}; 338 339//////////////////////////////////////////////////////////////////////////////// 340 341struct ACodec::IdleToExecutingState : public ACodec::BaseState { 342 IdleToExecutingState(ACodec *codec); 343 344protected: 345 virtual bool onMessageReceived(const sp<AMessage> &msg); 346 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 347 virtual void stateEntered(); 348 349private: 350 DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState); 351}; 352 353//////////////////////////////////////////////////////////////////////////////// 354 355struct ACodec::ExecutingState : public ACodec::BaseState { 356 ExecutingState(ACodec *codec); 357 358 void submitRegularOutputBuffers(); 359 void submitOutputMetaBuffers(); 360 void submitOutputBuffers(); 361 362 // Submit output buffers to the decoder, submit input buffers to client 363 // to fill with data. 364 void resume(); 365 366 // Returns true iff input and output buffers are in play. 367 bool active() const { return mActive; } 368 369protected: 370 virtual PortMode getPortMode(OMX_U32 portIndex); 371 virtual bool onMessageReceived(const sp<AMessage> &msg); 372 virtual void stateEntered(); 373 374 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 375 virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); 376 377private: 378 bool mActive; 379 380 DISALLOW_EVIL_CONSTRUCTORS(ExecutingState); 381}; 382 383//////////////////////////////////////////////////////////////////////////////// 384 385struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState { 386 OutputPortSettingsChangedState(ACodec *codec); 387 388protected: 389 virtual PortMode getPortMode(OMX_U32 portIndex); 390 virtual bool onMessageReceived(const sp<AMessage> &msg); 391 virtual void stateEntered(); 392 393 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 394 virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); 395 396private: 397 DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState); 398}; 399 400//////////////////////////////////////////////////////////////////////////////// 401 402struct ACodec::ExecutingToIdleState : public ACodec::BaseState { 403 ExecutingToIdleState(ACodec *codec); 404 405protected: 406 virtual bool onMessageReceived(const sp<AMessage> &msg); 407 virtual void stateEntered(); 408 409 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 410 411 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 412 virtual void onInputBufferFilled(const sp<AMessage> &msg); 413 414private: 415 void changeStateIfWeOwnAllBuffers(); 416 417 bool mComponentNowIdle; 418 419 DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState); 420}; 421 422//////////////////////////////////////////////////////////////////////////////// 423 424struct ACodec::IdleToLoadedState : public ACodec::BaseState { 425 IdleToLoadedState(ACodec *codec); 426 427protected: 428 virtual bool onMessageReceived(const sp<AMessage> &msg); 429 virtual void stateEntered(); 430 431 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 432 433private: 434 DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState); 435}; 436 437//////////////////////////////////////////////////////////////////////////////// 438 439struct ACodec::FlushingState : public ACodec::BaseState { 440 FlushingState(ACodec *codec); 441 442protected: 443 virtual bool onMessageReceived(const sp<AMessage> &msg); 444 virtual void stateEntered(); 445 446 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 447 448 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 449 virtual void onInputBufferFilled(const sp<AMessage> &msg); 450 451private: 452 bool mFlushComplete[2]; 453 454 void changeStateIfWeOwnAllBuffers(); 455 456 DISALLOW_EVIL_CONSTRUCTORS(FlushingState); 457}; 458 459//////////////////////////////////////////////////////////////////////////////// 460 461void ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) { 462 if (mFenceFd >= 0) { 463 ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s", 464 mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg); 465 } 466 mFenceFd = fenceFd; 467 mIsReadFence = false; 468} 469 470void ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) { 471 if (mFenceFd >= 0) { 472 ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s", 473 mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg); 474 } 475 mFenceFd = fenceFd; 476 mIsReadFence = true; 477} 478 479void ACodec::BufferInfo::checkWriteFence(const char *dbg) { 480 if (mFenceFd >= 0 && mIsReadFence) { 481 ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg); 482 } 483} 484 485void ACodec::BufferInfo::checkReadFence(const char *dbg) { 486 if (mFenceFd >= 0 && !mIsReadFence) { 487 ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg); 488 } 489} 490 491//////////////////////////////////////////////////////////////////////////////// 492 493ACodec::ACodec() 494 : mQuirks(0), 495 mNode(0), 496 mNativeWindowUsageBits(0), 497 mSentFormat(false), 498 mIsVideo(false), 499 mIsEncoder(false), 500 mFatalError(false), 501 mShutdownInProgress(false), 502 mExplicitShutdown(false), 503 mEncoderDelay(0), 504 mEncoderPadding(0), 505 mRotationDegrees(0), 506 mChannelMaskPresent(false), 507 mChannelMask(0), 508 mDequeueCounter(0), 509 mInputMetadataType(kMetadataBufferTypeInvalid), 510 mOutputMetadataType(kMetadataBufferTypeInvalid), 511 mLegacyAdaptiveExperiment(false), 512 mMetadataBuffersToSubmit(0), 513 mRepeatFrameDelayUs(-1ll), 514 mMaxPtsGapUs(-1ll), 515 mMaxFps(-1), 516 mTimePerFrameUs(-1ll), 517 mTimePerCaptureUs(-1ll), 518 mCreateInputBuffersSuspended(false), 519 mTunneled(false) { 520 mUninitializedState = new UninitializedState(this); 521 mLoadedState = new LoadedState(this); 522 mLoadedToIdleState = new LoadedToIdleState(this); 523 mIdleToExecutingState = new IdleToExecutingState(this); 524 mExecutingState = new ExecutingState(this); 525 526 mOutputPortSettingsChangedState = 527 new OutputPortSettingsChangedState(this); 528 529 mExecutingToIdleState = new ExecutingToIdleState(this); 530 mIdleToLoadedState = new IdleToLoadedState(this); 531 mFlushingState = new FlushingState(this); 532 533 mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false; 534 mInputEOSResult = OK; 535 536 changeState(mUninitializedState); 537} 538 539ACodec::~ACodec() { 540} 541 542void ACodec::setNotificationMessage(const sp<AMessage> &msg) { 543 mNotify = msg; 544} 545 546void ACodec::initiateSetup(const sp<AMessage> &msg) { 547 msg->setWhat(kWhatSetup); 548 msg->setTarget(this); 549 msg->post(); 550} 551 552void ACodec::signalSetParameters(const sp<AMessage> ¶ms) { 553 sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 554 msg->setMessage("params", params); 555 msg->post(); 556} 557 558void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) { 559 msg->setWhat(kWhatAllocateComponent); 560 msg->setTarget(this); 561 msg->post(); 562} 563 564void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) { 565 msg->setWhat(kWhatConfigureComponent); 566 msg->setTarget(this); 567 msg->post(); 568} 569 570status_t ACodec::setSurface(const sp<Surface> &surface) { 571 sp<AMessage> msg = new AMessage(kWhatSetSurface, this); 572 msg->setObject("surface", surface); 573 574 sp<AMessage> response; 575 status_t err = msg->postAndAwaitResponse(&response); 576 577 if (err == OK) { 578 (void)response->findInt32("err", &err); 579 } 580 return err; 581} 582 583void ACodec::initiateCreateInputSurface() { 584 (new AMessage(kWhatCreateInputSurface, this))->post(); 585} 586 587void ACodec::initiateSetInputSurface( 588 const sp<PersistentSurface> &surface) { 589 sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this); 590 msg->setObject("input-surface", surface); 591 msg->post(); 592} 593 594void ACodec::signalEndOfInputStream() { 595 (new AMessage(kWhatSignalEndOfInputStream, this))->post(); 596} 597 598void ACodec::initiateStart() { 599 (new AMessage(kWhatStart, this))->post(); 600} 601 602void ACodec::signalFlush() { 603 ALOGV("[%s] signalFlush", mComponentName.c_str()); 604 (new AMessage(kWhatFlush, this))->post(); 605} 606 607void ACodec::signalResume() { 608 (new AMessage(kWhatResume, this))->post(); 609} 610 611void ACodec::initiateShutdown(bool keepComponentAllocated) { 612 sp<AMessage> msg = new AMessage(kWhatShutdown, this); 613 msg->setInt32("keepComponentAllocated", keepComponentAllocated); 614 msg->post(); 615 if (!keepComponentAllocated) { 616 // ensure shutdown completes in 3 seconds 617 (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000); 618 } 619} 620 621void ACodec::signalRequestIDRFrame() { 622 (new AMessage(kWhatRequestIDRFrame, this))->post(); 623} 624 625// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 626// Some codecs may return input buffers before having them processed. 627// This causes a halt if we already signaled an EOS on the input 628// port. For now keep submitting an output buffer if there was an 629// EOS on the input port, but not yet on the output port. 630void ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() { 631 if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] && 632 mMetadataBuffersToSubmit > 0) { 633 (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post(); 634 } 635} 636 637status_t ACodec::handleSetSurface(const sp<Surface> &surface) { 638 // allow keeping unset surface 639 if (surface == NULL) { 640 if (mNativeWindow != NULL) { 641 ALOGW("cannot unset a surface"); 642 return INVALID_OPERATION; 643 } 644 return OK; 645 } 646 647 // cannot switch from bytebuffers to surface 648 if (mNativeWindow == NULL) { 649 ALOGW("component was not configured with a surface"); 650 return INVALID_OPERATION; 651 } 652 653 ANativeWindow *nativeWindow = surface.get(); 654 // if we have not yet started the codec, we can simply set the native window 655 if (mBuffers[kPortIndexInput].size() == 0) { 656 mNativeWindow = surface; 657 return OK; 658 } 659 660 // we do not support changing a tunneled surface after start 661 if (mTunneled) { 662 ALOGW("cannot change tunneled surface"); 663 return INVALID_OPERATION; 664 } 665 666 int usageBits = 0; 667 status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow, &usageBits); 668 if (err != OK) { 669 return err; 670 } 671 672 int ignoredFlags = kVideoGrallocUsage; 673 // New output surface is not allowed to add new usage flag except ignored ones. 674 if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) { 675 ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits); 676 return BAD_VALUE; 677 } 678 679 // get min undequeued count. We cannot switch to a surface that has a higher 680 // undequeued count than we allocated. 681 int minUndequeuedBuffers = 0; 682 err = nativeWindow->query( 683 nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 684 &minUndequeuedBuffers); 685 if (err != 0) { 686 ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 687 strerror(-err), -err); 688 return err; 689 } 690 if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) { 691 ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)", 692 minUndequeuedBuffers, mNumUndequeuedBuffers); 693 return BAD_VALUE; 694 } 695 696 // we cannot change the number of output buffers while OMX is running 697 // set up surface to the same count 698 Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput]; 699 ALOGV("setting up surface for %zu buffers", buffers.size()); 700 701 err = native_window_set_buffer_count(nativeWindow, buffers.size()); 702 if (err != 0) { 703 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 704 -err); 705 return err; 706 } 707 708 // need to enable allocation when attaching 709 surface->getIGraphicBufferProducer()->allowAllocation(true); 710 711 // for meta data mode, we move dequeud buffers to the new surface. 712 // for non-meta mode, we must move all registered buffers 713 for (size_t i = 0; i < buffers.size(); ++i) { 714 const BufferInfo &info = buffers[i]; 715 // skip undequeued buffers for meta data mode 716 if (storingMetadataInDecodedBuffers() 717 && !mLegacyAdaptiveExperiment 718 && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 719 ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer()); 720 continue; 721 } 722 ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer()); 723 724 err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer()); 725 if (err != OK) { 726 ALOGE("failed to attach buffer %p to the new surface: %s (%d)", 727 info.mGraphicBuffer->getNativeBuffer(), 728 strerror(-err), -err); 729 return err; 730 } 731 } 732 733 // cancel undequeued buffers to new surface 734 if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) { 735 for (size_t i = 0; i < buffers.size(); ++i) { 736 BufferInfo &info = buffers.editItemAt(i); 737 if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 738 ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer()); 739 err = nativeWindow->cancelBuffer( 740 nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd); 741 info.mFenceFd = -1; 742 if (err != OK) { 743 ALOGE("failed to cancel buffer %p to the new surface: %s (%d)", 744 info.mGraphicBuffer->getNativeBuffer(), 745 strerror(-err), -err); 746 return err; 747 } 748 } 749 } 750 // disallow further allocation 751 (void)surface->getIGraphicBufferProducer()->allowAllocation(false); 752 } 753 754 // push blank buffers to previous window if requested 755 if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) { 756 pushBlankBuffersToNativeWindow(mNativeWindow.get()); 757 } 758 759 mNativeWindow = nativeWindow; 760 mNativeWindowUsageBits = usageBits; 761 return OK; 762} 763 764status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) { 765 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 766 767 CHECK(mDealer[portIndex] == NULL); 768 CHECK(mBuffers[portIndex].isEmpty()); 769 770 status_t err; 771 if (mNativeWindow != NULL && portIndex == kPortIndexOutput) { 772 if (storingMetadataInDecodedBuffers()) { 773 err = allocateOutputMetadataBuffers(); 774 } else { 775 err = allocateOutputBuffersFromNativeWindow(); 776 } 777 } else { 778 OMX_PARAM_PORTDEFINITIONTYPE def; 779 InitOMXParams(&def); 780 def.nPortIndex = portIndex; 781 782 err = mOMX->getParameter( 783 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 784 785 if (err == OK) { 786 MetadataBufferType type = 787 portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType; 788 int32_t bufSize = def.nBufferSize; 789 if (type == kMetadataBufferTypeGrallocSource) { 790 bufSize = sizeof(VideoGrallocMetadata); 791 } else if (type == kMetadataBufferTypeANWBuffer) { 792 bufSize = sizeof(VideoNativeMetadata); 793 } 794 795 // If using gralloc or native source input metadata buffers, allocate largest 796 // metadata size as we prefer to generate native source metadata, but component 797 // may require gralloc source. For camera source, allocate at least enough 798 // size for native metadata buffers. 799 int32_t allottedSize = bufSize; 800 if (portIndex == kPortIndexInput && type >= kMetadataBufferTypeGrallocSource) { 801 bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata)); 802 } else if (portIndex == kPortIndexInput && type == kMetadataBufferTypeCameraSource) { 803 bufSize = max(bufSize, (int32_t)sizeof(VideoNativeMetadata)); 804 } 805 806 ALOGV("[%s] Allocating %u buffers of size %d/%d (from %u using %s) on %s port", 807 mComponentName.c_str(), 808 def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type), 809 portIndex == kPortIndexInput ? "input" : "output"); 810 811 if (bufSize == 0 || def.nBufferCountActual > SIZE_MAX / bufSize) { 812 ALOGE("b/22885421"); 813 return NO_MEMORY; 814 } 815 size_t totalSize = def.nBufferCountActual * bufSize; 816 mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec"); 817 818 for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) { 819 sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize); 820 if (mem == NULL || mem->pointer() == NULL) { 821 return NO_MEMORY; 822 } 823 824 BufferInfo info; 825 info.mStatus = BufferInfo::OWNED_BY_US; 826 info.mFenceFd = -1; 827 info.mRenderInfo = NULL; 828 829 uint32_t requiresAllocateBufferBit = 830 (portIndex == kPortIndexInput) 831 ? OMXCodec::kRequiresAllocateBufferOnInputPorts 832 : OMXCodec::kRequiresAllocateBufferOnOutputPorts; 833 834 if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) 835 || (portIndex == kPortIndexOutput && usingMetadataOnEncoderOutput())) { 836 mem.clear(); 837 838 void *ptr; 839 err = mOMX->allocateBuffer( 840 mNode, portIndex, bufSize, &info.mBufferID, 841 &ptr); 842 843 info.mData = new ABuffer(ptr, bufSize); 844 } else if (mQuirks & requiresAllocateBufferBit) { 845 err = mOMX->allocateBufferWithBackup( 846 mNode, portIndex, mem, &info.mBufferID, allottedSize); 847 } else { 848 err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID, allottedSize); 849 } 850 851 if (mem != NULL) { 852 info.mData = new ABuffer(mem->pointer(), bufSize); 853 if (type == kMetadataBufferTypeANWBuffer) { 854 ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1; 855 } 856 info.mMemRef = mem; 857 } 858 859 mBuffers[portIndex].push(info); 860 } 861 } 862 } 863 864 if (err != OK) { 865 return err; 866 } 867 868 sp<AMessage> notify = mNotify->dup(); 869 notify->setInt32("what", CodecBase::kWhatBuffersAllocated); 870 871 notify->setInt32("portIndex", portIndex); 872 873 sp<PortDescription> desc = new PortDescription; 874 875 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 876 const BufferInfo &info = mBuffers[portIndex][i]; 877 desc->addBuffer(info.mBufferID, info.mData, info.mMemRef); 878 } 879 880 notify->setObject("portDesc", desc); 881 notify->post(); 882 883 return OK; 884} 885 886status_t ACodec::setupNativeWindowSizeFormatAndUsage( 887 ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */) { 888 OMX_PARAM_PORTDEFINITIONTYPE def; 889 InitOMXParams(&def); 890 def.nPortIndex = kPortIndexOutput; 891 892 status_t err = mOMX->getParameter( 893 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 894 895 if (err != OK) { 896 return err; 897 } 898 899 OMX_U32 usage = 0; 900 err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage); 901 if (err != 0) { 902 ALOGW("querying usage flags from OMX IL component failed: %d", err); 903 // XXX: Currently this error is logged, but not fatal. 904 usage = 0; 905 } 906 int omxUsage = usage; 907 908 if (mFlags & kFlagIsGrallocUsageProtected) { 909 usage |= GRALLOC_USAGE_PROTECTED; 910 } 911 912 usage |= kVideoGrallocUsage; 913 *finalUsage = usage; 914 915 ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage); 916 return setNativeWindowSizeFormatAndUsage( 917 nativeWindow, 918 def.format.video.nFrameWidth, 919 def.format.video.nFrameHeight, 920 def.format.video.eColorFormat, 921 mRotationDegrees, 922 usage); 923} 924 925status_t ACodec::configureOutputBuffersFromNativeWindow( 926 OMX_U32 *bufferCount, OMX_U32 *bufferSize, 927 OMX_U32 *minUndequeuedBuffers) { 928 OMX_PARAM_PORTDEFINITIONTYPE def; 929 InitOMXParams(&def); 930 def.nPortIndex = kPortIndexOutput; 931 932 status_t err = mOMX->getParameter( 933 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 934 935 if (err == OK) { 936 err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get(), &mNativeWindowUsageBits); 937 } 938 if (err != OK) { 939 mNativeWindowUsageBits = 0; 940 return err; 941 } 942 943 // Exits here for tunneled video playback codecs -- i.e. skips native window 944 // buffer allocation step as this is managed by the tunneled OMX omponent 945 // itself and explicitly sets def.nBufferCountActual to 0. 946 if (mTunneled) { 947 ALOGV("Tunneled Playback: skipping native window buffer allocation."); 948 def.nBufferCountActual = 0; 949 err = mOMX->setParameter( 950 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 951 952 *minUndequeuedBuffers = 0; 953 *bufferCount = 0; 954 *bufferSize = 0; 955 return err; 956 } 957 958 *minUndequeuedBuffers = 0; 959 err = mNativeWindow->query( 960 mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 961 (int *)minUndequeuedBuffers); 962 963 if (err != 0) { 964 ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 965 strerror(-err), -err); 966 return err; 967 } 968 969 // FIXME: assume that surface is controlled by app (native window 970 // returns the number for the case when surface is not controlled by app) 971 // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported 972 // For now, try to allocate 1 more buffer, but don't fail if unsuccessful 973 974 // Use conservative allocation while also trying to reduce starvation 975 // 976 // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the 977 // minimum needed for the consumer to be able to work 978 // 2. try to allocate two (2) additional buffers to reduce starvation from 979 // the consumer 980 // plus an extra buffer to account for incorrect minUndequeuedBufs 981 for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) { 982 OMX_U32 newBufferCount = 983 def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers; 984 def.nBufferCountActual = newBufferCount; 985 err = mOMX->setParameter( 986 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 987 988 if (err == OK) { 989 *minUndequeuedBuffers += extraBuffers; 990 break; 991 } 992 993 ALOGW("[%s] setting nBufferCountActual to %u failed: %d", 994 mComponentName.c_str(), newBufferCount, err); 995 /* exit condition */ 996 if (extraBuffers == 0) { 997 return err; 998 } 999 } 1000 1001 err = native_window_set_buffer_count( 1002 mNativeWindow.get(), def.nBufferCountActual); 1003 1004 if (err != 0) { 1005 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 1006 -err); 1007 return err; 1008 } 1009 1010 *bufferCount = def.nBufferCountActual; 1011 *bufferSize = def.nBufferSize; 1012 return err; 1013} 1014 1015status_t ACodec::allocateOutputBuffersFromNativeWindow() { 1016 OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers; 1017 status_t err = configureOutputBuffersFromNativeWindow( 1018 &bufferCount, &bufferSize, &minUndequeuedBuffers); 1019 if (err != 0) 1020 return err; 1021 mNumUndequeuedBuffers = minUndequeuedBuffers; 1022 1023 if (!storingMetadataInDecodedBuffers()) { 1024 static_cast<Surface*>(mNativeWindow.get()) 1025 ->getIGraphicBufferProducer()->allowAllocation(true); 1026 } 1027 1028 ALOGV("[%s] Allocating %u buffers from a native window of size %u on " 1029 "output port", 1030 mComponentName.c_str(), bufferCount, bufferSize); 1031 1032 // Dequeue buffers and send them to OMX 1033 for (OMX_U32 i = 0; i < bufferCount; i++) { 1034 ANativeWindowBuffer *buf; 1035 int fenceFd; 1036 err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd); 1037 if (err != 0) { 1038 ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 1039 break; 1040 } 1041 1042 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 1043 BufferInfo info; 1044 info.mStatus = BufferInfo::OWNED_BY_US; 1045 info.mFenceFd = fenceFd; 1046 info.mIsReadFence = false; 1047 info.mRenderInfo = NULL; 1048 info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */); 1049 info.mGraphicBuffer = graphicBuffer; 1050 mBuffers[kPortIndexOutput].push(info); 1051 1052 IOMX::buffer_id bufferId; 1053 err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer, 1054 &bufferId); 1055 if (err != 0) { 1056 ALOGE("registering GraphicBuffer %u with OMX IL component failed: " 1057 "%d", i, err); 1058 break; 1059 } 1060 1061 mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId; 1062 1063 ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)", 1064 mComponentName.c_str(), 1065 bufferId, graphicBuffer.get()); 1066 } 1067 1068 OMX_U32 cancelStart; 1069 OMX_U32 cancelEnd; 1070 1071 if (err != 0) { 1072 // If an error occurred while dequeuing we need to cancel any buffers 1073 // that were dequeued. 1074 cancelStart = 0; 1075 cancelEnd = mBuffers[kPortIndexOutput].size(); 1076 } else { 1077 // Return the required minimum undequeued buffers to the native window. 1078 cancelStart = bufferCount - minUndequeuedBuffers; 1079 cancelEnd = bufferCount; 1080 } 1081 1082 for (OMX_U32 i = cancelStart; i < cancelEnd; i++) { 1083 BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 1084 if (info->mStatus == BufferInfo::OWNED_BY_US) { 1085 status_t error = cancelBufferToNativeWindow(info); 1086 if (err == 0) { 1087 err = error; 1088 } 1089 } 1090 } 1091 1092 if (!storingMetadataInDecodedBuffers()) { 1093 static_cast<Surface*>(mNativeWindow.get()) 1094 ->getIGraphicBufferProducer()->allowAllocation(false); 1095 } 1096 1097 return err; 1098} 1099 1100status_t ACodec::allocateOutputMetadataBuffers() { 1101 OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers; 1102 status_t err = configureOutputBuffersFromNativeWindow( 1103 &bufferCount, &bufferSize, &minUndequeuedBuffers); 1104 if (err != 0) 1105 return err; 1106 mNumUndequeuedBuffers = minUndequeuedBuffers; 1107 1108 ALOGV("[%s] Allocating %u meta buffers on output port", 1109 mComponentName.c_str(), bufferCount); 1110 1111 size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ? 1112 sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata); 1113 size_t totalSize = bufferCount * bufSize; 1114 mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec"); 1115 1116 // Dequeue buffers and send them to OMX 1117 for (OMX_U32 i = 0; i < bufferCount; i++) { 1118 BufferInfo info; 1119 info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 1120 info.mFenceFd = -1; 1121 info.mRenderInfo = NULL; 1122 info.mGraphicBuffer = NULL; 1123 info.mDequeuedAt = mDequeueCounter; 1124 1125 sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize); 1126 if (mem == NULL || mem->pointer() == NULL) { 1127 return NO_MEMORY; 1128 } 1129 if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) { 1130 ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1; 1131 } 1132 info.mData = new ABuffer(mem->pointer(), mem->size()); 1133 1134 // we use useBuffer for metadata regardless of quirks 1135 err = mOMX->useBuffer( 1136 mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size()); 1137 info.mMemRef = mem; 1138 mBuffers[kPortIndexOutput].push(info); 1139 1140 ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)", 1141 mComponentName.c_str(), info.mBufferID, mem->pointer()); 1142 } 1143 1144 if (mLegacyAdaptiveExperiment) { 1145 // preallocate and preregister buffers 1146 static_cast<Surface *>(mNativeWindow.get()) 1147 ->getIGraphicBufferProducer()->allowAllocation(true); 1148 1149 ALOGV("[%s] Allocating %u buffers from a native window of size %u on " 1150 "output port", 1151 mComponentName.c_str(), bufferCount, bufferSize); 1152 1153 // Dequeue buffers then cancel them all 1154 for (OMX_U32 i = 0; i < bufferCount; i++) { 1155 BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 1156 1157 ANativeWindowBuffer *buf; 1158 int fenceFd; 1159 err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd); 1160 if (err != 0) { 1161 ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 1162 break; 1163 } 1164 1165 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 1166 mOMX->updateGraphicBufferInMeta( 1167 mNode, kPortIndexOutput, graphicBuffer, info->mBufferID); 1168 info->mStatus = BufferInfo::OWNED_BY_US; 1169 info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy"); 1170 info->mGraphicBuffer = graphicBuffer; 1171 } 1172 1173 for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) { 1174 BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 1175 if (info->mStatus == BufferInfo::OWNED_BY_US) { 1176 status_t error = cancelBufferToNativeWindow(info); 1177 if (err == OK) { 1178 err = error; 1179 } 1180 } 1181 } 1182 1183 static_cast<Surface*>(mNativeWindow.get()) 1184 ->getIGraphicBufferProducer()->allowAllocation(false); 1185 } 1186 1187 mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers; 1188 return err; 1189} 1190 1191status_t ACodec::submitOutputMetadataBuffer() { 1192 CHECK(storingMetadataInDecodedBuffers()); 1193 if (mMetadataBuffersToSubmit == 0) 1194 return OK; 1195 1196 BufferInfo *info = dequeueBufferFromNativeWindow(); 1197 if (info == NULL) { 1198 return ERROR_IO; 1199 } 1200 1201 ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p", 1202 mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get()); 1203 1204 --mMetadataBuffersToSubmit; 1205 info->checkWriteFence("submitOutputMetadataBuffer"); 1206 status_t err = mOMX->fillBuffer(mNode, info->mBufferID, info->mFenceFd); 1207 info->mFenceFd = -1; 1208 if (err == OK) { 1209 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 1210 } 1211 1212 return err; 1213} 1214 1215status_t ACodec::waitForFence(int fd, const char *dbg ) { 1216 status_t res = OK; 1217 if (fd >= 0) { 1218 sp<Fence> fence = new Fence(fd); 1219 res = fence->wait(IOMX::kFenceTimeoutMs); 1220 ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg); 1221 } 1222 return res; 1223} 1224 1225// static 1226const char *ACodec::_asString(BufferInfo::Status s) { 1227 switch (s) { 1228 case BufferInfo::OWNED_BY_US: return "OUR"; 1229 case BufferInfo::OWNED_BY_COMPONENT: return "COMPONENT"; 1230 case BufferInfo::OWNED_BY_UPSTREAM: return "UPSTREAM"; 1231 case BufferInfo::OWNED_BY_DOWNSTREAM: return "DOWNSTREAM"; 1232 case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE"; 1233 case BufferInfo::UNRECOGNIZED: return "UNRECOGNIZED"; 1234 default: return "?"; 1235 } 1236} 1237 1238void ACodec::dumpBuffers(OMX_U32 portIndex) { 1239 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1240 ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(), 1241 portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size()); 1242 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 1243 const BufferInfo &info = mBuffers[portIndex][i]; 1244 ALOGI(" slot %2zu: #%8u %p/%p %s(%d) dequeued:%u", 1245 i, info.mBufferID, info.mGraphicBuffer.get(), 1246 info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(), 1247 _asString(info.mStatus), info.mStatus, info.mDequeuedAt); 1248 } 1249} 1250 1251status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) { 1252 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 1253 1254 ALOGV("[%s] Calling cancelBuffer on buffer %u", 1255 mComponentName.c_str(), info->mBufferID); 1256 1257 info->checkWriteFence("cancelBufferToNativeWindow"); 1258 int err = mNativeWindow->cancelBuffer( 1259 mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd); 1260 info->mFenceFd = -1; 1261 1262 ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window", 1263 mComponentName.c_str(), info->mBufferID); 1264 // change ownership even if cancelBuffer fails 1265 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 1266 1267 return err; 1268} 1269 1270void ACodec::updateRenderInfoForDequeuedBuffer( 1271 ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) { 1272 1273 info->mRenderInfo = 1274 mRenderTracker.updateInfoForDequeuedBuffer( 1275 buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]); 1276 1277 // check for any fences already signaled 1278 notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo); 1279} 1280 1281void ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { 1282 if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) { 1283 mRenderTracker.dumpRenderQueue(); 1284 } 1285} 1286 1287void ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) { 1288 sp<AMessage> msg = mNotify->dup(); 1289 msg->setInt32("what", CodecBase::kWhatOutputFramesRendered); 1290 std::list<FrameRenderTracker::Info> done = 1291 mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete); 1292 1293 // unlink untracked frames 1294 for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin(); 1295 it != done.cend(); ++it) { 1296 ssize_t index = it->getIndex(); 1297 if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) { 1298 mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL; 1299 } else if (index >= 0) { 1300 // THIS SHOULD NEVER HAPPEN 1301 ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size()); 1302 } 1303 } 1304 1305 if (MediaCodec::CreateFramesRenderedMessage(done, msg)) { 1306 msg->post(); 1307 } 1308} 1309 1310ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() { 1311 ANativeWindowBuffer *buf; 1312 CHECK(mNativeWindow.get() != NULL); 1313 1314 if (mTunneled) { 1315 ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel" 1316 " video playback mode mode!"); 1317 return NULL; 1318 } 1319 1320 if (mFatalError) { 1321 ALOGW("not dequeuing from native window due to fatal error"); 1322 return NULL; 1323 } 1324 1325 int fenceFd = -1; 1326 do { 1327 status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd); 1328 if (err != 0) { 1329 ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err); 1330 return NULL; 1331 } 1332 1333 bool stale = false; 1334 for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) { 1335 i--; 1336 BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 1337 1338 if (info->mGraphicBuffer != NULL && 1339 info->mGraphicBuffer->handle == buf->handle) { 1340 // Since consumers can attach buffers to BufferQueues, it is possible 1341 // that a known yet stale buffer can return from a surface that we 1342 // once used. We can simply ignore this as we have already dequeued 1343 // this buffer properly. NOTE: this does not eliminate all cases, 1344 // e.g. it is possible that we have queued the valid buffer to the 1345 // NW, and a stale copy of the same buffer gets dequeued - which will 1346 // be treated as the valid buffer by ACodec. 1347 if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 1348 ALOGI("dequeued stale buffer %p. discarding", buf); 1349 stale = true; 1350 break; 1351 } 1352 1353 ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer()); 1354 info->mStatus = BufferInfo::OWNED_BY_US; 1355 info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow"); 1356 updateRenderInfoForDequeuedBuffer(buf, fenceFd, info); 1357 return info; 1358 } 1359 } 1360 1361 // It is also possible to receive a previously unregistered buffer 1362 // in non-meta mode. These should be treated as stale buffers. The 1363 // same is possible in meta mode, in which case, it will be treated 1364 // as a normal buffer, which is not desirable. 1365 // TODO: fix this. 1366 if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) { 1367 ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf); 1368 stale = true; 1369 } 1370 if (stale) { 1371 // TODO: detach stale buffer, but there is no API yet to do it. 1372 buf = NULL; 1373 } 1374 } while (buf == NULL); 1375 1376 // get oldest undequeued buffer 1377 BufferInfo *oldest = NULL; 1378 for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) { 1379 i--; 1380 BufferInfo *info = 1381 &mBuffers[kPortIndexOutput].editItemAt(i); 1382 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW && 1383 (oldest == NULL || 1384 // avoid potential issues from counter rolling over 1385 mDequeueCounter - info->mDequeuedAt > 1386 mDequeueCounter - oldest->mDequeuedAt)) { 1387 oldest = info; 1388 } 1389 } 1390 1391 // it is impossible dequeue a buffer when there are no buffers with ANW 1392 CHECK(oldest != NULL); 1393 // it is impossible to dequeue an unknown buffer in non-meta mode, as the 1394 // while loop above does not complete 1395 CHECK(storingMetadataInDecodedBuffers()); 1396 1397 // discard buffer in LRU info and replace with new buffer 1398 oldest->mGraphicBuffer = new GraphicBuffer(buf, false); 1399 oldest->mStatus = BufferInfo::OWNED_BY_US; 1400 oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest"); 1401 mRenderTracker.untrackFrame(oldest->mRenderInfo); 1402 oldest->mRenderInfo = NULL; 1403 1404 mOMX->updateGraphicBufferInMeta( 1405 mNode, kPortIndexOutput, oldest->mGraphicBuffer, 1406 oldest->mBufferID); 1407 1408 if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) { 1409 VideoGrallocMetadata *grallocMeta = 1410 reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->base()); 1411 ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)", 1412 (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]), 1413 mDequeueCounter - oldest->mDequeuedAt, 1414 (void *)(uintptr_t)grallocMeta->pHandle, 1415 oldest->mGraphicBuffer->handle, oldest->mData->base()); 1416 } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) { 1417 VideoNativeMetadata *nativeMeta = 1418 reinterpret_cast<VideoNativeMetadata *>(oldest->mData->base()); 1419 ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)", 1420 (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]), 1421 mDequeueCounter - oldest->mDequeuedAt, 1422 (void *)(uintptr_t)nativeMeta->pBuffer, 1423 oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->base()); 1424 } 1425 1426 updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest); 1427 return oldest; 1428} 1429 1430status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) { 1431 status_t err = OK; 1432 for (size_t i = mBuffers[portIndex].size(); i > 0;) { 1433 i--; 1434 status_t err2 = freeBuffer(portIndex, i); 1435 if (err == OK) { 1436 err = err2; 1437 } 1438 } 1439 1440 // clear mDealer even on an error 1441 mDealer[portIndex].clear(); 1442 return err; 1443} 1444 1445status_t ACodec::freeOutputBuffersNotOwnedByComponent() { 1446 status_t err = OK; 1447 for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) { 1448 i--; 1449 BufferInfo *info = 1450 &mBuffers[kPortIndexOutput].editItemAt(i); 1451 1452 // At this time some buffers may still be with the component 1453 // or being drained. 1454 if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT && 1455 info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) { 1456 status_t err2 = freeBuffer(kPortIndexOutput, i); 1457 if (err == OK) { 1458 err = err2; 1459 } 1460 } 1461 } 1462 1463 return err; 1464} 1465 1466status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) { 1467 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 1468 status_t err = OK; 1469 1470 // there should not be any fences in the metadata 1471 MetadataBufferType type = 1472 portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType; 1473 if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL 1474 && info->mData->size() >= sizeof(VideoNativeMetadata)) { 1475 int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd; 1476 if (fenceFd >= 0) { 1477 ALOGW("unreleased fence (%d) in %s metadata buffer %zu", 1478 fenceFd, portIndex == kPortIndexInput ? "input" : "output", i); 1479 } 1480 } 1481 1482 switch (info->mStatus) { 1483 case BufferInfo::OWNED_BY_US: 1484 if (portIndex == kPortIndexOutput && mNativeWindow != NULL) { 1485 (void)cancelBufferToNativeWindow(info); 1486 } 1487 // fall through 1488 1489 case BufferInfo::OWNED_BY_NATIVE_WINDOW: 1490 err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID); 1491 break; 1492 1493 default: 1494 ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus); 1495 err = FAILED_TRANSACTION; 1496 break; 1497 } 1498 1499 if (info->mFenceFd >= 0) { 1500 ::close(info->mFenceFd); 1501 } 1502 1503 if (portIndex == kPortIndexOutput) { 1504 mRenderTracker.untrackFrame(info->mRenderInfo, i); 1505 info->mRenderInfo = NULL; 1506 } 1507 1508 // remove buffer even if mOMX->freeBuffer fails 1509 mBuffers[portIndex].removeAt(i); 1510 return err; 1511} 1512 1513ACodec::BufferInfo *ACodec::findBufferByID( 1514 uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) { 1515 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 1516 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 1517 1518 if (info->mBufferID == bufferID) { 1519 if (index != NULL) { 1520 *index = i; 1521 } 1522 return info; 1523 } 1524 } 1525 1526 ALOGE("Could not find buffer with ID %u", bufferID); 1527 return NULL; 1528} 1529 1530status_t ACodec::setComponentRole( 1531 bool isEncoder, const char *mime) { 1532 struct MimeToRole { 1533 const char *mime; 1534 const char *decoderRole; 1535 const char *encoderRole; 1536 }; 1537 1538 static const MimeToRole kMimeToRole[] = { 1539 { MEDIA_MIMETYPE_AUDIO_MPEG, 1540 "audio_decoder.mp3", "audio_encoder.mp3" }, 1541 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I, 1542 "audio_decoder.mp1", "audio_encoder.mp1" }, 1543 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II, 1544 "audio_decoder.mp2", "audio_encoder.mp2" }, 1545 { MEDIA_MIMETYPE_AUDIO_AMR_NB, 1546 "audio_decoder.amrnb", "audio_encoder.amrnb" }, 1547 { MEDIA_MIMETYPE_AUDIO_AMR_WB, 1548 "audio_decoder.amrwb", "audio_encoder.amrwb" }, 1549 { MEDIA_MIMETYPE_AUDIO_AAC, 1550 "audio_decoder.aac", "audio_encoder.aac" }, 1551 { MEDIA_MIMETYPE_AUDIO_VORBIS, 1552 "audio_decoder.vorbis", "audio_encoder.vorbis" }, 1553 { MEDIA_MIMETYPE_AUDIO_OPUS, 1554 "audio_decoder.opus", "audio_encoder.opus" }, 1555 { MEDIA_MIMETYPE_AUDIO_G711_MLAW, 1556 "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" }, 1557 { MEDIA_MIMETYPE_AUDIO_G711_ALAW, 1558 "audio_decoder.g711alaw", "audio_encoder.g711alaw" }, 1559 { MEDIA_MIMETYPE_VIDEO_AVC, 1560 "video_decoder.avc", "video_encoder.avc" }, 1561 { MEDIA_MIMETYPE_VIDEO_HEVC, 1562 "video_decoder.hevc", "video_encoder.hevc" }, 1563 { MEDIA_MIMETYPE_VIDEO_MPEG4, 1564 "video_decoder.mpeg4", "video_encoder.mpeg4" }, 1565 { MEDIA_MIMETYPE_VIDEO_H263, 1566 "video_decoder.h263", "video_encoder.h263" }, 1567 { MEDIA_MIMETYPE_VIDEO_VP8, 1568 "video_decoder.vp8", "video_encoder.vp8" }, 1569 { MEDIA_MIMETYPE_VIDEO_VP9, 1570 "video_decoder.vp9", "video_encoder.vp9" }, 1571 { MEDIA_MIMETYPE_AUDIO_RAW, 1572 "audio_decoder.raw", "audio_encoder.raw" }, 1573 { MEDIA_MIMETYPE_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 if (mSkipCutBuffer != NULL) { 4449 size_t prevbufsize = mSkipCutBuffer->size(); 4450 if (prevbufsize != 0) { 4451 ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize); 4452 } 4453 } 4454 mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount); 4455 } 4456 4457 notify->post(); 4458 4459 mSentFormat = true; 4460} 4461 4462void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) { 4463 sp<AMessage> notify = mNotify->dup(); 4464 notify->setInt32("what", CodecBase::kWhatError); 4465 ALOGE("signalError(omxError %#x, internalError %d)", error, internalError); 4466 4467 if (internalError == UNKNOWN_ERROR) { // find better error code 4468 const status_t omxStatus = statusFromOMXError(error); 4469 if (omxStatus != 0) { 4470 internalError = omxStatus; 4471 } else { 4472 ALOGW("Invalid OMX error %#x", error); 4473 } 4474 } 4475 4476 mFatalError = true; 4477 4478 notify->setInt32("err", internalError); 4479 notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error. 4480 notify->post(); 4481} 4482 4483//////////////////////////////////////////////////////////////////////////////// 4484 4485ACodec::PortDescription::PortDescription() { 4486} 4487 4488status_t ACodec::requestIDRFrame() { 4489 if (!mIsEncoder) { 4490 return ERROR_UNSUPPORTED; 4491 } 4492 4493 OMX_CONFIG_INTRAREFRESHVOPTYPE params; 4494 InitOMXParams(¶ms); 4495 4496 params.nPortIndex = kPortIndexOutput; 4497 params.IntraRefreshVOP = OMX_TRUE; 4498 4499 return mOMX->setConfig( 4500 mNode, 4501 OMX_IndexConfigVideoIntraVOPRefresh, 4502 ¶ms, 4503 sizeof(params)); 4504} 4505 4506void ACodec::PortDescription::addBuffer( 4507 IOMX::buffer_id id, const sp<ABuffer> &buffer, const sp<RefBase> &memRef) { 4508 mBufferIDs.push_back(id); 4509 mBuffers.push_back(buffer); 4510 mMemRefs.push_back(memRef); 4511} 4512 4513size_t ACodec::PortDescription::countBuffers() { 4514 return mBufferIDs.size(); 4515} 4516 4517IOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const { 4518 return mBufferIDs.itemAt(index); 4519} 4520 4521sp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const { 4522 return mBuffers.itemAt(index); 4523} 4524 4525sp<RefBase> ACodec::PortDescription::memRefAt(size_t index) const { 4526 return mMemRefs.itemAt(index); 4527} 4528 4529//////////////////////////////////////////////////////////////////////////////// 4530 4531ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState) 4532 : AState(parentState), 4533 mCodec(codec) { 4534} 4535 4536ACodec::BaseState::PortMode ACodec::BaseState::getPortMode( 4537 OMX_U32 /* portIndex */) { 4538 return KEEP_BUFFERS; 4539} 4540 4541bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { 4542 switch (msg->what()) { 4543 case kWhatInputBufferFilled: 4544 { 4545 onInputBufferFilled(msg); 4546 break; 4547 } 4548 4549 case kWhatOutputBufferDrained: 4550 { 4551 onOutputBufferDrained(msg); 4552 break; 4553 } 4554 4555 case ACodec::kWhatOMXMessageList: 4556 { 4557 return checkOMXMessage(msg) ? onOMXMessageList(msg) : true; 4558 } 4559 4560 case ACodec::kWhatOMXMessageItem: 4561 { 4562 // no need to check as we already did it for kWhatOMXMessageList 4563 return onOMXMessage(msg); 4564 } 4565 4566 case ACodec::kWhatOMXMessage: 4567 { 4568 return checkOMXMessage(msg) ? onOMXMessage(msg) : true; 4569 } 4570 4571 case ACodec::kWhatSetSurface: 4572 { 4573 sp<AReplyToken> replyID; 4574 CHECK(msg->senderAwaitsResponse(&replyID)); 4575 4576 sp<RefBase> obj; 4577 CHECK(msg->findObject("surface", &obj)); 4578 4579 status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get())); 4580 4581 sp<AMessage> response = new AMessage; 4582 response->setInt32("err", err); 4583 response->postReply(replyID); 4584 break; 4585 } 4586 4587 case ACodec::kWhatCreateInputSurface: 4588 case ACodec::kWhatSetInputSurface: 4589 case ACodec::kWhatSignalEndOfInputStream: 4590 { 4591 // This may result in an app illegal state exception. 4592 ALOGE("Message 0x%x was not handled", msg->what()); 4593 mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION); 4594 return true; 4595 } 4596 4597 case ACodec::kWhatOMXDied: 4598 { 4599 // This will result in kFlagSawMediaServerDie handling in MediaCodec. 4600 ALOGE("OMX/mediaserver died, signalling error!"); 4601 mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT); 4602 break; 4603 } 4604 4605 case ACodec::kWhatReleaseCodecInstance: 4606 { 4607 ALOGI("[%s] forcing the release of codec", 4608 mCodec->mComponentName.c_str()); 4609 status_t err = mCodec->mOMX->freeNode(mCodec->mNode); 4610 ALOGE_IF("[%s] failed to release codec instance: err=%d", 4611 mCodec->mComponentName.c_str(), err); 4612 sp<AMessage> notify = mCodec->mNotify->dup(); 4613 notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 4614 notify->post(); 4615 break; 4616 } 4617 4618 default: 4619 return false; 4620 } 4621 4622 return true; 4623} 4624 4625bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) { 4626 // there is a possibility that this is an outstanding message for a 4627 // codec that we have already destroyed 4628 if (mCodec->mNode == 0) { 4629 ALOGI("ignoring message as already freed component: %s", 4630 msg->debugString().c_str()); 4631 return false; 4632 } 4633 4634 IOMX::node_id nodeID; 4635 CHECK(msg->findInt32("node", (int32_t*)&nodeID)); 4636 if (nodeID != mCodec->mNode) { 4637 ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode); 4638 return false; 4639 } 4640 return true; 4641} 4642 4643bool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) { 4644 sp<RefBase> obj; 4645 CHECK(msg->findObject("messages", &obj)); 4646 sp<MessageList> msgList = static_cast<MessageList *>(obj.get()); 4647 4648 bool receivedRenderedEvents = false; 4649 for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin(); 4650 it != msgList->getList().cend(); ++it) { 4651 (*it)->setWhat(ACodec::kWhatOMXMessageItem); 4652 mCodec->handleMessage(*it); 4653 int32_t type; 4654 CHECK((*it)->findInt32("type", &type)); 4655 if (type == omx_message::FRAME_RENDERED) { 4656 receivedRenderedEvents = true; 4657 } 4658 } 4659 4660 if (receivedRenderedEvents) { 4661 // NOTE: all buffers are rendered in this case 4662 mCodec->notifyOfRenderedFrames(); 4663 } 4664 return true; 4665} 4666 4667bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { 4668 int32_t type; 4669 CHECK(msg->findInt32("type", &type)); 4670 4671 switch (type) { 4672 case omx_message::EVENT: 4673 { 4674 int32_t event, data1, data2; 4675 CHECK(msg->findInt32("event", &event)); 4676 CHECK(msg->findInt32("data1", &data1)); 4677 CHECK(msg->findInt32("data2", &data2)); 4678 4679 if (event == OMX_EventCmdComplete 4680 && data1 == OMX_CommandFlush 4681 && data2 == (int32_t)OMX_ALL) { 4682 // Use of this notification is not consistent across 4683 // implementations. We'll drop this notification and rely 4684 // on flush-complete notifications on the individual port 4685 // indices instead. 4686 4687 return true; 4688 } 4689 4690 return onOMXEvent( 4691 static_cast<OMX_EVENTTYPE>(event), 4692 static_cast<OMX_U32>(data1), 4693 static_cast<OMX_U32>(data2)); 4694 } 4695 4696 case omx_message::EMPTY_BUFFER_DONE: 4697 { 4698 IOMX::buffer_id bufferID; 4699 int32_t fenceFd; 4700 4701 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 4702 CHECK(msg->findInt32("fence_fd", &fenceFd)); 4703 4704 return onOMXEmptyBufferDone(bufferID, fenceFd); 4705 } 4706 4707 case omx_message::FILL_BUFFER_DONE: 4708 { 4709 IOMX::buffer_id bufferID; 4710 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 4711 4712 int32_t rangeOffset, rangeLength, flags, fenceFd; 4713 int64_t timeUs; 4714 4715 CHECK(msg->findInt32("range_offset", &rangeOffset)); 4716 CHECK(msg->findInt32("range_length", &rangeLength)); 4717 CHECK(msg->findInt32("flags", &flags)); 4718 CHECK(msg->findInt64("timestamp", &timeUs)); 4719 CHECK(msg->findInt32("fence_fd", &fenceFd)); 4720 4721 return onOMXFillBufferDone( 4722 bufferID, 4723 (size_t)rangeOffset, (size_t)rangeLength, 4724 (OMX_U32)flags, 4725 timeUs, 4726 fenceFd); 4727 } 4728 4729 case omx_message::FRAME_RENDERED: 4730 { 4731 int64_t mediaTimeUs, systemNano; 4732 4733 CHECK(msg->findInt64("media_time_us", &mediaTimeUs)); 4734 CHECK(msg->findInt64("system_nano", &systemNano)); 4735 4736 return onOMXFrameRendered( 4737 mediaTimeUs, systemNano); 4738 } 4739 4740 default: 4741 ALOGE("Unexpected message type: %d", type); 4742 return false; 4743 } 4744} 4745 4746bool ACodec::BaseState::onOMXFrameRendered( 4747 int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) { 4748 // ignore outside of Executing and PortSettingsChanged states 4749 return true; 4750} 4751 4752bool ACodec::BaseState::onOMXEvent( 4753 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4754 if (event != OMX_EventError) { 4755 ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)", 4756 mCodec->mComponentName.c_str(), event, data1, data2); 4757 4758 return false; 4759 } 4760 4761 ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1); 4762 4763 // verify OMX component sends back an error we expect. 4764 OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1; 4765 if (!isOMXError(omxError)) { 4766 ALOGW("Invalid OMX error %#x", omxError); 4767 omxError = OMX_ErrorUndefined; 4768 } 4769 mCodec->signalError(omxError); 4770 4771 return true; 4772} 4773 4774bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) { 4775 ALOGV("[%s] onOMXEmptyBufferDone %u", 4776 mCodec->mComponentName.c_str(), bufferID); 4777 4778 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 4779 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 4780 if (status != BufferInfo::OWNED_BY_COMPONENT) { 4781 ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 4782 mCodec->dumpBuffers(kPortIndexInput); 4783 if (fenceFd >= 0) { 4784 ::close(fenceFd); 4785 } 4786 return false; 4787 } 4788 info->mStatus = BufferInfo::OWNED_BY_US; 4789 4790 // input buffers cannot take fences, so wait for any fence now 4791 (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone"); 4792 fenceFd = -1; 4793 4794 // still save fence for completeness 4795 info->setWriteFence(fenceFd, "onOMXEmptyBufferDone"); 4796 4797 // We're in "store-metadata-in-buffers" mode, the underlying 4798 // OMX component had access to data that's implicitly refcounted 4799 // by this "MediaBuffer" object. Now that the OMX component has 4800 // told us that it's done with the input buffer, we can decrement 4801 // the mediaBuffer's reference count. 4802 info->mData->setMediaBufferBase(NULL); 4803 4804 PortMode mode = getPortMode(kPortIndexInput); 4805 4806 switch (mode) { 4807 case KEEP_BUFFERS: 4808 break; 4809 4810 case RESUBMIT_BUFFERS: 4811 postFillThisBuffer(info); 4812 break; 4813 4814 case FREE_BUFFERS: 4815 default: 4816 ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers"); 4817 return false; 4818 } 4819 4820 return true; 4821} 4822 4823void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) { 4824 if (mCodec->mPortEOS[kPortIndexInput]) { 4825 return; 4826 } 4827 4828 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 4829 4830 sp<AMessage> notify = mCodec->mNotify->dup(); 4831 notify->setInt32("what", CodecBase::kWhatFillThisBuffer); 4832 notify->setInt32("buffer-id", info->mBufferID); 4833 4834 info->mData->meta()->clear(); 4835 notify->setBuffer("buffer", info->mData); 4836 4837 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec); 4838 reply->setInt32("buffer-id", info->mBufferID); 4839 4840 notify->setMessage("reply", reply); 4841 4842 notify->post(); 4843 4844 info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 4845} 4846 4847void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { 4848 IOMX::buffer_id bufferID; 4849 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 4850 sp<ABuffer> buffer; 4851 int32_t err = OK; 4852 bool eos = false; 4853 PortMode mode = getPortMode(kPortIndexInput); 4854 4855 if (!msg->findBuffer("buffer", &buffer)) { 4856 /* these are unfilled buffers returned by client */ 4857 CHECK(msg->findInt32("err", &err)); 4858 4859 if (err == OK) { 4860 /* buffers with no errors are returned on MediaCodec.flush */ 4861 mode = KEEP_BUFFERS; 4862 } else { 4863 ALOGV("[%s] saw error %d instead of an input buffer", 4864 mCodec->mComponentName.c_str(), err); 4865 eos = true; 4866 } 4867 4868 buffer.clear(); 4869 } 4870 4871 int32_t tmp; 4872 if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) { 4873 eos = true; 4874 err = ERROR_END_OF_STREAM; 4875 } 4876 4877 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 4878 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 4879 if (status != BufferInfo::OWNED_BY_UPSTREAM) { 4880 ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID); 4881 mCodec->dumpBuffers(kPortIndexInput); 4882 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 4883 return; 4884 } 4885 4886 info->mStatus = BufferInfo::OWNED_BY_US; 4887 4888 switch (mode) { 4889 case KEEP_BUFFERS: 4890 { 4891 if (eos) { 4892 if (!mCodec->mPortEOS[kPortIndexInput]) { 4893 mCodec->mPortEOS[kPortIndexInput] = true; 4894 mCodec->mInputEOSResult = err; 4895 } 4896 } 4897 break; 4898 } 4899 4900 case RESUBMIT_BUFFERS: 4901 { 4902 if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) { 4903 // Do not send empty input buffer w/o EOS to the component. 4904 if (buffer->size() == 0 && !eos) { 4905 postFillThisBuffer(info); 4906 break; 4907 } 4908 4909 int64_t timeUs; 4910 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 4911 4912 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 4913 4914 int32_t isCSD; 4915 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) { 4916 flags |= OMX_BUFFERFLAG_CODECCONFIG; 4917 } 4918 4919 if (eos) { 4920 flags |= OMX_BUFFERFLAG_EOS; 4921 } 4922 4923 if (buffer != info->mData) { 4924 ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)", 4925 mCodec->mComponentName.c_str(), 4926 bufferID, 4927 buffer.get(), info->mData.get()); 4928 4929 if (buffer->size() > info->mData->capacity()) { 4930 ALOGE("data size (%zu) is greated than buffer capacity (%zu)", 4931 buffer->size(), // this is the data received 4932 info->mData->capacity()); // this is out buffer size 4933 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 4934 return; 4935 } 4936 memcpy(info->mData->data(), buffer->data(), buffer->size()); 4937 } 4938 4939 if (flags & OMX_BUFFERFLAG_CODECCONFIG) { 4940 ALOGV("[%s] calling emptyBuffer %u w/ codec specific data", 4941 mCodec->mComponentName.c_str(), bufferID); 4942 } else if (flags & OMX_BUFFERFLAG_EOS) { 4943 ALOGV("[%s] calling emptyBuffer %u w/ EOS", 4944 mCodec->mComponentName.c_str(), bufferID); 4945 } else { 4946#if TRACK_BUFFER_TIMING 4947 ALOGI("[%s] calling emptyBuffer %u w/ time %lld us", 4948 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 4949#else 4950 ALOGV("[%s] calling emptyBuffer %u w/ time %lld us", 4951 mCodec->mComponentName.c_str(), bufferID, (long long)timeUs); 4952#endif 4953 } 4954 4955#if TRACK_BUFFER_TIMING 4956 ACodec::BufferStats stats; 4957 stats.mEmptyBufferTimeUs = ALooper::GetNowUs(); 4958 stats.mFillBufferDoneTimeUs = -1ll; 4959 mCodec->mBufferStats.add(timeUs, stats); 4960#endif 4961 4962 if (mCodec->storingMetadataInDecodedBuffers()) { 4963 // try to submit an output buffer for each input buffer 4964 PortMode outputMode = getPortMode(kPortIndexOutput); 4965 4966 ALOGV("MetadataBuffersToSubmit=%u portMode=%s", 4967 mCodec->mMetadataBuffersToSubmit, 4968 (outputMode == FREE_BUFFERS ? "FREE" : 4969 outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT")); 4970 if (outputMode == RESUBMIT_BUFFERS) { 4971 mCodec->submitOutputMetadataBuffer(); 4972 } 4973 } 4974 info->checkReadFence("onInputBufferFilled"); 4975 status_t err2 = mCodec->mOMX->emptyBuffer( 4976 mCodec->mNode, 4977 bufferID, 4978 0, 4979 buffer->size(), 4980 flags, 4981 timeUs, 4982 info->mFenceFd); 4983 info->mFenceFd = -1; 4984 if (err2 != OK) { 4985 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 4986 return; 4987 } 4988 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 4989 4990 if (!eos && err == OK) { 4991 getMoreInputDataIfPossible(); 4992 } else { 4993 ALOGV("[%s] Signalled EOS (%d) on the input port", 4994 mCodec->mComponentName.c_str(), err); 4995 4996 mCodec->mPortEOS[kPortIndexInput] = true; 4997 mCodec->mInputEOSResult = err; 4998 } 4999 } else if (!mCodec->mPortEOS[kPortIndexInput]) { 5000 if (err != OK && err != ERROR_END_OF_STREAM) { 5001 ALOGV("[%s] Signalling EOS on the input port due to error %d", 5002 mCodec->mComponentName.c_str(), err); 5003 } else { 5004 ALOGV("[%s] Signalling EOS on the input port", 5005 mCodec->mComponentName.c_str()); 5006 } 5007 5008 ALOGV("[%s] calling emptyBuffer %u signalling EOS", 5009 mCodec->mComponentName.c_str(), bufferID); 5010 5011 info->checkReadFence("onInputBufferFilled"); 5012 status_t err2 = mCodec->mOMX->emptyBuffer( 5013 mCodec->mNode, 5014 bufferID, 5015 0, 5016 0, 5017 OMX_BUFFERFLAG_EOS, 5018 0, 5019 info->mFenceFd); 5020 info->mFenceFd = -1; 5021 if (err2 != OK) { 5022 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2)); 5023 return; 5024 } 5025 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5026 5027 mCodec->mPortEOS[kPortIndexInput] = true; 5028 mCodec->mInputEOSResult = err; 5029 } 5030 break; 5031 } 5032 5033 case FREE_BUFFERS: 5034 break; 5035 5036 default: 5037 ALOGE("invalid port mode: %d", mode); 5038 break; 5039 } 5040} 5041 5042void ACodec::BaseState::getMoreInputDataIfPossible() { 5043 if (mCodec->mPortEOS[kPortIndexInput]) { 5044 return; 5045 } 5046 5047 BufferInfo *eligible = NULL; 5048 5049 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 5050 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 5051 5052#if 0 5053 if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 5054 // There's already a "read" pending. 5055 return; 5056 } 5057#endif 5058 5059 if (info->mStatus == BufferInfo::OWNED_BY_US) { 5060 eligible = info; 5061 } 5062 } 5063 5064 if (eligible == NULL) { 5065 return; 5066 } 5067 5068 postFillThisBuffer(eligible); 5069} 5070 5071bool ACodec::BaseState::onOMXFillBufferDone( 5072 IOMX::buffer_id bufferID, 5073 size_t rangeOffset, size_t rangeLength, 5074 OMX_U32 flags, 5075 int64_t timeUs, 5076 int fenceFd) { 5077 ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x", 5078 mCodec->mComponentName.c_str(), bufferID, timeUs, flags); 5079 5080 ssize_t index; 5081 status_t err= OK; 5082 5083#if TRACK_BUFFER_TIMING 5084 index = mCodec->mBufferStats.indexOfKey(timeUs); 5085 if (index >= 0) { 5086 ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index); 5087 stats->mFillBufferDoneTimeUs = ALooper::GetNowUs(); 5088 5089 ALOGI("frame PTS %lld: %lld", 5090 timeUs, 5091 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs); 5092 5093 mCodec->mBufferStats.removeItemsAt(index); 5094 stats = NULL; 5095 } 5096#endif 5097 5098 BufferInfo *info = 5099 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 5100 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5101 if (status != BufferInfo::OWNED_BY_COMPONENT) { 5102 ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5103 mCodec->dumpBuffers(kPortIndexOutput); 5104 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5105 if (fenceFd >= 0) { 5106 ::close(fenceFd); 5107 } 5108 return true; 5109 } 5110 5111 info->mDequeuedAt = ++mCodec->mDequeueCounter; 5112 info->mStatus = BufferInfo::OWNED_BY_US; 5113 5114 if (info->mRenderInfo != NULL) { 5115 // The fence for an emptied buffer must have signaled, but there still could be queued 5116 // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these, 5117 // as we will soon requeue this buffer to the surface. While in theory we could still keep 5118 // track of buffers that are requeued to the surface, it is better to add support to the 5119 // buffer-queue to notify us of released buffers and their fences (in the future). 5120 mCodec->notifyOfRenderedFrames(true /* dropIncomplete */); 5121 } 5122 5123 // byte buffers cannot take fences, so wait for any fence now 5124 if (mCodec->mNativeWindow == NULL) { 5125 (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone"); 5126 fenceFd = -1; 5127 } 5128 info->setReadFence(fenceFd, "onOMXFillBufferDone"); 5129 5130 PortMode mode = getPortMode(kPortIndexOutput); 5131 5132 switch (mode) { 5133 case KEEP_BUFFERS: 5134 break; 5135 5136 case RESUBMIT_BUFFERS: 5137 { 5138 if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS) 5139 || mCodec->mPortEOS[kPortIndexOutput])) { 5140 ALOGV("[%s] calling fillBuffer %u", 5141 mCodec->mComponentName.c_str(), info->mBufferID); 5142 5143 err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd); 5144 info->mFenceFd = -1; 5145 if (err != OK) { 5146 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5147 return true; 5148 } 5149 5150 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5151 break; 5152 } 5153 5154 sp<AMessage> reply = 5155 new AMessage(kWhatOutputBufferDrained, mCodec); 5156 5157 if (!mCodec->mSentFormat && rangeLength > 0) { 5158 mCodec->sendFormatChange(reply); 5159 } 5160 if (mCodec->usingMetadataOnEncoderOutput()) { 5161 native_handle_t *handle = NULL; 5162 VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data(); 5163 VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data(); 5164 if (info->mData->size() >= sizeof(grallocMeta) 5165 && grallocMeta.eType == kMetadataBufferTypeGrallocSource) { 5166 handle = (native_handle_t *)(uintptr_t)grallocMeta.pHandle; 5167 } else if (info->mData->size() >= sizeof(nativeMeta) 5168 && nativeMeta.eType == kMetadataBufferTypeANWBuffer) { 5169#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 5170 // ANativeWindowBuffer is only valid on 32-bit/mediaserver process 5171 handle = NULL; 5172#else 5173 handle = (native_handle_t *)nativeMeta.pBuffer->handle; 5174#endif 5175 } 5176 info->mData->meta()->setPointer("handle", handle); 5177 info->mData->meta()->setInt32("rangeOffset", rangeOffset); 5178 info->mData->meta()->setInt32("rangeLength", rangeLength); 5179 } else { 5180 info->mData->setRange(rangeOffset, rangeLength); 5181 } 5182#if 0 5183 if (mCodec->mNativeWindow == NULL) { 5184 if (IsIDR(info->mData)) { 5185 ALOGI("IDR frame"); 5186 } 5187 } 5188#endif 5189 5190 if (mCodec->mSkipCutBuffer != NULL) { 5191 mCodec->mSkipCutBuffer->submit(info->mData); 5192 } 5193 info->mData->meta()->setInt64("timeUs", timeUs); 5194 5195 sp<AMessage> notify = mCodec->mNotify->dup(); 5196 notify->setInt32("what", CodecBase::kWhatDrainThisBuffer); 5197 notify->setInt32("buffer-id", info->mBufferID); 5198 notify->setBuffer("buffer", info->mData); 5199 notify->setInt32("flags", flags); 5200 5201 reply->setInt32("buffer-id", info->mBufferID); 5202 5203 notify->setMessage("reply", reply); 5204 5205 notify->post(); 5206 5207 info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 5208 5209 if (flags & OMX_BUFFERFLAG_EOS) { 5210 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str()); 5211 5212 sp<AMessage> notify = mCodec->mNotify->dup(); 5213 notify->setInt32("what", CodecBase::kWhatEOS); 5214 notify->setInt32("err", mCodec->mInputEOSResult); 5215 notify->post(); 5216 5217 mCodec->mPortEOS[kPortIndexOutput] = true; 5218 } 5219 break; 5220 } 5221 5222 case FREE_BUFFERS: 5223 err = mCodec->freeBuffer(kPortIndexOutput, index); 5224 if (err != OK) { 5225 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5226 return true; 5227 } 5228 break; 5229 5230 default: 5231 ALOGE("Invalid port mode: %d", mode); 5232 return false; 5233 } 5234 5235 return true; 5236} 5237 5238void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 5239 IOMX::buffer_id bufferID; 5240 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 5241 ssize_t index; 5242 BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 5243 BufferInfo::Status status = BufferInfo::getSafeStatus(info); 5244 if (status != BufferInfo::OWNED_BY_DOWNSTREAM) { 5245 ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID); 5246 mCodec->dumpBuffers(kPortIndexOutput); 5247 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 5248 return; 5249 } 5250 5251 android_native_rect_t crop; 5252 if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) { 5253 status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop); 5254 ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err); 5255 } 5256 5257 int32_t render; 5258 if (mCodec->mNativeWindow != NULL 5259 && msg->findInt32("render", &render) && render != 0 5260 && info->mData != NULL && info->mData->size() != 0) { 5261 ATRACE_NAME("render"); 5262 // The client wants this buffer to be rendered. 5263 5264 // save buffers sent to the surface so we can get render time when they return 5265 int64_t mediaTimeUs = -1; 5266 info->mData->meta()->findInt64("timeUs", &mediaTimeUs); 5267 if (mediaTimeUs >= 0) { 5268 mCodec->mRenderTracker.onFrameQueued( 5269 mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd))); 5270 } 5271 5272 int64_t timestampNs = 0; 5273 if (!msg->findInt64("timestampNs", ×tampNs)) { 5274 // use media timestamp if client did not request a specific render timestamp 5275 if (info->mData->meta()->findInt64("timeUs", ×tampNs)) { 5276 ALOGV("using buffer PTS of %lld", (long long)timestampNs); 5277 timestampNs *= 1000; 5278 } 5279 } 5280 5281 status_t err; 5282 err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs); 5283 ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err); 5284 5285 info->checkReadFence("onOutputBufferDrained before queueBuffer"); 5286 err = mCodec->mNativeWindow->queueBuffer( 5287 mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd); 5288 info->mFenceFd = -1; 5289 if (err == OK) { 5290 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 5291 } else { 5292 ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err); 5293 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5294 info->mStatus = BufferInfo::OWNED_BY_US; 5295 // keeping read fence as write fence to avoid clobbering 5296 info->mIsReadFence = false; 5297 } 5298 } else { 5299 if (mCodec->mNativeWindow != NULL && 5300 (info->mData == NULL || info->mData->size() != 0)) { 5301 // move read fence into write fence to avoid clobbering 5302 info->mIsReadFence = false; 5303 ATRACE_NAME("frame-drop"); 5304 } 5305 info->mStatus = BufferInfo::OWNED_BY_US; 5306 } 5307 5308 PortMode mode = getPortMode(kPortIndexOutput); 5309 5310 switch (mode) { 5311 case KEEP_BUFFERS: 5312 { 5313 // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 5314 5315 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 5316 // We cannot resubmit the buffer we just rendered, dequeue 5317 // the spare instead. 5318 5319 info = mCodec->dequeueBufferFromNativeWindow(); 5320 } 5321 break; 5322 } 5323 5324 case RESUBMIT_BUFFERS: 5325 { 5326 if (!mCodec->mPortEOS[kPortIndexOutput]) { 5327 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 5328 // We cannot resubmit the buffer we just rendered, dequeue 5329 // the spare instead. 5330 5331 info = mCodec->dequeueBufferFromNativeWindow(); 5332 } 5333 5334 if (info != NULL) { 5335 ALOGV("[%s] calling fillBuffer %u", 5336 mCodec->mComponentName.c_str(), info->mBufferID); 5337 info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS"); 5338 status_t err = mCodec->mOMX->fillBuffer( 5339 mCodec->mNode, info->mBufferID, info->mFenceFd); 5340 info->mFenceFd = -1; 5341 if (err == OK) { 5342 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 5343 } else { 5344 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5345 } 5346 } 5347 } 5348 break; 5349 } 5350 5351 case FREE_BUFFERS: 5352 { 5353 status_t err = mCodec->freeBuffer(kPortIndexOutput, index); 5354 if (err != OK) { 5355 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5356 } 5357 break; 5358 } 5359 5360 default: 5361 ALOGE("Invalid port mode: %d", mode); 5362 return; 5363 } 5364} 5365 5366//////////////////////////////////////////////////////////////////////////////// 5367 5368ACodec::UninitializedState::UninitializedState(ACodec *codec) 5369 : BaseState(codec) { 5370} 5371 5372void ACodec::UninitializedState::stateEntered() { 5373 ALOGV("Now uninitialized"); 5374 5375 if (mDeathNotifier != NULL) { 5376 IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier); 5377 mDeathNotifier.clear(); 5378 } 5379 5380 mCodec->mNativeWindow.clear(); 5381 mCodec->mNativeWindowUsageBits = 0; 5382 mCodec->mNode = 0; 5383 mCodec->mOMX.clear(); 5384 mCodec->mQuirks = 0; 5385 mCodec->mFlags = 0; 5386 mCodec->mInputMetadataType = kMetadataBufferTypeInvalid; 5387 mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid; 5388 mCodec->mComponentName.clear(); 5389} 5390 5391bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 5392 bool handled = false; 5393 5394 switch (msg->what()) { 5395 case ACodec::kWhatSetup: 5396 { 5397 onSetup(msg); 5398 5399 handled = true; 5400 break; 5401 } 5402 5403 case ACodec::kWhatAllocateComponent: 5404 { 5405 onAllocateComponent(msg); 5406 handled = true; 5407 break; 5408 } 5409 5410 case ACodec::kWhatShutdown: 5411 { 5412 int32_t keepComponentAllocated; 5413 CHECK(msg->findInt32( 5414 "keepComponentAllocated", &keepComponentAllocated)); 5415 ALOGW_IF(keepComponentAllocated, 5416 "cannot keep component allocated on shutdown in Uninitialized state"); 5417 5418 sp<AMessage> notify = mCodec->mNotify->dup(); 5419 notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 5420 notify->post(); 5421 5422 handled = true; 5423 break; 5424 } 5425 5426 case ACodec::kWhatFlush: 5427 { 5428 sp<AMessage> notify = mCodec->mNotify->dup(); 5429 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5430 notify->post(); 5431 5432 handled = true; 5433 break; 5434 } 5435 5436 case ACodec::kWhatReleaseCodecInstance: 5437 { 5438 // nothing to do, as we have already signaled shutdown 5439 handled = true; 5440 break; 5441 } 5442 5443 default: 5444 return BaseState::onMessageReceived(msg); 5445 } 5446 5447 return handled; 5448} 5449 5450void ACodec::UninitializedState::onSetup( 5451 const sp<AMessage> &msg) { 5452 if (onAllocateComponent(msg) 5453 && mCodec->mLoadedState->onConfigureComponent(msg)) { 5454 mCodec->mLoadedState->onStart(); 5455 } 5456} 5457 5458bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { 5459 ALOGV("onAllocateComponent"); 5460 5461 CHECK(mCodec->mNode == 0); 5462 5463 OMXClient client; 5464 if (client.connect() != OK) { 5465 mCodec->signalError(OMX_ErrorUndefined, NO_INIT); 5466 return false; 5467 } 5468 5469 sp<IOMX> omx = client.interface(); 5470 5471 sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec); 5472 5473 mDeathNotifier = new DeathNotifier(notify); 5474 if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) { 5475 // This was a local binder, if it dies so do we, we won't care 5476 // about any notifications in the afterlife. 5477 mDeathNotifier.clear(); 5478 } 5479 5480 Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs; 5481 5482 AString mime; 5483 5484 AString componentName; 5485 uint32_t quirks = 0; 5486 int32_t encoder = false; 5487 if (msg->findString("componentName", &componentName)) { 5488 ssize_t index = matchingCodecs.add(); 5489 OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index); 5490 entry->mName = String8(componentName.c_str()); 5491 5492 if (!OMXCodec::findCodecQuirks( 5493 componentName.c_str(), &entry->mQuirks)) { 5494 entry->mQuirks = 0; 5495 } 5496 } else { 5497 CHECK(msg->findString("mime", &mime)); 5498 5499 if (!msg->findInt32("encoder", &encoder)) { 5500 encoder = false; 5501 } 5502 5503 OMXCodec::findMatchingCodecs( 5504 mime.c_str(), 5505 encoder, // createEncoder 5506 NULL, // matchComponentName 5507 0, // flags 5508 &matchingCodecs); 5509 } 5510 5511 sp<CodecObserver> observer = new CodecObserver; 5512 IOMX::node_id node = 0; 5513 5514 status_t err = NAME_NOT_FOUND; 5515 for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); 5516 ++matchIndex) { 5517 componentName = matchingCodecs.itemAt(matchIndex).mName.string(); 5518 quirks = matchingCodecs.itemAt(matchIndex).mQuirks; 5519 5520 pid_t tid = gettid(); 5521 int prevPriority = androidGetThreadPriority(tid); 5522 androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); 5523 err = omx->allocateNode(componentName.c_str(), observer, &node); 5524 androidSetThreadPriority(tid, prevPriority); 5525 5526 if (err == OK) { 5527 break; 5528 } else { 5529 ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str()); 5530 } 5531 5532 node = 0; 5533 } 5534 5535 if (node == 0) { 5536 if (!mime.empty()) { 5537 ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.", 5538 encoder ? "en" : "de", mime.c_str(), err); 5539 } else { 5540 ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err); 5541 } 5542 5543 mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err)); 5544 return false; 5545 } 5546 5547 notify = new AMessage(kWhatOMXMessageList, mCodec); 5548 observer->setNotificationMessage(notify); 5549 5550 mCodec->mComponentName = componentName; 5551 mCodec->mRenderTracker.setComponentName(componentName); 5552 mCodec->mFlags = 0; 5553 5554 if (componentName.endsWith(".secure")) { 5555 mCodec->mFlags |= kFlagIsSecure; 5556 mCodec->mFlags |= kFlagIsGrallocUsageProtected; 5557 mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 5558 } 5559 5560 mCodec->mQuirks = quirks; 5561 mCodec->mOMX = omx; 5562 mCodec->mNode = node; 5563 5564 { 5565 sp<AMessage> notify = mCodec->mNotify->dup(); 5566 notify->setInt32("what", CodecBase::kWhatComponentAllocated); 5567 notify->setString("componentName", mCodec->mComponentName.c_str()); 5568 notify->post(); 5569 } 5570 5571 mCodec->changeState(mCodec->mLoadedState); 5572 5573 return true; 5574} 5575 5576//////////////////////////////////////////////////////////////////////////////// 5577 5578ACodec::LoadedState::LoadedState(ACodec *codec) 5579 : BaseState(codec) { 5580} 5581 5582void ACodec::LoadedState::stateEntered() { 5583 ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 5584 5585 mCodec->mPortEOS[kPortIndexInput] = 5586 mCodec->mPortEOS[kPortIndexOutput] = false; 5587 5588 mCodec->mInputEOSResult = OK; 5589 5590 mCodec->mDequeueCounter = 0; 5591 mCodec->mMetadataBuffersToSubmit = 0; 5592 mCodec->mRepeatFrameDelayUs = -1ll; 5593 mCodec->mInputFormat.clear(); 5594 mCodec->mOutputFormat.clear(); 5595 mCodec->mBaseOutputFormat.clear(); 5596 5597 if (mCodec->mShutdownInProgress) { 5598 bool keepComponentAllocated = mCodec->mKeepComponentAllocated; 5599 5600 mCodec->mShutdownInProgress = false; 5601 mCodec->mKeepComponentAllocated = false; 5602 5603 onShutdown(keepComponentAllocated); 5604 } 5605 mCodec->mExplicitShutdown = false; 5606 5607 mCodec->processDeferredMessages(); 5608} 5609 5610void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) { 5611 if (!keepComponentAllocated) { 5612 (void)mCodec->mOMX->freeNode(mCodec->mNode); 5613 5614 mCodec->changeState(mCodec->mUninitializedState); 5615 } 5616 5617 if (mCodec->mExplicitShutdown) { 5618 sp<AMessage> notify = mCodec->mNotify->dup(); 5619 notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 5620 notify->post(); 5621 mCodec->mExplicitShutdown = false; 5622 } 5623} 5624 5625bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) { 5626 bool handled = false; 5627 5628 switch (msg->what()) { 5629 case ACodec::kWhatConfigureComponent: 5630 { 5631 onConfigureComponent(msg); 5632 handled = true; 5633 break; 5634 } 5635 5636 case ACodec::kWhatCreateInputSurface: 5637 { 5638 onCreateInputSurface(msg); 5639 handled = true; 5640 break; 5641 } 5642 5643 case ACodec::kWhatSetInputSurface: 5644 { 5645 onSetInputSurface(msg); 5646 handled = true; 5647 break; 5648 } 5649 5650 case ACodec::kWhatStart: 5651 { 5652 onStart(); 5653 handled = true; 5654 break; 5655 } 5656 5657 case ACodec::kWhatShutdown: 5658 { 5659 int32_t keepComponentAllocated; 5660 CHECK(msg->findInt32( 5661 "keepComponentAllocated", &keepComponentAllocated)); 5662 5663 mCodec->mExplicitShutdown = true; 5664 onShutdown(keepComponentAllocated); 5665 5666 handled = true; 5667 break; 5668 } 5669 5670 case ACodec::kWhatFlush: 5671 { 5672 sp<AMessage> notify = mCodec->mNotify->dup(); 5673 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5674 notify->post(); 5675 5676 handled = true; 5677 break; 5678 } 5679 5680 default: 5681 return BaseState::onMessageReceived(msg); 5682 } 5683 5684 return handled; 5685} 5686 5687bool ACodec::LoadedState::onConfigureComponent( 5688 const sp<AMessage> &msg) { 5689 ALOGV("onConfigureComponent"); 5690 5691 CHECK(mCodec->mNode != 0); 5692 5693 status_t err = OK; 5694 AString mime; 5695 if (!msg->findString("mime", &mime)) { 5696 err = BAD_VALUE; 5697 } else { 5698 err = mCodec->configureCodec(mime.c_str(), msg); 5699 } 5700 if (err != OK) { 5701 ALOGE("[%s] configureCodec returning error %d", 5702 mCodec->mComponentName.c_str(), err); 5703 5704 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5705 return false; 5706 } 5707 5708 { 5709 sp<AMessage> notify = mCodec->mNotify->dup(); 5710 notify->setInt32("what", CodecBase::kWhatComponentConfigured); 5711 notify->setMessage("input-format", mCodec->mInputFormat); 5712 notify->setMessage("output-format", mCodec->mOutputFormat); 5713 notify->post(); 5714 } 5715 5716 return true; 5717} 5718 5719status_t ACodec::LoadedState::setupInputSurface() { 5720 status_t err = OK; 5721 5722 if (mCodec->mRepeatFrameDelayUs > 0ll) { 5723 err = mCodec->mOMX->setInternalOption( 5724 mCodec->mNode, 5725 kPortIndexInput, 5726 IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY, 5727 &mCodec->mRepeatFrameDelayUs, 5728 sizeof(mCodec->mRepeatFrameDelayUs)); 5729 5730 if (err != OK) { 5731 ALOGE("[%s] Unable to configure option to repeat previous " 5732 "frames (err %d)", 5733 mCodec->mComponentName.c_str(), 5734 err); 5735 return err; 5736 } 5737 } 5738 5739 if (mCodec->mMaxPtsGapUs > 0ll) { 5740 err = mCodec->mOMX->setInternalOption( 5741 mCodec->mNode, 5742 kPortIndexInput, 5743 IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP, 5744 &mCodec->mMaxPtsGapUs, 5745 sizeof(mCodec->mMaxPtsGapUs)); 5746 5747 if (err != OK) { 5748 ALOGE("[%s] Unable to configure max timestamp gap (err %d)", 5749 mCodec->mComponentName.c_str(), 5750 err); 5751 return err; 5752 } 5753 } 5754 5755 if (mCodec->mMaxFps > 0) { 5756 err = mCodec->mOMX->setInternalOption( 5757 mCodec->mNode, 5758 kPortIndexInput, 5759 IOMX::INTERNAL_OPTION_MAX_FPS, 5760 &mCodec->mMaxFps, 5761 sizeof(mCodec->mMaxFps)); 5762 5763 if (err != OK) { 5764 ALOGE("[%s] Unable to configure max fps (err %d)", 5765 mCodec->mComponentName.c_str(), 5766 err); 5767 return err; 5768 } 5769 } 5770 5771 if (mCodec->mTimePerCaptureUs > 0ll 5772 && mCodec->mTimePerFrameUs > 0ll) { 5773 int64_t timeLapse[2]; 5774 timeLapse[0] = mCodec->mTimePerFrameUs; 5775 timeLapse[1] = mCodec->mTimePerCaptureUs; 5776 err = mCodec->mOMX->setInternalOption( 5777 mCodec->mNode, 5778 kPortIndexInput, 5779 IOMX::INTERNAL_OPTION_TIME_LAPSE, 5780 &timeLapse[0], 5781 sizeof(timeLapse)); 5782 5783 if (err != OK) { 5784 ALOGE("[%s] Unable to configure time lapse (err %d)", 5785 mCodec->mComponentName.c_str(), 5786 err); 5787 return err; 5788 } 5789 } 5790 5791 if (mCodec->mCreateInputBuffersSuspended) { 5792 bool suspend = true; 5793 err = mCodec->mOMX->setInternalOption( 5794 mCodec->mNode, 5795 kPortIndexInput, 5796 IOMX::INTERNAL_OPTION_SUSPEND, 5797 &suspend, 5798 sizeof(suspend)); 5799 5800 if (err != OK) { 5801 ALOGE("[%s] Unable to configure option to suspend (err %d)", 5802 mCodec->mComponentName.c_str(), 5803 err); 5804 return err; 5805 } 5806 } 5807 5808 uint32_t usageBits; 5809 if (mCodec->mOMX->getParameter( 5810 mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, 5811 &usageBits, sizeof(usageBits)) == OK) { 5812 mCodec->mInputFormat->setInt32( 5813 "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN)); 5814 } 5815 5816 return OK; 5817} 5818 5819void ACodec::LoadedState::onCreateInputSurface( 5820 const sp<AMessage> & /* msg */) { 5821 ALOGV("onCreateInputSurface"); 5822 5823 sp<AMessage> notify = mCodec->mNotify->dup(); 5824 notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated); 5825 5826 sp<IGraphicBufferProducer> bufferProducer; 5827 status_t err = mCodec->mOMX->createInputSurface( 5828 mCodec->mNode, kPortIndexInput, &bufferProducer, &mCodec->mInputMetadataType); 5829 5830 if (err == OK) { 5831 err = setupInputSurface(); 5832 } 5833 5834 if (err == OK) { 5835 notify->setObject("input-surface", 5836 new BufferProducerWrapper(bufferProducer)); 5837 } else { 5838 // Can't use mCodec->signalError() here -- MediaCodec won't forward 5839 // the error through because it's in the "configured" state. We 5840 // send a kWhatInputSurfaceCreated with an error value instead. 5841 ALOGE("[%s] onCreateInputSurface returning error %d", 5842 mCodec->mComponentName.c_str(), err); 5843 notify->setInt32("err", err); 5844 } 5845 notify->post(); 5846} 5847 5848void ACodec::LoadedState::onSetInputSurface( 5849 const sp<AMessage> &msg) { 5850 ALOGV("onSetInputSurface"); 5851 5852 sp<AMessage> notify = mCodec->mNotify->dup(); 5853 notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted); 5854 5855 sp<RefBase> obj; 5856 CHECK(msg->findObject("input-surface", &obj)); 5857 sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get()); 5858 5859 status_t err = mCodec->mOMX->setInputSurface( 5860 mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(), 5861 &mCodec->mInputMetadataType); 5862 5863 if (err == OK) { 5864 err = setupInputSurface(); 5865 } 5866 5867 if (err != OK) { 5868 // Can't use mCodec->signalError() here -- MediaCodec won't forward 5869 // the error through because it's in the "configured" state. We 5870 // send a kWhatInputSurfaceAccepted with an error value instead. 5871 ALOGE("[%s] onSetInputSurface returning error %d", 5872 mCodec->mComponentName.c_str(), err); 5873 notify->setInt32("err", err); 5874 } 5875 notify->post(); 5876} 5877 5878void ACodec::LoadedState::onStart() { 5879 ALOGV("onStart"); 5880 5881 status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle); 5882 if (err != OK) { 5883 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5884 } else { 5885 mCodec->changeState(mCodec->mLoadedToIdleState); 5886 } 5887} 5888 5889//////////////////////////////////////////////////////////////////////////////// 5890 5891ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 5892 : BaseState(codec) { 5893} 5894 5895void ACodec::LoadedToIdleState::stateEntered() { 5896 ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 5897 5898 status_t err; 5899 if ((err = allocateBuffers()) != OK) { 5900 ALOGE("Failed to allocate buffers after transitioning to IDLE state " 5901 "(error 0x%08x)", 5902 err); 5903 5904 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5905 5906 mCodec->changeState(mCodec->mLoadedState); 5907 } 5908} 5909 5910status_t ACodec::LoadedToIdleState::allocateBuffers() { 5911 status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 5912 5913 if (err != OK) { 5914 return err; 5915 } 5916 5917 return mCodec->allocateBuffersOnPort(kPortIndexOutput); 5918} 5919 5920bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 5921 switch (msg->what()) { 5922 case kWhatSetParameters: 5923 case kWhatShutdown: 5924 { 5925 mCodec->deferMessage(msg); 5926 return true; 5927 } 5928 5929 case kWhatSignalEndOfInputStream: 5930 { 5931 mCodec->onSignalEndOfInputStream(); 5932 return true; 5933 } 5934 5935 case kWhatResume: 5936 { 5937 // We'll be active soon enough. 5938 return true; 5939 } 5940 5941 case kWhatFlush: 5942 { 5943 // We haven't even started yet, so we're flushed alright... 5944 sp<AMessage> notify = mCodec->mNotify->dup(); 5945 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 5946 notify->post(); 5947 return true; 5948 } 5949 5950 default: 5951 return BaseState::onMessageReceived(msg); 5952 } 5953} 5954 5955bool ACodec::LoadedToIdleState::onOMXEvent( 5956 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 5957 switch (event) { 5958 case OMX_EventCmdComplete: 5959 { 5960 status_t err = OK; 5961 if (data1 != (OMX_U32)OMX_CommandStateSet 5962 || data2 != (OMX_U32)OMX_StateIdle) { 5963 ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)", 5964 asString((OMX_COMMANDTYPE)data1), data1, 5965 asString((OMX_STATETYPE)data2), data2); 5966 err = FAILED_TRANSACTION; 5967 } 5968 5969 if (err == OK) { 5970 err = mCodec->mOMX->sendCommand( 5971 mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting); 5972 } 5973 5974 if (err != OK) { 5975 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 5976 } else { 5977 mCodec->changeState(mCodec->mIdleToExecutingState); 5978 } 5979 5980 return true; 5981 } 5982 5983 default: 5984 return BaseState::onOMXEvent(event, data1, data2); 5985 } 5986} 5987 5988//////////////////////////////////////////////////////////////////////////////// 5989 5990ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 5991 : BaseState(codec) { 5992} 5993 5994void ACodec::IdleToExecutingState::stateEntered() { 5995 ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 5996} 5997 5998bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 5999 switch (msg->what()) { 6000 case kWhatSetParameters: 6001 case kWhatShutdown: 6002 { 6003 mCodec->deferMessage(msg); 6004 return true; 6005 } 6006 6007 case kWhatResume: 6008 { 6009 // We'll be active soon enough. 6010 return true; 6011 } 6012 6013 case kWhatFlush: 6014 { 6015 // We haven't even started yet, so we're flushed alright... 6016 sp<AMessage> notify = mCodec->mNotify->dup(); 6017 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 6018 notify->post(); 6019 6020 return true; 6021 } 6022 6023 case kWhatSignalEndOfInputStream: 6024 { 6025 mCodec->onSignalEndOfInputStream(); 6026 return true; 6027 } 6028 6029 default: 6030 return BaseState::onMessageReceived(msg); 6031 } 6032} 6033 6034bool ACodec::IdleToExecutingState::onOMXEvent( 6035 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6036 switch (event) { 6037 case OMX_EventCmdComplete: 6038 { 6039 if (data1 != (OMX_U32)OMX_CommandStateSet 6040 || data2 != (OMX_U32)OMX_StateExecuting) { 6041 ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)", 6042 asString((OMX_COMMANDTYPE)data1), data1, 6043 asString((OMX_STATETYPE)data2), data2); 6044 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6045 return true; 6046 } 6047 6048 mCodec->mExecutingState->resume(); 6049 mCodec->changeState(mCodec->mExecutingState); 6050 6051 return true; 6052 } 6053 6054 default: 6055 return BaseState::onOMXEvent(event, data1, data2); 6056 } 6057} 6058 6059//////////////////////////////////////////////////////////////////////////////// 6060 6061ACodec::ExecutingState::ExecutingState(ACodec *codec) 6062 : BaseState(codec), 6063 mActive(false) { 6064} 6065 6066ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 6067 OMX_U32 /* portIndex */) { 6068 return RESUBMIT_BUFFERS; 6069} 6070 6071void ACodec::ExecutingState::submitOutputMetaBuffers() { 6072 // submit as many buffers as there are input buffers with the codec 6073 // in case we are in port reconfiguring 6074 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 6075 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 6076 6077 if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) { 6078 if (mCodec->submitOutputMetadataBuffer() != OK) 6079 break; 6080 } 6081 } 6082 6083 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 6084 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 6085} 6086 6087void ACodec::ExecutingState::submitRegularOutputBuffers() { 6088 bool failed = false; 6089 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 6090 BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 6091 6092 if (mCodec->mNativeWindow != NULL) { 6093 if (info->mStatus != BufferInfo::OWNED_BY_US 6094 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6095 ALOGE("buffers should be owned by us or the surface"); 6096 failed = true; 6097 break; 6098 } 6099 6100 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 6101 continue; 6102 } 6103 } else { 6104 if (info->mStatus != BufferInfo::OWNED_BY_US) { 6105 ALOGE("buffers should be owned by us"); 6106 failed = true; 6107 break; 6108 } 6109 } 6110 6111 ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID); 6112 6113 info->checkWriteFence("submitRegularOutputBuffers"); 6114 status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd); 6115 info->mFenceFd = -1; 6116 if (err != OK) { 6117 failed = true; 6118 break; 6119 } 6120 6121 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 6122 } 6123 6124 if (failed) { 6125 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6126 } 6127} 6128 6129void ACodec::ExecutingState::submitOutputBuffers() { 6130 submitRegularOutputBuffers(); 6131 if (mCodec->storingMetadataInDecodedBuffers()) { 6132 submitOutputMetaBuffers(); 6133 } 6134} 6135 6136void ACodec::ExecutingState::resume() { 6137 if (mActive) { 6138 ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str()); 6139 return; 6140 } 6141 6142 submitOutputBuffers(); 6143 6144 // Post all available input buffers 6145 if (mCodec->mBuffers[kPortIndexInput].size() == 0u) { 6146 ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str()); 6147 } 6148 6149 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) { 6150 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 6151 if (info->mStatus == BufferInfo::OWNED_BY_US) { 6152 postFillThisBuffer(info); 6153 } 6154 } 6155 6156 mActive = true; 6157} 6158 6159void ACodec::ExecutingState::stateEntered() { 6160 ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 6161 6162 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 6163 mCodec->processDeferredMessages(); 6164} 6165 6166bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 6167 bool handled = false; 6168 6169 switch (msg->what()) { 6170 case kWhatShutdown: 6171 { 6172 int32_t keepComponentAllocated; 6173 CHECK(msg->findInt32( 6174 "keepComponentAllocated", &keepComponentAllocated)); 6175 6176 mCodec->mShutdownInProgress = true; 6177 mCodec->mExplicitShutdown = true; 6178 mCodec->mKeepComponentAllocated = keepComponentAllocated; 6179 6180 mActive = false; 6181 6182 status_t err = mCodec->mOMX->sendCommand( 6183 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle); 6184 if (err != OK) { 6185 if (keepComponentAllocated) { 6186 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6187 } 6188 // TODO: do some recovery here. 6189 } else { 6190 mCodec->changeState(mCodec->mExecutingToIdleState); 6191 } 6192 6193 handled = true; 6194 break; 6195 } 6196 6197 case kWhatFlush: 6198 { 6199 ALOGV("[%s] ExecutingState flushing now " 6200 "(codec owns %zu/%zu input, %zu/%zu output).", 6201 mCodec->mComponentName.c_str(), 6202 mCodec->countBuffersOwnedByComponent(kPortIndexInput), 6203 mCodec->mBuffers[kPortIndexInput].size(), 6204 mCodec->countBuffersOwnedByComponent(kPortIndexOutput), 6205 mCodec->mBuffers[kPortIndexOutput].size()); 6206 6207 mActive = false; 6208 6209 status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL); 6210 if (err != OK) { 6211 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6212 } else { 6213 mCodec->changeState(mCodec->mFlushingState); 6214 } 6215 6216 handled = true; 6217 break; 6218 } 6219 6220 case kWhatResume: 6221 { 6222 resume(); 6223 6224 handled = true; 6225 break; 6226 } 6227 6228 case kWhatRequestIDRFrame: 6229 { 6230 status_t err = mCodec->requestIDRFrame(); 6231 if (err != OK) { 6232 ALOGW("Requesting an IDR frame failed."); 6233 } 6234 6235 handled = true; 6236 break; 6237 } 6238 6239 case kWhatSetParameters: 6240 { 6241 sp<AMessage> params; 6242 CHECK(msg->findMessage("params", ¶ms)); 6243 6244 status_t err = mCodec->setParameters(params); 6245 6246 sp<AMessage> reply; 6247 if (msg->findMessage("reply", &reply)) { 6248 reply->setInt32("err", err); 6249 reply->post(); 6250 } 6251 6252 handled = true; 6253 break; 6254 } 6255 6256 case ACodec::kWhatSignalEndOfInputStream: 6257 { 6258 mCodec->onSignalEndOfInputStream(); 6259 handled = true; 6260 break; 6261 } 6262 6263 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 6264 case kWhatSubmitOutputMetadataBufferIfEOS: 6265 { 6266 if (mCodec->mPortEOS[kPortIndexInput] && 6267 !mCodec->mPortEOS[kPortIndexOutput]) { 6268 status_t err = mCodec->submitOutputMetadataBuffer(); 6269 if (err == OK) { 6270 mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); 6271 } 6272 } 6273 return true; 6274 } 6275 6276 default: 6277 handled = BaseState::onMessageReceived(msg); 6278 break; 6279 } 6280 6281 return handled; 6282} 6283 6284status_t ACodec::setParameters(const sp<AMessage> ¶ms) { 6285 int32_t videoBitrate; 6286 if (params->findInt32("video-bitrate", &videoBitrate)) { 6287 OMX_VIDEO_CONFIG_BITRATETYPE configParams; 6288 InitOMXParams(&configParams); 6289 configParams.nPortIndex = kPortIndexOutput; 6290 configParams.nEncodeBitrate = videoBitrate; 6291 6292 status_t err = mOMX->setConfig( 6293 mNode, 6294 OMX_IndexConfigVideoBitrate, 6295 &configParams, 6296 sizeof(configParams)); 6297 6298 if (err != OK) { 6299 ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d", 6300 videoBitrate, err); 6301 6302 return err; 6303 } 6304 } 6305 6306 int64_t skipFramesBeforeUs; 6307 if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) { 6308 status_t err = 6309 mOMX->setInternalOption( 6310 mNode, 6311 kPortIndexInput, 6312 IOMX::INTERNAL_OPTION_START_TIME, 6313 &skipFramesBeforeUs, 6314 sizeof(skipFramesBeforeUs)); 6315 6316 if (err != OK) { 6317 ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err); 6318 return err; 6319 } 6320 } 6321 6322 int32_t dropInputFrames; 6323 if (params->findInt32("drop-input-frames", &dropInputFrames)) { 6324 bool suspend = dropInputFrames != 0; 6325 6326 status_t err = 6327 mOMX->setInternalOption( 6328 mNode, 6329 kPortIndexInput, 6330 IOMX::INTERNAL_OPTION_SUSPEND, 6331 &suspend, 6332 sizeof(suspend)); 6333 6334 if (err != OK) { 6335 ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err); 6336 return err; 6337 } 6338 } 6339 6340 int32_t dummy; 6341 if (params->findInt32("request-sync", &dummy)) { 6342 status_t err = requestIDRFrame(); 6343 6344 if (err != OK) { 6345 ALOGE("Requesting a sync frame failed w/ err %d", err); 6346 return err; 6347 } 6348 } 6349 6350 float rate; 6351 if (params->findFloat("operating-rate", &rate) && rate > 0) { 6352 status_t err = setOperatingRate(rate, mIsVideo); 6353 if (err != OK) { 6354 ALOGE("Failed to set parameter 'operating-rate' (err %d)", err); 6355 return err; 6356 } 6357 } 6358 6359 return OK; 6360} 6361 6362void ACodec::onSignalEndOfInputStream() { 6363 sp<AMessage> notify = mNotify->dup(); 6364 notify->setInt32("what", CodecBase::kWhatSignaledInputEOS); 6365 6366 status_t err = mOMX->signalEndOfInputStream(mNode); 6367 if (err != OK) { 6368 notify->setInt32("err", err); 6369 } 6370 notify->post(); 6371} 6372 6373bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) { 6374 mCodec->onFrameRendered(mediaTimeUs, systemNano); 6375 return true; 6376} 6377 6378bool ACodec::ExecutingState::onOMXEvent( 6379 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6380 switch (event) { 6381 case OMX_EventPortSettingsChanged: 6382 { 6383 CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 6384 6385 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 6386 mCodec->mMetadataBuffersToSubmit = 0; 6387 CHECK_EQ(mCodec->mOMX->sendCommand( 6388 mCodec->mNode, 6389 OMX_CommandPortDisable, kPortIndexOutput), 6390 (status_t)OK); 6391 6392 mCodec->freeOutputBuffersNotOwnedByComponent(); 6393 6394 mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 6395 } else if (data2 == OMX_IndexConfigCommonOutputCrop) { 6396 mCodec->mSentFormat = false; 6397 6398 if (mCodec->mTunneled) { 6399 sp<AMessage> dummy = new AMessage(kWhatOutputBufferDrained, mCodec); 6400 mCodec->sendFormatChange(dummy); 6401 } 6402 } else { 6403 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x", 6404 mCodec->mComponentName.c_str(), data2); 6405 } 6406 6407 return true; 6408 } 6409 6410 case OMX_EventBufferFlag: 6411 { 6412 return true; 6413 } 6414 6415 default: 6416 return BaseState::onOMXEvent(event, data1, data2); 6417 } 6418} 6419 6420//////////////////////////////////////////////////////////////////////////////// 6421 6422ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 6423 ACodec *codec) 6424 : BaseState(codec) { 6425} 6426 6427ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 6428 OMX_U32 portIndex) { 6429 if (portIndex == kPortIndexOutput) { 6430 return FREE_BUFFERS; 6431 } 6432 6433 CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 6434 6435 return RESUBMIT_BUFFERS; 6436} 6437 6438bool ACodec::OutputPortSettingsChangedState::onMessageReceived( 6439 const sp<AMessage> &msg) { 6440 bool handled = false; 6441 6442 switch (msg->what()) { 6443 case kWhatFlush: 6444 case kWhatShutdown: 6445 case kWhatResume: 6446 case kWhatSetParameters: 6447 { 6448 if (msg->what() == kWhatResume) { 6449 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 6450 } 6451 6452 mCodec->deferMessage(msg); 6453 handled = true; 6454 break; 6455 } 6456 6457 default: 6458 handled = BaseState::onMessageReceived(msg); 6459 break; 6460 } 6461 6462 return handled; 6463} 6464 6465void ACodec::OutputPortSettingsChangedState::stateEntered() { 6466 ALOGV("[%s] Now handling output port settings change", 6467 mCodec->mComponentName.c_str()); 6468} 6469 6470bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered( 6471 int64_t mediaTimeUs, nsecs_t systemNano) { 6472 mCodec->onFrameRendered(mediaTimeUs, systemNano); 6473 return true; 6474} 6475 6476bool ACodec::OutputPortSettingsChangedState::onOMXEvent( 6477 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6478 switch (event) { 6479 case OMX_EventCmdComplete: 6480 { 6481 if (data1 == (OMX_U32)OMX_CommandPortDisable) { 6482 if (data2 != (OMX_U32)kPortIndexOutput) { 6483 ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2); 6484 return false; 6485 } 6486 6487 ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str()); 6488 6489 status_t err = OK; 6490 if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) { 6491 ALOGE("disabled port should be empty, but has %zu buffers", 6492 mCodec->mBuffers[kPortIndexOutput].size()); 6493 err = FAILED_TRANSACTION; 6494 } else { 6495 mCodec->mDealer[kPortIndexOutput].clear(); 6496 } 6497 6498 if (err == OK) { 6499 err = mCodec->mOMX->sendCommand( 6500 mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput); 6501 } 6502 6503 if (err == OK) { 6504 err = mCodec->allocateBuffersOnPort(kPortIndexOutput); 6505 ALOGE_IF(err != OK, "Failed to allocate output port buffers after port " 6506 "reconfiguration: (%d)", err); 6507 } 6508 6509 if (err != OK) { 6510 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); 6511 6512 // This is technically not correct, but appears to be 6513 // the only way to free the component instance. 6514 // Controlled transitioning from excecuting->idle 6515 // and idle->loaded seem impossible probably because 6516 // the output port never finishes re-enabling. 6517 mCodec->mShutdownInProgress = true; 6518 mCodec->mKeepComponentAllocated = false; 6519 mCodec->changeState(mCodec->mLoadedState); 6520 } 6521 6522 return true; 6523 } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 6524 if (data2 != (OMX_U32)kPortIndexOutput) { 6525 ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2); 6526 return false; 6527 } 6528 6529 mCodec->mSentFormat = false; 6530 6531 if (mCodec->mTunneled) { 6532 sp<AMessage> dummy = new AMessage(kWhatOutputBufferDrained, mCodec); 6533 mCodec->sendFormatChange(dummy); 6534 } 6535 6536 ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str()); 6537 6538 if (mCodec->mExecutingState->active()) { 6539 mCodec->mExecutingState->submitOutputBuffers(); 6540 } 6541 6542 mCodec->changeState(mCodec->mExecutingState); 6543 6544 return true; 6545 } 6546 6547 return false; 6548 } 6549 6550 default: 6551 return false; 6552 } 6553} 6554 6555//////////////////////////////////////////////////////////////////////////////// 6556 6557ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 6558 : BaseState(codec), 6559 mComponentNowIdle(false) { 6560} 6561 6562bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 6563 bool handled = false; 6564 6565 switch (msg->what()) { 6566 case kWhatFlush: 6567 { 6568 // Don't send me a flush request if you previously wanted me 6569 // to shutdown. 6570 ALOGW("Ignoring flush request in ExecutingToIdleState"); 6571 break; 6572 } 6573 6574 case kWhatShutdown: 6575 { 6576 // We're already doing that... 6577 6578 handled = true; 6579 break; 6580 } 6581 6582 default: 6583 handled = BaseState::onMessageReceived(msg); 6584 break; 6585 } 6586 6587 return handled; 6588} 6589 6590void ACodec::ExecutingToIdleState::stateEntered() { 6591 ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 6592 6593 mComponentNowIdle = false; 6594 mCodec->mSentFormat = false; 6595} 6596 6597bool ACodec::ExecutingToIdleState::onOMXEvent( 6598 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6599 switch (event) { 6600 case OMX_EventCmdComplete: 6601 { 6602 if (data1 != (OMX_U32)OMX_CommandStateSet 6603 || data2 != (OMX_U32)OMX_StateIdle) { 6604 ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)", 6605 asString((OMX_COMMANDTYPE)data1), data1, 6606 asString((OMX_STATETYPE)data2), data2); 6607 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6608 return true; 6609 } 6610 6611 mComponentNowIdle = true; 6612 6613 changeStateIfWeOwnAllBuffers(); 6614 6615 return true; 6616 } 6617 6618 case OMX_EventPortSettingsChanged: 6619 case OMX_EventBufferFlag: 6620 { 6621 // We're shutting down and don't care about this anymore. 6622 return true; 6623 } 6624 6625 default: 6626 return BaseState::onOMXEvent(event, data1, data2); 6627 } 6628} 6629 6630void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 6631 if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) { 6632 status_t err = mCodec->mOMX->sendCommand( 6633 mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded); 6634 if (err == OK) { 6635 err = mCodec->freeBuffersOnPort(kPortIndexInput); 6636 status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput); 6637 if (err == OK) { 6638 err = err2; 6639 } 6640 } 6641 6642 if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) 6643 && mCodec->mNativeWindow != NULL) { 6644 // We push enough 1x1 blank buffers to ensure that one of 6645 // them has made it to the display. This allows the OMX 6646 // component teardown to zero out any protected buffers 6647 // without the risk of scanning out one of those buffers. 6648 pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get()); 6649 } 6650 6651 if (err != OK) { 6652 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6653 return; 6654 } 6655 6656 mCodec->changeState(mCodec->mIdleToLoadedState); 6657 } 6658} 6659 6660void ACodec::ExecutingToIdleState::onInputBufferFilled( 6661 const sp<AMessage> &msg) { 6662 BaseState::onInputBufferFilled(msg); 6663 6664 changeStateIfWeOwnAllBuffers(); 6665} 6666 6667void ACodec::ExecutingToIdleState::onOutputBufferDrained( 6668 const sp<AMessage> &msg) { 6669 BaseState::onOutputBufferDrained(msg); 6670 6671 changeStateIfWeOwnAllBuffers(); 6672} 6673 6674//////////////////////////////////////////////////////////////////////////////// 6675 6676ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 6677 : BaseState(codec) { 6678} 6679 6680bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 6681 bool handled = false; 6682 6683 switch (msg->what()) { 6684 case kWhatShutdown: 6685 { 6686 // We're already doing that... 6687 6688 handled = true; 6689 break; 6690 } 6691 6692 case kWhatFlush: 6693 { 6694 // Don't send me a flush request if you previously wanted me 6695 // to shutdown. 6696 ALOGE("Got flush request in IdleToLoadedState"); 6697 break; 6698 } 6699 6700 default: 6701 handled = BaseState::onMessageReceived(msg); 6702 break; 6703 } 6704 6705 return handled; 6706} 6707 6708void ACodec::IdleToLoadedState::stateEntered() { 6709 ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 6710} 6711 6712bool ACodec::IdleToLoadedState::onOMXEvent( 6713 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6714 switch (event) { 6715 case OMX_EventCmdComplete: 6716 { 6717 if (data1 != (OMX_U32)OMX_CommandStateSet 6718 || data2 != (OMX_U32)OMX_StateLoaded) { 6719 ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)", 6720 asString((OMX_COMMANDTYPE)data1), data1, 6721 asString((OMX_STATETYPE)data2), data2); 6722 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6723 return true; 6724 } 6725 6726 mCodec->changeState(mCodec->mLoadedState); 6727 6728 return true; 6729 } 6730 6731 default: 6732 return BaseState::onOMXEvent(event, data1, data2); 6733 } 6734} 6735 6736//////////////////////////////////////////////////////////////////////////////// 6737 6738ACodec::FlushingState::FlushingState(ACodec *codec) 6739 : BaseState(codec) { 6740} 6741 6742void ACodec::FlushingState::stateEntered() { 6743 ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 6744 6745 mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 6746} 6747 6748bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 6749 bool handled = false; 6750 6751 switch (msg->what()) { 6752 case kWhatShutdown: 6753 { 6754 mCodec->deferMessage(msg); 6755 break; 6756 } 6757 6758 case kWhatFlush: 6759 { 6760 // We're already doing this right now. 6761 handled = true; 6762 break; 6763 } 6764 6765 default: 6766 handled = BaseState::onMessageReceived(msg); 6767 break; 6768 } 6769 6770 return handled; 6771} 6772 6773bool ACodec::FlushingState::onOMXEvent( 6774 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 6775 ALOGV("[%s] FlushingState onOMXEvent(%u,%d)", 6776 mCodec->mComponentName.c_str(), event, (OMX_S32)data1); 6777 6778 switch (event) { 6779 case OMX_EventCmdComplete: 6780 { 6781 if (data1 != (OMX_U32)OMX_CommandFlush) { 6782 ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState", 6783 asString((OMX_COMMANDTYPE)data1), data1, data2); 6784 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION); 6785 return true; 6786 } 6787 6788 if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 6789 if (mFlushComplete[data2]) { 6790 ALOGW("Flush already completed for %s port", 6791 data2 == kPortIndexInput ? "input" : "output"); 6792 return true; 6793 } 6794 mFlushComplete[data2] = true; 6795 6796 if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) { 6797 changeStateIfWeOwnAllBuffers(); 6798 } 6799 } else if (data2 == OMX_ALL) { 6800 if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) { 6801 ALOGW("received flush complete event for OMX_ALL before ports have been" 6802 "flushed (%d/%d)", 6803 mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]); 6804 return false; 6805 } 6806 6807 changeStateIfWeOwnAllBuffers(); 6808 } else { 6809 ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2); 6810 } 6811 6812 return true; 6813 } 6814 6815 case OMX_EventPortSettingsChanged: 6816 { 6817 sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec); 6818 msg->setInt32("type", omx_message::EVENT); 6819 msg->setInt32("node", mCodec->mNode); 6820 msg->setInt32("event", event); 6821 msg->setInt32("data1", data1); 6822 msg->setInt32("data2", data2); 6823 6824 ALOGV("[%s] Deferring OMX_EventPortSettingsChanged", 6825 mCodec->mComponentName.c_str()); 6826 6827 mCodec->deferMessage(msg); 6828 6829 return true; 6830 } 6831 6832 default: 6833 return BaseState::onOMXEvent(event, data1, data2); 6834 } 6835 6836 return true; 6837} 6838 6839void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 6840 BaseState::onOutputBufferDrained(msg); 6841 6842 changeStateIfWeOwnAllBuffers(); 6843} 6844 6845void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 6846 BaseState::onInputBufferFilled(msg); 6847 6848 changeStateIfWeOwnAllBuffers(); 6849} 6850 6851void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 6852 if (mFlushComplete[kPortIndexInput] 6853 && mFlushComplete[kPortIndexOutput] 6854 && mCodec->allYourBuffersAreBelongToUs()) { 6855 // We now own all buffers except possibly those still queued with 6856 // the native window for rendering. Let's get those back as well. 6857 mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs(); 6858 6859 mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC)); 6860 6861 sp<AMessage> notify = mCodec->mNotify->dup(); 6862 notify->setInt32("what", CodecBase::kWhatFlushCompleted); 6863 notify->post(); 6864 6865 mCodec->mPortEOS[kPortIndexInput] = 6866 mCodec->mPortEOS[kPortIndexOutput] = false; 6867 6868 mCodec->mInputEOSResult = OK; 6869 6870 if (mCodec->mSkipCutBuffer != NULL) { 6871 mCodec->mSkipCutBuffer->clear(); 6872 } 6873 6874 mCodec->changeState(mCodec->mExecutingState); 6875 } 6876} 6877 6878} // namespace android 6879