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