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