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