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