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