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