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