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