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