ACodec.cpp revision 609b815a3131d22da38b2f452faa9f89daad4039
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#include <inttypes.h> 21#include <utils/Trace.h> 22 23#include <media/stagefright/ACodec.h> 24 25#include <binder/MemoryDealer.h> 26 27#include <media/stagefright/foundation/hexdump.h> 28#include <media/stagefright/foundation/ABuffer.h> 29#include <media/stagefright/foundation/ADebug.h> 30#include <media/stagefright/foundation/AMessage.h> 31 32#include <media/stagefright/BufferProducerWrapper.h> 33#include <media/stagefright/MediaCodecList.h> 34#include <media/stagefright/MediaDefs.h> 35#include <media/stagefright/NativeWindowWrapper.h> 36#include <media/stagefright/OMXClient.h> 37#include <media/stagefright/OMXCodec.h> 38 39#include <media/hardware/HardwareAPI.h> 40 41#include <OMX_AudioExt.h> 42#include <OMX_VideoExt.h> 43#include <OMX_Component.h> 44#include <OMX_IndexExt.h> 45 46#include "include/avc_utils.h" 47 48namespace android { 49 50template<class T> 51static void InitOMXParams(T *params) { 52 params->nSize = sizeof(T); 53 params->nVersion.s.nVersionMajor = 1; 54 params->nVersion.s.nVersionMinor = 0; 55 params->nVersion.s.nRevision = 0; 56 params->nVersion.s.nStep = 0; 57} 58 59struct CodecObserver : public BnOMXObserver { 60 CodecObserver() {} 61 62 void setNotificationMessage(const sp<AMessage> &msg) { 63 mNotify = msg; 64 } 65 66 // from IOMXObserver 67 virtual void onMessage(const omx_message &omx_msg) { 68 sp<AMessage> msg = mNotify->dup(); 69 70 msg->setInt32("type", omx_msg.type); 71 msg->setInt32("node", omx_msg.node); 72 73 switch (omx_msg.type) { 74 case omx_message::EVENT: 75 { 76 msg->setInt32("event", omx_msg.u.event_data.event); 77 msg->setInt32("data1", omx_msg.u.event_data.data1); 78 msg->setInt32("data2", omx_msg.u.event_data.data2); 79 break; 80 } 81 82 case omx_message::EMPTY_BUFFER_DONE: 83 { 84 msg->setInt32("buffer", omx_msg.u.buffer_data.buffer); 85 break; 86 } 87 88 case omx_message::FILL_BUFFER_DONE: 89 { 90 msg->setInt32( 91 "buffer", omx_msg.u.extended_buffer_data.buffer); 92 msg->setInt32( 93 "range_offset", 94 omx_msg.u.extended_buffer_data.range_offset); 95 msg->setInt32( 96 "range_length", 97 omx_msg.u.extended_buffer_data.range_length); 98 msg->setInt32( 99 "flags", 100 omx_msg.u.extended_buffer_data.flags); 101 msg->setInt64( 102 "timestamp", 103 omx_msg.u.extended_buffer_data.timestamp); 104 break; 105 } 106 107 default: 108 TRESPASS(); 109 break; 110 } 111 112 msg->post(); 113 } 114 115protected: 116 virtual ~CodecObserver() {} 117 118private: 119 sp<AMessage> mNotify; 120 121 DISALLOW_EVIL_CONSTRUCTORS(CodecObserver); 122}; 123 124//////////////////////////////////////////////////////////////////////////////// 125 126struct ACodec::BaseState : public AState { 127 BaseState(ACodec *codec, const sp<AState> &parentState = NULL); 128 129protected: 130 enum PortMode { 131 KEEP_BUFFERS, 132 RESUBMIT_BUFFERS, 133 FREE_BUFFERS, 134 }; 135 136 ACodec *mCodec; 137 138 virtual PortMode getPortMode(OMX_U32 portIndex); 139 140 virtual bool onMessageReceived(const sp<AMessage> &msg); 141 142 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 143 144 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 145 virtual void onInputBufferFilled(const sp<AMessage> &msg); 146 147 void postFillThisBuffer(BufferInfo *info); 148 149private: 150 bool onOMXMessage(const sp<AMessage> &msg); 151 152 bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID); 153 154 bool onOMXFillBufferDone( 155 IOMX::buffer_id bufferID, 156 size_t rangeOffset, size_t rangeLength, 157 OMX_U32 flags, 158 int64_t timeUs); 159 160 void getMoreInputDataIfPossible(); 161 162 DISALLOW_EVIL_CONSTRUCTORS(BaseState); 163}; 164 165//////////////////////////////////////////////////////////////////////////////// 166 167struct ACodec::DeathNotifier : public IBinder::DeathRecipient { 168 DeathNotifier(const sp<AMessage> ¬ify) 169 : mNotify(notify) { 170 } 171 172 virtual void binderDied(const wp<IBinder> &) { 173 mNotify->post(); 174 } 175 176protected: 177 virtual ~DeathNotifier() {} 178 179private: 180 sp<AMessage> mNotify; 181 182 DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier); 183}; 184 185struct ACodec::UninitializedState : public ACodec::BaseState { 186 UninitializedState(ACodec *codec); 187 188protected: 189 virtual bool onMessageReceived(const sp<AMessage> &msg); 190 virtual void stateEntered(); 191 192private: 193 void onSetup(const sp<AMessage> &msg); 194 bool onAllocateComponent(const sp<AMessage> &msg); 195 196 sp<DeathNotifier> mDeathNotifier; 197 198 DISALLOW_EVIL_CONSTRUCTORS(UninitializedState); 199}; 200 201//////////////////////////////////////////////////////////////////////////////// 202 203struct ACodec::LoadedState : public ACodec::BaseState { 204 LoadedState(ACodec *codec); 205 206protected: 207 virtual bool onMessageReceived(const sp<AMessage> &msg); 208 virtual void stateEntered(); 209 210private: 211 friend struct ACodec::UninitializedState; 212 213 bool onConfigureComponent(const sp<AMessage> &msg); 214 void onCreateInputSurface(const sp<AMessage> &msg); 215 void onStart(); 216 void onShutdown(bool keepComponentAllocated); 217 218 DISALLOW_EVIL_CONSTRUCTORS(LoadedState); 219}; 220 221//////////////////////////////////////////////////////////////////////////////// 222 223struct ACodec::LoadedToIdleState : public ACodec::BaseState { 224 LoadedToIdleState(ACodec *codec); 225 226protected: 227 virtual bool onMessageReceived(const sp<AMessage> &msg); 228 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 229 virtual void stateEntered(); 230 231private: 232 status_t allocateBuffers(); 233 234 DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState); 235}; 236 237//////////////////////////////////////////////////////////////////////////////// 238 239struct ACodec::IdleToExecutingState : public ACodec::BaseState { 240 IdleToExecutingState(ACodec *codec); 241 242protected: 243 virtual bool onMessageReceived(const sp<AMessage> &msg); 244 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 245 virtual void stateEntered(); 246 247private: 248 DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState); 249}; 250 251//////////////////////////////////////////////////////////////////////////////// 252 253struct ACodec::ExecutingState : public ACodec::BaseState { 254 ExecutingState(ACodec *codec); 255 256 void submitRegularOutputBuffers(); 257 void submitOutputMetaBuffers(); 258 void submitOutputBuffers(); 259 260 // Submit output buffers to the decoder, submit input buffers to client 261 // to fill with data. 262 void resume(); 263 264 // Returns true iff input and output buffers are in play. 265 bool active() const { return mActive; } 266 267protected: 268 virtual PortMode getPortMode(OMX_U32 portIndex); 269 virtual bool onMessageReceived(const sp<AMessage> &msg); 270 virtual void stateEntered(); 271 272 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 273 274private: 275 bool mActive; 276 277 DISALLOW_EVIL_CONSTRUCTORS(ExecutingState); 278}; 279 280//////////////////////////////////////////////////////////////////////////////// 281 282struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState { 283 OutputPortSettingsChangedState(ACodec *codec); 284 285protected: 286 virtual PortMode getPortMode(OMX_U32 portIndex); 287 virtual bool onMessageReceived(const sp<AMessage> &msg); 288 virtual void stateEntered(); 289 290 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 291 292private: 293 DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState); 294}; 295 296//////////////////////////////////////////////////////////////////////////////// 297 298struct ACodec::ExecutingToIdleState : public ACodec::BaseState { 299 ExecutingToIdleState(ACodec *codec); 300 301protected: 302 virtual bool onMessageReceived(const sp<AMessage> &msg); 303 virtual void stateEntered(); 304 305 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 306 307 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 308 virtual void onInputBufferFilled(const sp<AMessage> &msg); 309 310private: 311 void changeStateIfWeOwnAllBuffers(); 312 313 bool mComponentNowIdle; 314 315 DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState); 316}; 317 318//////////////////////////////////////////////////////////////////////////////// 319 320struct ACodec::IdleToLoadedState : public ACodec::BaseState { 321 IdleToLoadedState(ACodec *codec); 322 323protected: 324 virtual bool onMessageReceived(const sp<AMessage> &msg); 325 virtual void stateEntered(); 326 327 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 328 329private: 330 DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState); 331}; 332 333//////////////////////////////////////////////////////////////////////////////// 334 335struct ACodec::FlushingState : public ACodec::BaseState { 336 FlushingState(ACodec *codec); 337 338protected: 339 virtual bool onMessageReceived(const sp<AMessage> &msg); 340 virtual void stateEntered(); 341 342 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 343 344 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 345 virtual void onInputBufferFilled(const sp<AMessage> &msg); 346 347private: 348 bool mFlushComplete[2]; 349 350 void changeStateIfWeOwnAllBuffers(); 351 352 DISALLOW_EVIL_CONSTRUCTORS(FlushingState); 353}; 354 355//////////////////////////////////////////////////////////////////////////////// 356 357ACodec::ACodec() 358 : mQuirks(0), 359 mNode(0), 360 mSentFormat(false), 361 mIsEncoder(false), 362 mUseMetadataOnEncoderOutput(false), 363 mShutdownInProgress(false), 364 mExplicitShutdown(false), 365 mEncoderDelay(0), 366 mEncoderPadding(0), 367 mChannelMaskPresent(false), 368 mChannelMask(0), 369 mDequeueCounter(0), 370 mStoreMetaDataInOutputBuffers(false), 371 mMetaDataBuffersToSubmit(0), 372 mRepeatFrameDelayUs(-1ll), 373 mMaxPtsGapUs(-1ll), 374 mTimePerFrameUs(-1ll), 375 mTimePerCaptureUs(-1ll), 376 mCreateInputBuffersSuspended(false) { 377 mUninitializedState = new UninitializedState(this); 378 mLoadedState = new LoadedState(this); 379 mLoadedToIdleState = new LoadedToIdleState(this); 380 mIdleToExecutingState = new IdleToExecutingState(this); 381 mExecutingState = new ExecutingState(this); 382 383 mOutputPortSettingsChangedState = 384 new OutputPortSettingsChangedState(this); 385 386 mExecutingToIdleState = new ExecutingToIdleState(this); 387 mIdleToLoadedState = new IdleToLoadedState(this); 388 mFlushingState = new FlushingState(this); 389 390 mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false; 391 mInputEOSResult = OK; 392 393 changeState(mUninitializedState); 394} 395 396ACodec::~ACodec() { 397} 398 399void ACodec::setNotificationMessage(const sp<AMessage> &msg) { 400 mNotify = msg; 401} 402 403void ACodec::initiateSetup(const sp<AMessage> &msg) { 404 msg->setWhat(kWhatSetup); 405 msg->setTarget(id()); 406 msg->post(); 407} 408 409void ACodec::signalSetParameters(const sp<AMessage> ¶ms) { 410 sp<AMessage> msg = new AMessage(kWhatSetParameters, id()); 411 msg->setMessage("params", params); 412 msg->post(); 413} 414 415void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) { 416 msg->setWhat(kWhatAllocateComponent); 417 msg->setTarget(id()); 418 msg->post(); 419} 420 421void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) { 422 msg->setWhat(kWhatConfigureComponent); 423 msg->setTarget(id()); 424 msg->post(); 425} 426 427void ACodec::initiateCreateInputSurface() { 428 (new AMessage(kWhatCreateInputSurface, id()))->post(); 429} 430 431void ACodec::signalEndOfInputStream() { 432 (new AMessage(kWhatSignalEndOfInputStream, id()))->post(); 433} 434 435void ACodec::initiateStart() { 436 (new AMessage(kWhatStart, id()))->post(); 437} 438 439void ACodec::signalFlush() { 440 ALOGV("[%s] signalFlush", mComponentName.c_str()); 441 (new AMessage(kWhatFlush, id()))->post(); 442} 443 444void ACodec::signalResume() { 445 (new AMessage(kWhatResume, id()))->post(); 446} 447 448void ACodec::initiateShutdown(bool keepComponentAllocated) { 449 sp<AMessage> msg = new AMessage(kWhatShutdown, id()); 450 msg->setInt32("keepComponentAllocated", keepComponentAllocated); 451 msg->post(); 452} 453 454void ACodec::signalRequestIDRFrame() { 455 (new AMessage(kWhatRequestIDRFrame, id()))->post(); 456} 457 458// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 459// Some codecs may return input buffers before having them processed. 460// This causes a halt if we already signaled an EOS on the input 461// port. For now keep submitting an output buffer if there was an 462// EOS on the input port, but not yet on the output port. 463void ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() { 464 if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] && 465 mMetaDataBuffersToSubmit > 0) { 466 (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post(); 467 } 468} 469 470status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) { 471 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 472 473 CHECK(mDealer[portIndex] == NULL); 474 CHECK(mBuffers[portIndex].isEmpty()); 475 476 status_t err; 477 if (mNativeWindow != NULL && portIndex == kPortIndexOutput) { 478 if (mStoreMetaDataInOutputBuffers) { 479 err = allocateOutputMetaDataBuffers(); 480 } else { 481 err = allocateOutputBuffersFromNativeWindow(); 482 } 483 } else { 484 OMX_PARAM_PORTDEFINITIONTYPE def; 485 InitOMXParams(&def); 486 def.nPortIndex = portIndex; 487 488 err = mOMX->getParameter( 489 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 490 491 if (err == OK) { 492 ALOGV("[%s] Allocating %u buffers of size %u on %s port", 493 mComponentName.c_str(), 494 def.nBufferCountActual, def.nBufferSize, 495 portIndex == kPortIndexInput ? "input" : "output"); 496 497 size_t totalSize = def.nBufferCountActual * def.nBufferSize; 498 mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec"); 499 500 for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { 501 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); 502 CHECK(mem.get() != NULL); 503 504 BufferInfo info; 505 info.mStatus = BufferInfo::OWNED_BY_US; 506 507 uint32_t requiresAllocateBufferBit = 508 (portIndex == kPortIndexInput) 509 ? OMXCodec::kRequiresAllocateBufferOnInputPorts 510 : OMXCodec::kRequiresAllocateBufferOnOutputPorts; 511 512 if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) 513 || mUseMetadataOnEncoderOutput) { 514 mem.clear(); 515 516 void *ptr; 517 err = mOMX->allocateBuffer( 518 mNode, portIndex, def.nBufferSize, &info.mBufferID, 519 &ptr); 520 521 int32_t bufSize = mUseMetadataOnEncoderOutput ? 522 (4 + sizeof(buffer_handle_t)) : def.nBufferSize; 523 524 info.mData = new ABuffer(ptr, bufSize); 525 } else if (mQuirks & requiresAllocateBufferBit) { 526 err = mOMX->allocateBufferWithBackup( 527 mNode, portIndex, mem, &info.mBufferID); 528 } else { 529 err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID); 530 } 531 532 if (mem != NULL) { 533 info.mData = new ABuffer(mem->pointer(), def.nBufferSize); 534 } 535 536 mBuffers[portIndex].push(info); 537 } 538 } 539 } 540 541 if (err != OK) { 542 return err; 543 } 544 545 sp<AMessage> notify = mNotify->dup(); 546 notify->setInt32("what", ACodec::kWhatBuffersAllocated); 547 548 notify->setInt32("portIndex", portIndex); 549 550 sp<PortDescription> desc = new PortDescription; 551 552 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 553 const BufferInfo &info = mBuffers[portIndex][i]; 554 555 desc->addBuffer(info.mBufferID, info.mData); 556 } 557 558 notify->setObject("portDesc", desc); 559 notify->post(); 560 561 return OK; 562} 563 564status_t ACodec::configureOutputBuffersFromNativeWindow( 565 OMX_U32 *bufferCount, OMX_U32 *bufferSize, 566 OMX_U32 *minUndequeuedBuffers) { 567 OMX_PARAM_PORTDEFINITIONTYPE def; 568 InitOMXParams(&def); 569 def.nPortIndex = kPortIndexOutput; 570 571 status_t err = mOMX->getParameter( 572 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 573 574 if (err != OK) { 575 return err; 576 } 577 578 err = native_window_set_buffers_geometry( 579 mNativeWindow.get(), 580 def.format.video.nFrameWidth, 581 def.format.video.nFrameHeight, 582 def.format.video.eColorFormat); 583 584 if (err != 0) { 585 ALOGE("native_window_set_buffers_geometry failed: %s (%d)", 586 strerror(-err), -err); 587 return err; 588 } 589 590 // Set up the native window. 591 OMX_U32 usage = 0; 592 err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage); 593 if (err != 0) { 594 ALOGW("querying usage flags from OMX IL component failed: %d", err); 595 // XXX: Currently this error is logged, but not fatal. 596 usage = 0; 597 } 598 599 if (mFlags & kFlagIsSecure) { 600 usage |= GRALLOC_USAGE_PROTECTED; 601 } 602 603 // Make sure to check whether either Stagefright or the video decoder 604 // requested protected buffers. 605 if (usage & GRALLOC_USAGE_PROTECTED) { 606 // Verify that the ANativeWindow sends images directly to 607 // SurfaceFlinger. 608 int queuesToNativeWindow = 0; 609 err = mNativeWindow->query( 610 mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, 611 &queuesToNativeWindow); 612 if (err != 0) { 613 ALOGE("error authenticating native window: %d", err); 614 return err; 615 } 616 if (queuesToNativeWindow != 1) { 617 ALOGE("native window could not be authenticated"); 618 return PERMISSION_DENIED; 619 } 620 } 621 622 err = native_window_set_usage( 623 mNativeWindow.get(), 624 usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP); 625 626 if (err != 0) { 627 ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err); 628 return err; 629 } 630 631 *minUndequeuedBuffers = 0; 632 err = mNativeWindow->query( 633 mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 634 (int *)minUndequeuedBuffers); 635 636 if (err != 0) { 637 ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 638 strerror(-err), -err); 639 return err; 640 } 641 642 // FIXME: assume that surface is controlled by app (native window 643 // returns the number for the case when surface is not controlled by app) 644 // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported 645 // For now, try to allocate 1 more buffer, but don't fail if unsuccessful 646 647 // Use conservative allocation while also trying to reduce starvation 648 // 649 // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the 650 // minimum needed for the consumer to be able to work 651 // 2. try to allocate two (2) additional buffers to reduce starvation from 652 // the consumer 653 // plus an extra buffer to account for incorrect minUndequeuedBufs 654 for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) { 655 OMX_U32 newBufferCount = 656 def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers; 657 def.nBufferCountActual = newBufferCount; 658 err = mOMX->setParameter( 659 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 660 661 if (err == OK) { 662 *minUndequeuedBuffers += extraBuffers; 663 break; 664 } 665 666 ALOGW("[%s] setting nBufferCountActual to %u failed: %d", 667 mComponentName.c_str(), newBufferCount, err); 668 /* exit condition */ 669 if (extraBuffers == 0) { 670 return err; 671 } 672 } 673 674 err = native_window_set_buffer_count( 675 mNativeWindow.get(), def.nBufferCountActual); 676 677 if (err != 0) { 678 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 679 -err); 680 return err; 681 } 682 683 *bufferCount = def.nBufferCountActual; 684 *bufferSize = def.nBufferSize; 685 return err; 686} 687 688status_t ACodec::allocateOutputBuffersFromNativeWindow() { 689 OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers; 690 status_t err = configureOutputBuffersFromNativeWindow( 691 &bufferCount, &bufferSize, &minUndequeuedBuffers); 692 if (err != 0) 693 return err; 694 mNumUndequeuedBuffers = minUndequeuedBuffers; 695 696 ALOGV("[%s] Allocating %u buffers from a native window of size %u on " 697 "output port", 698 mComponentName.c_str(), bufferCount, bufferSize); 699 700 // Dequeue buffers and send them to OMX 701 for (OMX_U32 i = 0; i < bufferCount; i++) { 702 ANativeWindowBuffer *buf; 703 err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf); 704 if (err != 0) { 705 ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 706 break; 707 } 708 709 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 710 BufferInfo info; 711 info.mStatus = BufferInfo::OWNED_BY_US; 712 info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */); 713 info.mGraphicBuffer = graphicBuffer; 714 mBuffers[kPortIndexOutput].push(info); 715 716 IOMX::buffer_id bufferId; 717 err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer, 718 &bufferId); 719 if (err != 0) { 720 ALOGE("registering GraphicBuffer %u with OMX IL component failed: " 721 "%d", i, err); 722 break; 723 } 724 725 mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId; 726 727 ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)", 728 mComponentName.c_str(), 729 bufferId, graphicBuffer.get()); 730 } 731 732 OMX_U32 cancelStart; 733 OMX_U32 cancelEnd; 734 735 if (err != 0) { 736 // If an error occurred while dequeuing we need to cancel any buffers 737 // that were dequeued. 738 cancelStart = 0; 739 cancelEnd = mBuffers[kPortIndexOutput].size(); 740 } else { 741 // Return the required minimum undequeued buffers to the native window. 742 cancelStart = bufferCount - minUndequeuedBuffers; 743 cancelEnd = bufferCount; 744 } 745 746 for (OMX_U32 i = cancelStart; i < cancelEnd; i++) { 747 BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 748 cancelBufferToNativeWindow(info); 749 } 750 751 return err; 752} 753 754status_t ACodec::allocateOutputMetaDataBuffers() { 755 OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers; 756 status_t err = configureOutputBuffersFromNativeWindow( 757 &bufferCount, &bufferSize, &minUndequeuedBuffers); 758 if (err != 0) 759 return err; 760 mNumUndequeuedBuffers = minUndequeuedBuffers; 761 762 ALOGV("[%s] Allocating %u meta buffers on output port", 763 mComponentName.c_str(), bufferCount); 764 765 size_t totalSize = bufferCount * 8; 766 mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec"); 767 768 // Dequeue buffers and send them to OMX 769 for (OMX_U32 i = 0; i < bufferCount; i++) { 770 BufferInfo info; 771 info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 772 info.mGraphicBuffer = NULL; 773 info.mDequeuedAt = mDequeueCounter; 774 775 sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate( 776 sizeof(struct VideoDecoderOutputMetaData)); 777 CHECK(mem.get() != NULL); 778 info.mData = new ABuffer(mem->pointer(), mem->size()); 779 780 // we use useBuffer for metadata regardless of quirks 781 err = mOMX->useBuffer( 782 mNode, kPortIndexOutput, mem, &info.mBufferID); 783 784 mBuffers[kPortIndexOutput].push(info); 785 786 ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)", 787 mComponentName.c_str(), info.mBufferID, mem->pointer()); 788 } 789 790 mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers; 791 return err; 792} 793 794status_t ACodec::submitOutputMetaDataBuffer() { 795 CHECK(mStoreMetaDataInOutputBuffers); 796 if (mMetaDataBuffersToSubmit == 0) 797 return OK; 798 799 BufferInfo *info = dequeueBufferFromNativeWindow(); 800 if (info == NULL) 801 return ERROR_IO; 802 803 ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p", 804 mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get()); 805 806 --mMetaDataBuffersToSubmit; 807 CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID), 808 (status_t)OK); 809 810 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 811 return OK; 812} 813 814status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) { 815 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 816 817 ALOGV("[%s] Calling cancelBuffer on buffer %u", 818 mComponentName.c_str(), info->mBufferID); 819 820 int err = mNativeWindow->cancelBuffer( 821 mNativeWindow.get(), info->mGraphicBuffer.get(), -1); 822 823 CHECK_EQ(err, 0); 824 825 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 826 827 return OK; 828} 829 830ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() { 831 ANativeWindowBuffer *buf; 832 int fenceFd = -1; 833 CHECK(mNativeWindow.get() != NULL); 834 if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) { 835 ALOGE("dequeueBuffer failed."); 836 return NULL; 837 } 838 839 BufferInfo *oldest = NULL; 840 for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { 841 BufferInfo *info = 842 &mBuffers[kPortIndexOutput].editItemAt(i); 843 844 if (info->mGraphicBuffer != NULL && 845 info->mGraphicBuffer->handle == buf->handle) { 846 CHECK_EQ((int)info->mStatus, 847 (int)BufferInfo::OWNED_BY_NATIVE_WINDOW); 848 849 info->mStatus = BufferInfo::OWNED_BY_US; 850 851 return info; 852 } 853 854 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW && 855 (oldest == NULL || 856 // avoid potential issues from counter rolling over 857 mDequeueCounter - info->mDequeuedAt > 858 mDequeueCounter - oldest->mDequeuedAt)) { 859 oldest = info; 860 } 861 } 862 863 if (oldest) { 864 CHECK(mStoreMetaDataInOutputBuffers); 865 866 // discard buffer in LRU info and replace with new buffer 867 oldest->mGraphicBuffer = new GraphicBuffer(buf, false); 868 oldest->mStatus = BufferInfo::OWNED_BY_US; 869 870 mOMX->updateGraphicBufferInMeta( 871 mNode, kPortIndexOutput, oldest->mGraphicBuffer, 872 oldest->mBufferID); 873 874 VideoDecoderOutputMetaData *metaData = 875 reinterpret_cast<VideoDecoderOutputMetaData *>( 876 oldest->mData->base()); 877 CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource); 878 879 ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)", 880 oldest - &mBuffers[kPortIndexOutput][0], 881 mDequeueCounter - oldest->mDequeuedAt, 882 metaData->pHandle, 883 oldest->mGraphicBuffer->handle, oldest->mData->base()); 884 885 return oldest; 886 } 887 888 TRESPASS(); 889 890 return NULL; 891} 892 893status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) { 894 for (size_t i = mBuffers[portIndex].size(); i-- > 0;) { 895 CHECK_EQ((status_t)OK, freeBuffer(portIndex, i)); 896 } 897 898 mDealer[portIndex].clear(); 899 900 return OK; 901} 902 903status_t ACodec::freeOutputBuffersNotOwnedByComponent() { 904 for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { 905 BufferInfo *info = 906 &mBuffers[kPortIndexOutput].editItemAt(i); 907 908 // At this time some buffers may still be with the component 909 // or being drained. 910 if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT && 911 info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) { 912 CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i)); 913 } 914 } 915 916 return OK; 917} 918 919status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) { 920 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 921 922 CHECK(info->mStatus == BufferInfo::OWNED_BY_US 923 || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW); 924 925 if (portIndex == kPortIndexOutput && mNativeWindow != NULL 926 && info->mStatus == BufferInfo::OWNED_BY_US) { 927 CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info)); 928 } 929 930 CHECK_EQ(mOMX->freeBuffer( 931 mNode, portIndex, info->mBufferID), 932 (status_t)OK); 933 934 mBuffers[portIndex].removeAt(i); 935 936 return OK; 937} 938 939ACodec::BufferInfo *ACodec::findBufferByID( 940 uint32_t portIndex, IOMX::buffer_id bufferID, 941 ssize_t *index) { 942 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 943 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 944 945 if (info->mBufferID == bufferID) { 946 if (index != NULL) { 947 *index = i; 948 } 949 return info; 950 } 951 } 952 953 TRESPASS(); 954 955 return NULL; 956} 957 958status_t ACodec::setComponentRole( 959 bool isEncoder, const char *mime) { 960 struct MimeToRole { 961 const char *mime; 962 const char *decoderRole; 963 const char *encoderRole; 964 }; 965 966 static const MimeToRole kMimeToRole[] = { 967 { MEDIA_MIMETYPE_AUDIO_MPEG, 968 "audio_decoder.mp3", "audio_encoder.mp3" }, 969 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I, 970 "audio_decoder.mp1", "audio_encoder.mp1" }, 971 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II, 972 "audio_decoder.mp2", "audio_encoder.mp2" }, 973 { MEDIA_MIMETYPE_AUDIO_AMR_NB, 974 "audio_decoder.amrnb", "audio_encoder.amrnb" }, 975 { MEDIA_MIMETYPE_AUDIO_AMR_WB, 976 "audio_decoder.amrwb", "audio_encoder.amrwb" }, 977 { MEDIA_MIMETYPE_AUDIO_AAC, 978 "audio_decoder.aac", "audio_encoder.aac" }, 979 { MEDIA_MIMETYPE_AUDIO_VORBIS, 980 "audio_decoder.vorbis", "audio_encoder.vorbis" }, 981 { MEDIA_MIMETYPE_AUDIO_OPUS, 982 "audio_decoder.opus", "audio_encoder.opus" }, 983 { MEDIA_MIMETYPE_AUDIO_G711_MLAW, 984 "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" }, 985 { MEDIA_MIMETYPE_AUDIO_G711_ALAW, 986 "audio_decoder.g711alaw", "audio_encoder.g711alaw" }, 987 { MEDIA_MIMETYPE_VIDEO_AVC, 988 "video_decoder.avc", "video_encoder.avc" }, 989 { MEDIA_MIMETYPE_VIDEO_MPEG4, 990 "video_decoder.mpeg4", "video_encoder.mpeg4" }, 991 { MEDIA_MIMETYPE_VIDEO_H263, 992 "video_decoder.h263", "video_encoder.h263" }, 993 { MEDIA_MIMETYPE_VIDEO_VP8, 994 "video_decoder.vp8", "video_encoder.vp8" }, 995 { MEDIA_MIMETYPE_VIDEO_VP9, 996 "video_decoder.vp9", "video_encoder.vp9" }, 997 { MEDIA_MIMETYPE_AUDIO_RAW, 998 "audio_decoder.raw", "audio_encoder.raw" }, 999 { MEDIA_MIMETYPE_AUDIO_FLAC, 1000 "audio_decoder.flac", "audio_encoder.flac" }, 1001 { MEDIA_MIMETYPE_AUDIO_MSGSM, 1002 "audio_decoder.gsm", "audio_encoder.gsm" }, 1003 { MEDIA_MIMETYPE_VIDEO_MPEG2, 1004 "video_decoder.mpeg2", "video_encoder.mpeg2" }, 1005 { MEDIA_MIMETYPE_AUDIO_AC3, 1006 "audio_decoder.ac3", "audio_encoder.ac3" }, 1007 }; 1008 1009 static const size_t kNumMimeToRole = 1010 sizeof(kMimeToRole) / sizeof(kMimeToRole[0]); 1011 1012 size_t i; 1013 for (i = 0; i < kNumMimeToRole; ++i) { 1014 if (!strcasecmp(mime, kMimeToRole[i].mime)) { 1015 break; 1016 } 1017 } 1018 1019 if (i == kNumMimeToRole) { 1020 return ERROR_UNSUPPORTED; 1021 } 1022 1023 const char *role = 1024 isEncoder ? kMimeToRole[i].encoderRole 1025 : kMimeToRole[i].decoderRole; 1026 1027 if (role != NULL) { 1028 OMX_PARAM_COMPONENTROLETYPE roleParams; 1029 InitOMXParams(&roleParams); 1030 1031 strncpy((char *)roleParams.cRole, 1032 role, OMX_MAX_STRINGNAME_SIZE - 1); 1033 1034 roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 1035 1036 status_t err = mOMX->setParameter( 1037 mNode, OMX_IndexParamStandardComponentRole, 1038 &roleParams, sizeof(roleParams)); 1039 1040 if (err != OK) { 1041 ALOGW("[%s] Failed to set standard component role '%s'.", 1042 mComponentName.c_str(), role); 1043 1044 return err; 1045 } 1046 } 1047 1048 return OK; 1049} 1050 1051status_t ACodec::configureCodec( 1052 const char *mime, const sp<AMessage> &msg) { 1053 int32_t encoder; 1054 if (!msg->findInt32("encoder", &encoder)) { 1055 encoder = false; 1056 } 1057 1058 sp<AMessage> inputFormat = new AMessage(); 1059 sp<AMessage> outputFormat = new AMessage(); 1060 1061 mIsEncoder = encoder; 1062 1063 status_t err = setComponentRole(encoder /* isEncoder */, mime); 1064 1065 if (err != OK) { 1066 return err; 1067 } 1068 1069 int32_t bitRate = 0; 1070 // FLAC encoder doesn't need a bitrate, other encoders do 1071 if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC) 1072 && !msg->findInt32("bitrate", &bitRate)) { 1073 return INVALID_OPERATION; 1074 } 1075 1076 int32_t storeMeta; 1077 if (encoder 1078 && msg->findInt32("store-metadata-in-buffers", &storeMeta) 1079 && storeMeta != 0) { 1080 err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE); 1081 1082 if (err != OK) { 1083 ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d", 1084 mComponentName.c_str(), err); 1085 1086 return err; 1087 } 1088 } 1089 1090 int32_t prependSPSPPS = 0; 1091 if (encoder 1092 && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS) 1093 && prependSPSPPS != 0) { 1094 OMX_INDEXTYPE index; 1095 err = mOMX->getExtensionIndex( 1096 mNode, 1097 "OMX.google.android.index.prependSPSPPSToIDRFrames", 1098 &index); 1099 1100 if (err == OK) { 1101 PrependSPSPPSToIDRFramesParams params; 1102 InitOMXParams(¶ms); 1103 params.bEnable = OMX_TRUE; 1104 1105 err = mOMX->setParameter( 1106 mNode, index, ¶ms, sizeof(params)); 1107 } 1108 1109 if (err != OK) { 1110 ALOGE("Encoder could not be configured to emit SPS/PPS before " 1111 "IDR frames. (err %d)", err); 1112 1113 return err; 1114 } 1115 } 1116 1117 // Only enable metadata mode on encoder output if encoder can prepend 1118 // sps/pps to idr frames, since in metadata mode the bitstream is in an 1119 // opaque handle, to which we don't have access. 1120 int32_t video = !strncasecmp(mime, "video/", 6); 1121 if (encoder && video) { 1122 OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS 1123 && msg->findInt32("store-metadata-in-buffers-output", &storeMeta) 1124 && storeMeta != 0); 1125 1126 err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable); 1127 1128 if (err != OK) { 1129 ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d", 1130 mComponentName.c_str(), err); 1131 mUseMetadataOnEncoderOutput = 0; 1132 } else { 1133 mUseMetadataOnEncoderOutput = enable; 1134 } 1135 1136 if (!msg->findInt64( 1137 "repeat-previous-frame-after", 1138 &mRepeatFrameDelayUs)) { 1139 mRepeatFrameDelayUs = -1ll; 1140 } 1141 1142 if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) { 1143 mMaxPtsGapUs = -1ll; 1144 } 1145 1146 if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) { 1147 mTimePerCaptureUs = -1ll; 1148 } 1149 1150 if (!msg->findInt32( 1151 "create-input-buffers-suspended", 1152 (int32_t*)&mCreateInputBuffersSuspended)) { 1153 mCreateInputBuffersSuspended = false; 1154 } 1155 } 1156 1157 // Always try to enable dynamic output buffers on native surface 1158 sp<RefBase> obj; 1159 int32_t haveNativeWindow = msg->findObject("native-window", &obj) && 1160 obj != NULL; 1161 mStoreMetaDataInOutputBuffers = false; 1162 if (video && !encoder) { 1163 inputFormat->setInt32("adaptive-playback", false); 1164 } 1165 if (!encoder && video && haveNativeWindow) { 1166 err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE); 1167 if (err != OK) { 1168 ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d", 1169 mComponentName.c_str(), err); 1170 1171 // if adaptive playback has been requested, try JB fallback 1172 // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS 1173 // LARGE MEMORY REQUIREMENT 1174 1175 // we will not do adaptive playback on software accessed 1176 // surfaces as they never had to respond to changes in the 1177 // crop window, and we don't trust that they will be able to. 1178 int usageBits = 0; 1179 bool canDoAdaptivePlayback; 1180 1181 sp<NativeWindowWrapper> windowWrapper( 1182 static_cast<NativeWindowWrapper *>(obj.get())); 1183 sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow(); 1184 1185 if (nativeWindow->query( 1186 nativeWindow.get(), 1187 NATIVE_WINDOW_CONSUMER_USAGE_BITS, 1188 &usageBits) != OK) { 1189 canDoAdaptivePlayback = false; 1190 } else { 1191 canDoAdaptivePlayback = 1192 (usageBits & 1193 (GRALLOC_USAGE_SW_READ_MASK | 1194 GRALLOC_USAGE_SW_WRITE_MASK)) == 0; 1195 } 1196 1197 int32_t maxWidth = 0, maxHeight = 0; 1198 if (canDoAdaptivePlayback && 1199 msg->findInt32("max-width", &maxWidth) && 1200 msg->findInt32("max-height", &maxHeight)) { 1201 ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)", 1202 mComponentName.c_str(), maxWidth, maxHeight); 1203 1204 err = mOMX->prepareForAdaptivePlayback( 1205 mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight); 1206 ALOGW_IF(err != OK, 1207 "[%s] prepareForAdaptivePlayback failed w/ err %d", 1208 mComponentName.c_str(), err); 1209 1210 if (err == OK) { 1211 inputFormat->setInt32("max-width", maxWidth); 1212 inputFormat->setInt32("max-height", maxHeight); 1213 inputFormat->setInt32("adaptive-playback", true); 1214 } 1215 } 1216 // allow failure 1217 err = OK; 1218 } else { 1219 ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str()); 1220 mStoreMetaDataInOutputBuffers = true; 1221 inputFormat->setInt32("adaptive-playback", true); 1222 } 1223 1224 int32_t push; 1225 if (msg->findInt32("push-blank-buffers-on-shutdown", &push) 1226 && push != 0) { 1227 mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 1228 } 1229 } 1230 1231 if (video) { 1232 if (encoder) { 1233 err = setupVideoEncoder(mime, msg); 1234 } else { 1235 int32_t width, height; 1236 if (!msg->findInt32("width", &width) 1237 || !msg->findInt32("height", &height)) { 1238 err = INVALID_OPERATION; 1239 } else { 1240 err = setupVideoDecoder(mime, width, height); 1241 } 1242 } 1243 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { 1244 int32_t numChannels, sampleRate; 1245 if (!msg->findInt32("channel-count", &numChannels) 1246 || !msg->findInt32("sample-rate", &sampleRate)) { 1247 // Since we did not always check for these, leave them optional 1248 // and have the decoder figure it all out. 1249 err = OK; 1250 } else { 1251 err = setupRawAudioFormat( 1252 encoder ? kPortIndexInput : kPortIndexOutput, 1253 sampleRate, 1254 numChannels); 1255 } 1256 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1257 int32_t numChannels, sampleRate; 1258 if (!msg->findInt32("channel-count", &numChannels) 1259 || !msg->findInt32("sample-rate", &sampleRate)) { 1260 err = INVALID_OPERATION; 1261 } else { 1262 int32_t isADTS, aacProfile; 1263 if (!msg->findInt32("is-adts", &isADTS)) { 1264 isADTS = 0; 1265 } 1266 if (!msg->findInt32("aac-profile", &aacProfile)) { 1267 aacProfile = OMX_AUDIO_AACObjectNull; 1268 } 1269 1270 err = setupAACCodec( 1271 encoder, numChannels, sampleRate, bitRate, aacProfile, 1272 isADTS != 0); 1273 } 1274 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 1275 err = setupAMRCodec(encoder, false /* isWAMR */, bitRate); 1276 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 1277 err = setupAMRCodec(encoder, true /* isWAMR */, bitRate); 1278 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW) 1279 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) { 1280 // These are PCM-like formats with a fixed sample rate but 1281 // a variable number of channels. 1282 1283 int32_t numChannels; 1284 if (!msg->findInt32("channel-count", &numChannels)) { 1285 err = INVALID_OPERATION; 1286 } else { 1287 err = setupG711Codec(encoder, numChannels); 1288 } 1289 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) { 1290 int32_t numChannels, sampleRate, compressionLevel = -1; 1291 if (encoder && 1292 (!msg->findInt32("channel-count", &numChannels) 1293 || !msg->findInt32("sample-rate", &sampleRate))) { 1294 ALOGE("missing channel count or sample rate for FLAC encoder"); 1295 err = INVALID_OPERATION; 1296 } else { 1297 if (encoder) { 1298 if (!msg->findInt32( 1299 "flac-compression-level", &compressionLevel)) { 1300 compressionLevel = 5;// default FLAC compression level 1301 } else if (compressionLevel < 0) { 1302 ALOGW("compression level %d outside [0..8] range, " 1303 "using 0", 1304 compressionLevel); 1305 compressionLevel = 0; 1306 } else if (compressionLevel > 8) { 1307 ALOGW("compression level %d outside [0..8] range, " 1308 "using 8", 1309 compressionLevel); 1310 compressionLevel = 8; 1311 } 1312 } 1313 err = setupFlacCodec( 1314 encoder, numChannels, sampleRate, compressionLevel); 1315 } 1316 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) { 1317 int32_t numChannels, sampleRate; 1318 if (encoder 1319 || !msg->findInt32("channel-count", &numChannels) 1320 || !msg->findInt32("sample-rate", &sampleRate)) { 1321 err = INVALID_OPERATION; 1322 } else { 1323 err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 1324 } 1325 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) { 1326 int32_t numChannels; 1327 int32_t sampleRate; 1328 if (!msg->findInt32("channel-count", &numChannels) 1329 || !msg->findInt32("sample-rate", &sampleRate)) { 1330 err = INVALID_OPERATION; 1331 } else { 1332 err = setupAC3Codec(encoder, numChannels, sampleRate); 1333 } 1334 } 1335 1336 if (err != OK) { 1337 return err; 1338 } 1339 1340 if (!msg->findInt32("encoder-delay", &mEncoderDelay)) { 1341 mEncoderDelay = 0; 1342 } 1343 1344 if (!msg->findInt32("encoder-padding", &mEncoderPadding)) { 1345 mEncoderPadding = 0; 1346 } 1347 1348 if (msg->findInt32("channel-mask", &mChannelMask)) { 1349 mChannelMaskPresent = true; 1350 } else { 1351 mChannelMaskPresent = false; 1352 } 1353 1354 int32_t maxInputSize; 1355 if (msg->findInt32("max-input-size", &maxInputSize)) { 1356 err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize); 1357 } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) { 1358 err = setMinBufferSize(kPortIndexInput, 8192); // XXX 1359 } 1360 1361 CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK); 1362 CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK); 1363 mInputFormat = inputFormat; 1364 mOutputFormat = outputFormat; 1365 1366 return err; 1367} 1368 1369status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) { 1370 OMX_PARAM_PORTDEFINITIONTYPE def; 1371 InitOMXParams(&def); 1372 def.nPortIndex = portIndex; 1373 1374 status_t err = mOMX->getParameter( 1375 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1376 1377 if (err != OK) { 1378 return err; 1379 } 1380 1381 if (def.nBufferSize >= size) { 1382 return OK; 1383 } 1384 1385 def.nBufferSize = size; 1386 1387 err = mOMX->setParameter( 1388 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1389 1390 if (err != OK) { 1391 return err; 1392 } 1393 1394 err = mOMX->getParameter( 1395 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1396 1397 if (err != OK) { 1398 return err; 1399 } 1400 1401 CHECK(def.nBufferSize >= size); 1402 1403 return OK; 1404} 1405 1406status_t ACodec::selectAudioPortFormat( 1407 OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) { 1408 OMX_AUDIO_PARAM_PORTFORMATTYPE format; 1409 InitOMXParams(&format); 1410 1411 format.nPortIndex = portIndex; 1412 for (OMX_U32 index = 0;; ++index) { 1413 format.nIndex = index; 1414 1415 status_t err = mOMX->getParameter( 1416 mNode, OMX_IndexParamAudioPortFormat, 1417 &format, sizeof(format)); 1418 1419 if (err != OK) { 1420 return err; 1421 } 1422 1423 if (format.eEncoding == desiredFormat) { 1424 break; 1425 } 1426 } 1427 1428 return mOMX->setParameter( 1429 mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format)); 1430} 1431 1432status_t ACodec::setupAACCodec( 1433 bool encoder, int32_t numChannels, int32_t sampleRate, 1434 int32_t bitRate, int32_t aacProfile, bool isADTS) { 1435 if (encoder && isADTS) { 1436 return -EINVAL; 1437 } 1438 1439 status_t err = setupRawAudioFormat( 1440 encoder ? kPortIndexInput : kPortIndexOutput, 1441 sampleRate, 1442 numChannels); 1443 1444 if (err != OK) { 1445 return err; 1446 } 1447 1448 if (encoder) { 1449 err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC); 1450 1451 if (err != OK) { 1452 return err; 1453 } 1454 1455 OMX_PARAM_PORTDEFINITIONTYPE def; 1456 InitOMXParams(&def); 1457 def.nPortIndex = kPortIndexOutput; 1458 1459 err = mOMX->getParameter( 1460 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1461 1462 if (err != OK) { 1463 return err; 1464 } 1465 1466 def.format.audio.bFlagErrorConcealment = OMX_TRUE; 1467 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 1468 1469 err = mOMX->setParameter( 1470 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1471 1472 if (err != OK) { 1473 return err; 1474 } 1475 1476 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 1477 InitOMXParams(&profile); 1478 profile.nPortIndex = kPortIndexOutput; 1479 1480 err = mOMX->getParameter( 1481 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1482 1483 if (err != OK) { 1484 return err; 1485 } 1486 1487 profile.nChannels = numChannels; 1488 1489 profile.eChannelMode = 1490 (numChannels == 1) 1491 ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo; 1492 1493 profile.nSampleRate = sampleRate; 1494 profile.nBitRate = bitRate; 1495 profile.nAudioBandWidth = 0; 1496 profile.nFrameLength = 0; 1497 profile.nAACtools = OMX_AUDIO_AACToolAll; 1498 profile.nAACERtools = OMX_AUDIO_AACERNone; 1499 profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile; 1500 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; 1501 1502 err = mOMX->setParameter( 1503 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1504 1505 if (err != OK) { 1506 return err; 1507 } 1508 1509 return err; 1510 } 1511 1512 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 1513 InitOMXParams(&profile); 1514 profile.nPortIndex = kPortIndexInput; 1515 1516 err = mOMX->getParameter( 1517 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1518 1519 if (err != OK) { 1520 return err; 1521 } 1522 1523 profile.nChannels = numChannels; 1524 profile.nSampleRate = sampleRate; 1525 1526 profile.eAACStreamFormat = 1527 isADTS 1528 ? OMX_AUDIO_AACStreamFormatMP4ADTS 1529 : OMX_AUDIO_AACStreamFormatMP4FF; 1530 1531 return mOMX->setParameter( 1532 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1533} 1534 1535status_t ACodec::setupAC3Codec( 1536 bool encoder, int32_t numChannels, int32_t sampleRate) { 1537 status_t err = setupRawAudioFormat( 1538 encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels); 1539 1540 if (err != OK) { 1541 return err; 1542 } 1543 1544 if (encoder) { 1545 ALOGW("AC3 encoding is not supported."); 1546 return INVALID_OPERATION; 1547 } 1548 1549 OMX_AUDIO_PARAM_ANDROID_AC3TYPE def; 1550 InitOMXParams(&def); 1551 def.nPortIndex = kPortIndexInput; 1552 1553 err = mOMX->getParameter( 1554 mNode, 1555 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 1556 &def, 1557 sizeof(def)); 1558 1559 if (err != OK) { 1560 return err; 1561 } 1562 1563 def.nChannels = numChannels; 1564 def.nSampleRate = sampleRate; 1565 1566 return mOMX->setParameter( 1567 mNode, 1568 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 1569 &def, 1570 sizeof(def)); 1571} 1572 1573static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate( 1574 bool isAMRWB, int32_t bps) { 1575 if (isAMRWB) { 1576 if (bps <= 6600) { 1577 return OMX_AUDIO_AMRBandModeWB0; 1578 } else if (bps <= 8850) { 1579 return OMX_AUDIO_AMRBandModeWB1; 1580 } else if (bps <= 12650) { 1581 return OMX_AUDIO_AMRBandModeWB2; 1582 } else if (bps <= 14250) { 1583 return OMX_AUDIO_AMRBandModeWB3; 1584 } else if (bps <= 15850) { 1585 return OMX_AUDIO_AMRBandModeWB4; 1586 } else if (bps <= 18250) { 1587 return OMX_AUDIO_AMRBandModeWB5; 1588 } else if (bps <= 19850) { 1589 return OMX_AUDIO_AMRBandModeWB6; 1590 } else if (bps <= 23050) { 1591 return OMX_AUDIO_AMRBandModeWB7; 1592 } 1593 1594 // 23850 bps 1595 return OMX_AUDIO_AMRBandModeWB8; 1596 } else { // AMRNB 1597 if (bps <= 4750) { 1598 return OMX_AUDIO_AMRBandModeNB0; 1599 } else if (bps <= 5150) { 1600 return OMX_AUDIO_AMRBandModeNB1; 1601 } else if (bps <= 5900) { 1602 return OMX_AUDIO_AMRBandModeNB2; 1603 } else if (bps <= 6700) { 1604 return OMX_AUDIO_AMRBandModeNB3; 1605 } else if (bps <= 7400) { 1606 return OMX_AUDIO_AMRBandModeNB4; 1607 } else if (bps <= 7950) { 1608 return OMX_AUDIO_AMRBandModeNB5; 1609 } else if (bps <= 10200) { 1610 return OMX_AUDIO_AMRBandModeNB6; 1611 } 1612 1613 // 12200 bps 1614 return OMX_AUDIO_AMRBandModeNB7; 1615 } 1616} 1617 1618status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) { 1619 OMX_AUDIO_PARAM_AMRTYPE def; 1620 InitOMXParams(&def); 1621 def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput; 1622 1623 status_t err = 1624 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 1625 1626 if (err != OK) { 1627 return err; 1628 } 1629 1630 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 1631 def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate); 1632 1633 err = mOMX->setParameter( 1634 mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 1635 1636 if (err != OK) { 1637 return err; 1638 } 1639 1640 return setupRawAudioFormat( 1641 encoder ? kPortIndexInput : kPortIndexOutput, 1642 isWAMR ? 16000 : 8000 /* sampleRate */, 1643 1 /* numChannels */); 1644} 1645 1646status_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) { 1647 CHECK(!encoder); // XXX TODO 1648 1649 return setupRawAudioFormat( 1650 kPortIndexInput, 8000 /* sampleRate */, numChannels); 1651} 1652 1653status_t ACodec::setupFlacCodec( 1654 bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) { 1655 1656 if (encoder) { 1657 OMX_AUDIO_PARAM_FLACTYPE def; 1658 InitOMXParams(&def); 1659 def.nPortIndex = kPortIndexOutput; 1660 1661 // configure compression level 1662 status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def)); 1663 if (err != OK) { 1664 ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err); 1665 return err; 1666 } 1667 def.nCompressionLevel = compressionLevel; 1668 err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def)); 1669 if (err != OK) { 1670 ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err); 1671 return err; 1672 } 1673 } 1674 1675 return setupRawAudioFormat( 1676 encoder ? kPortIndexInput : kPortIndexOutput, 1677 sampleRate, 1678 numChannels); 1679} 1680 1681status_t ACodec::setupRawAudioFormat( 1682 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 1683 OMX_PARAM_PORTDEFINITIONTYPE def; 1684 InitOMXParams(&def); 1685 def.nPortIndex = portIndex; 1686 1687 status_t err = mOMX->getParameter( 1688 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1689 1690 if (err != OK) { 1691 return err; 1692 } 1693 1694 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 1695 1696 err = mOMX->setParameter( 1697 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1698 1699 if (err != OK) { 1700 return err; 1701 } 1702 1703 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 1704 InitOMXParams(&pcmParams); 1705 pcmParams.nPortIndex = portIndex; 1706 1707 err = mOMX->getParameter( 1708 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 1709 1710 if (err != OK) { 1711 return err; 1712 } 1713 1714 pcmParams.nChannels = numChannels; 1715 pcmParams.eNumData = OMX_NumericalDataSigned; 1716 pcmParams.bInterleaved = OMX_TRUE; 1717 pcmParams.nBitPerSample = 16; 1718 pcmParams.nSamplingRate = sampleRate; 1719 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 1720 1721 if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) { 1722 return OMX_ErrorNone; 1723 } 1724 1725 return mOMX->setParameter( 1726 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 1727} 1728 1729status_t ACodec::setVideoPortFormatType( 1730 OMX_U32 portIndex, 1731 OMX_VIDEO_CODINGTYPE compressionFormat, 1732 OMX_COLOR_FORMATTYPE colorFormat) { 1733 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 1734 InitOMXParams(&format); 1735 format.nPortIndex = portIndex; 1736 format.nIndex = 0; 1737 bool found = false; 1738 1739 OMX_U32 index = 0; 1740 for (;;) { 1741 format.nIndex = index; 1742 status_t err = mOMX->getParameter( 1743 mNode, OMX_IndexParamVideoPortFormat, 1744 &format, sizeof(format)); 1745 1746 if (err != OK) { 1747 return err; 1748 } 1749 1750 // The following assertion is violated by TI's video decoder. 1751 // CHECK_EQ(format.nIndex, index); 1752 1753 if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) { 1754 if (portIndex == kPortIndexInput 1755 && colorFormat == format.eColorFormat) { 1756 // eCompressionFormat does not seem right. 1757 found = true; 1758 break; 1759 } 1760 if (portIndex == kPortIndexOutput 1761 && compressionFormat == format.eCompressionFormat) { 1762 // eColorFormat does not seem right. 1763 found = true; 1764 break; 1765 } 1766 } 1767 1768 if (format.eCompressionFormat == compressionFormat 1769 && format.eColorFormat == colorFormat) { 1770 found = true; 1771 break; 1772 } 1773 1774 ++index; 1775 } 1776 1777 if (!found) { 1778 return UNKNOWN_ERROR; 1779 } 1780 1781 status_t err = mOMX->setParameter( 1782 mNode, OMX_IndexParamVideoPortFormat, 1783 &format, sizeof(format)); 1784 1785 return err; 1786} 1787 1788status_t ACodec::setSupportedOutputFormat() { 1789 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 1790 InitOMXParams(&format); 1791 format.nPortIndex = kPortIndexOutput; 1792 format.nIndex = 0; 1793 1794 status_t err = mOMX->getParameter( 1795 mNode, OMX_IndexParamVideoPortFormat, 1796 &format, sizeof(format)); 1797 CHECK_EQ(err, (status_t)OK); 1798 CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused); 1799 1800 return mOMX->setParameter( 1801 mNode, OMX_IndexParamVideoPortFormat, 1802 &format, sizeof(format)); 1803} 1804 1805static const struct VideoCodingMapEntry { 1806 const char *mMime; 1807 OMX_VIDEO_CODINGTYPE mVideoCodingType; 1808} kVideoCodingMapEntry[] = { 1809 { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC }, 1810 { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 }, 1811 { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 }, 1812 { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 }, 1813 { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 }, 1814 { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 }, 1815}; 1816 1817static status_t GetVideoCodingTypeFromMime( 1818 const char *mime, OMX_VIDEO_CODINGTYPE *codingType) { 1819 for (size_t i = 0; 1820 i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]); 1821 ++i) { 1822 if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) { 1823 *codingType = kVideoCodingMapEntry[i].mVideoCodingType; 1824 return OK; 1825 } 1826 } 1827 1828 *codingType = OMX_VIDEO_CodingUnused; 1829 1830 return ERROR_UNSUPPORTED; 1831} 1832 1833static status_t GetMimeTypeForVideoCoding( 1834 OMX_VIDEO_CODINGTYPE codingType, AString *mime) { 1835 for (size_t i = 0; 1836 i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]); 1837 ++i) { 1838 if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) { 1839 *mime = kVideoCodingMapEntry[i].mMime; 1840 return OK; 1841 } 1842 } 1843 1844 mime->clear(); 1845 1846 return ERROR_UNSUPPORTED; 1847} 1848 1849status_t ACodec::setupVideoDecoder( 1850 const char *mime, int32_t width, int32_t height) { 1851 OMX_VIDEO_CODINGTYPE compressionFormat; 1852 status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat); 1853 1854 if (err != OK) { 1855 return err; 1856 } 1857 1858 err = setVideoPortFormatType( 1859 kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 1860 1861 if (err != OK) { 1862 return err; 1863 } 1864 1865 err = setSupportedOutputFormat(); 1866 1867 if (err != OK) { 1868 return err; 1869 } 1870 1871 err = setVideoFormatOnPort( 1872 kPortIndexInput, width, height, compressionFormat); 1873 1874 if (err != OK) { 1875 return err; 1876 } 1877 1878 err = setVideoFormatOnPort( 1879 kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused); 1880 1881 if (err != OK) { 1882 return err; 1883 } 1884 1885 return OK; 1886} 1887 1888status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) { 1889 int32_t tmp; 1890 if (!msg->findInt32("color-format", &tmp)) { 1891 return INVALID_OPERATION; 1892 } 1893 1894 OMX_COLOR_FORMATTYPE colorFormat = 1895 static_cast<OMX_COLOR_FORMATTYPE>(tmp); 1896 1897 status_t err = setVideoPortFormatType( 1898 kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat); 1899 1900 if (err != OK) { 1901 ALOGE("[%s] does not support color format %d", 1902 mComponentName.c_str(), colorFormat); 1903 1904 return err; 1905 } 1906 1907 /* Input port configuration */ 1908 1909 OMX_PARAM_PORTDEFINITIONTYPE def; 1910 InitOMXParams(&def); 1911 1912 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 1913 1914 def.nPortIndex = kPortIndexInput; 1915 1916 err = mOMX->getParameter( 1917 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1918 1919 if (err != OK) { 1920 return err; 1921 } 1922 1923 int32_t width, height, bitrate; 1924 if (!msg->findInt32("width", &width) 1925 || !msg->findInt32("height", &height) 1926 || !msg->findInt32("bitrate", &bitrate)) { 1927 return INVALID_OPERATION; 1928 } 1929 1930 video_def->nFrameWidth = width; 1931 video_def->nFrameHeight = height; 1932 1933 int32_t stride; 1934 if (!msg->findInt32("stride", &stride)) { 1935 stride = width; 1936 } 1937 1938 video_def->nStride = stride; 1939 1940 int32_t sliceHeight; 1941 if (!msg->findInt32("slice-height", &sliceHeight)) { 1942 sliceHeight = height; 1943 } 1944 1945 video_def->nSliceHeight = sliceHeight; 1946 1947 def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2; 1948 1949 float frameRate; 1950 if (!msg->findFloat("frame-rate", &frameRate)) { 1951 int32_t tmp; 1952 if (!msg->findInt32("frame-rate", &tmp)) { 1953 return INVALID_OPERATION; 1954 } 1955 frameRate = (float)tmp; 1956 mTimePerFrameUs = (int64_t) (1000000.0f / frameRate); 1957 } 1958 1959 video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f); 1960 video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; 1961 video_def->eColorFormat = colorFormat; 1962 1963 err = mOMX->setParameter( 1964 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1965 1966 if (err != OK) { 1967 ALOGE("[%s] failed to set input port definition parameters.", 1968 mComponentName.c_str()); 1969 1970 return err; 1971 } 1972 1973 /* Output port configuration */ 1974 1975 OMX_VIDEO_CODINGTYPE compressionFormat; 1976 err = GetVideoCodingTypeFromMime(mime, &compressionFormat); 1977 1978 if (err != OK) { 1979 return err; 1980 } 1981 1982 err = setVideoPortFormatType( 1983 kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused); 1984 1985 if (err != OK) { 1986 ALOGE("[%s] does not support compression format %d", 1987 mComponentName.c_str(), compressionFormat); 1988 1989 return err; 1990 } 1991 1992 def.nPortIndex = kPortIndexOutput; 1993 1994 err = mOMX->getParameter( 1995 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1996 1997 if (err != OK) { 1998 return err; 1999 } 2000 2001 video_def->nFrameWidth = width; 2002 video_def->nFrameHeight = height; 2003 video_def->xFramerate = 0; 2004 video_def->nBitrate = bitrate; 2005 video_def->eCompressionFormat = compressionFormat; 2006 video_def->eColorFormat = OMX_COLOR_FormatUnused; 2007 2008 err = mOMX->setParameter( 2009 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2010 2011 if (err != OK) { 2012 ALOGE("[%s] failed to set output port definition parameters.", 2013 mComponentName.c_str()); 2014 2015 return err; 2016 } 2017 2018 switch (compressionFormat) { 2019 case OMX_VIDEO_CodingMPEG4: 2020 err = setupMPEG4EncoderParameters(msg); 2021 break; 2022 2023 case OMX_VIDEO_CodingH263: 2024 err = setupH263EncoderParameters(msg); 2025 break; 2026 2027 case OMX_VIDEO_CodingAVC: 2028 err = setupAVCEncoderParameters(msg); 2029 break; 2030 2031 case OMX_VIDEO_CodingVP8: 2032 case OMX_VIDEO_CodingVP9: 2033 err = setupVPXEncoderParameters(msg); 2034 break; 2035 2036 default: 2037 break; 2038 } 2039 2040 ALOGI("setupVideoEncoder succeeded"); 2041 2042 return err; 2043} 2044 2045status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) { 2046 OMX_VIDEO_PARAM_INTRAREFRESHTYPE params; 2047 InitOMXParams(¶ms); 2048 params.nPortIndex = kPortIndexOutput; 2049 2050 params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode); 2051 2052 if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic || 2053 params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 2054 int32_t mbs; 2055 if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) { 2056 return INVALID_OPERATION; 2057 } 2058 params.nCirMBs = mbs; 2059 } 2060 2061 if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive || 2062 params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 2063 int32_t mbs; 2064 if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) { 2065 return INVALID_OPERATION; 2066 } 2067 params.nAirMBs = mbs; 2068 2069 int32_t ref; 2070 if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) { 2071 return INVALID_OPERATION; 2072 } 2073 params.nAirRef = ref; 2074 } 2075 2076 status_t err = mOMX->setParameter( 2077 mNode, OMX_IndexParamVideoIntraRefresh, 2078 ¶ms, sizeof(params)); 2079 return err; 2080} 2081 2082static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) { 2083 if (iFramesInterval < 0) { 2084 return 0xFFFFFFFF; 2085 } else if (iFramesInterval == 0) { 2086 return 0; 2087 } 2088 OMX_U32 ret = frameRate * iFramesInterval; 2089 CHECK(ret > 1); 2090 return ret; 2091} 2092 2093static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) { 2094 int32_t tmp; 2095 if (!msg->findInt32("bitrate-mode", &tmp)) { 2096 return OMX_Video_ControlRateVariable; 2097 } 2098 2099 return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp); 2100} 2101 2102status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) { 2103 int32_t bitrate, iFrameInterval; 2104 if (!msg->findInt32("bitrate", &bitrate) 2105 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 2106 return INVALID_OPERATION; 2107 } 2108 2109 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 2110 2111 float frameRate; 2112 if (!msg->findFloat("frame-rate", &frameRate)) { 2113 int32_t tmp; 2114 if (!msg->findInt32("frame-rate", &tmp)) { 2115 return INVALID_OPERATION; 2116 } 2117 frameRate = (float)tmp; 2118 } 2119 2120 OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type; 2121 InitOMXParams(&mpeg4type); 2122 mpeg4type.nPortIndex = kPortIndexOutput; 2123 2124 status_t err = mOMX->getParameter( 2125 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 2126 2127 if (err != OK) { 2128 return err; 2129 } 2130 2131 mpeg4type.nSliceHeaderSpacing = 0; 2132 mpeg4type.bSVH = OMX_FALSE; 2133 mpeg4type.bGov = OMX_FALSE; 2134 2135 mpeg4type.nAllowedPictureTypes = 2136 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 2137 2138 mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 2139 if (mpeg4type.nPFrames == 0) { 2140 mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 2141 } 2142 mpeg4type.nBFrames = 0; 2143 mpeg4type.nIDCVLCThreshold = 0; 2144 mpeg4type.bACPred = OMX_TRUE; 2145 mpeg4type.nMaxPacketSize = 256; 2146 mpeg4type.nTimeIncRes = 1000; 2147 mpeg4type.nHeaderExtension = 0; 2148 mpeg4type.bReversibleVLC = OMX_FALSE; 2149 2150 int32_t profile; 2151 if (msg->findInt32("profile", &profile)) { 2152 int32_t level; 2153 if (!msg->findInt32("level", &level)) { 2154 return INVALID_OPERATION; 2155 } 2156 2157 err = verifySupportForProfileAndLevel(profile, level); 2158 2159 if (err != OK) { 2160 return err; 2161 } 2162 2163 mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile); 2164 mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level); 2165 } 2166 2167 err = mOMX->setParameter( 2168 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 2169 2170 if (err != OK) { 2171 return err; 2172 } 2173 2174 err = configureBitrate(bitrate, bitrateMode); 2175 2176 if (err != OK) { 2177 return err; 2178 } 2179 2180 return setupErrorCorrectionParameters(); 2181} 2182 2183status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) { 2184 int32_t bitrate, iFrameInterval; 2185 if (!msg->findInt32("bitrate", &bitrate) 2186 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 2187 return INVALID_OPERATION; 2188 } 2189 2190 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 2191 2192 float frameRate; 2193 if (!msg->findFloat("frame-rate", &frameRate)) { 2194 int32_t tmp; 2195 if (!msg->findInt32("frame-rate", &tmp)) { 2196 return INVALID_OPERATION; 2197 } 2198 frameRate = (float)tmp; 2199 } 2200 2201 OMX_VIDEO_PARAM_H263TYPE h263type; 2202 InitOMXParams(&h263type); 2203 h263type.nPortIndex = kPortIndexOutput; 2204 2205 status_t err = mOMX->getParameter( 2206 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 2207 2208 if (err != OK) { 2209 return err; 2210 } 2211 2212 h263type.nAllowedPictureTypes = 2213 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 2214 2215 h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 2216 if (h263type.nPFrames == 0) { 2217 h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 2218 } 2219 h263type.nBFrames = 0; 2220 2221 int32_t profile; 2222 if (msg->findInt32("profile", &profile)) { 2223 int32_t level; 2224 if (!msg->findInt32("level", &level)) { 2225 return INVALID_OPERATION; 2226 } 2227 2228 err = verifySupportForProfileAndLevel(profile, level); 2229 2230 if (err != OK) { 2231 return err; 2232 } 2233 2234 h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile); 2235 h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level); 2236 } 2237 2238 h263type.bPLUSPTYPEAllowed = OMX_FALSE; 2239 h263type.bForceRoundingTypeToZero = OMX_FALSE; 2240 h263type.nPictureHeaderRepetition = 0; 2241 h263type.nGOBHeaderInterval = 0; 2242 2243 err = mOMX->setParameter( 2244 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 2245 2246 if (err != OK) { 2247 return err; 2248 } 2249 2250 err = configureBitrate(bitrate, bitrateMode); 2251 2252 if (err != OK) { 2253 return err; 2254 } 2255 2256 return setupErrorCorrectionParameters(); 2257} 2258 2259status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) { 2260 int32_t bitrate, iFrameInterval; 2261 if (!msg->findInt32("bitrate", &bitrate) 2262 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 2263 return INVALID_OPERATION; 2264 } 2265 2266 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 2267 2268 float frameRate; 2269 if (!msg->findFloat("frame-rate", &frameRate)) { 2270 int32_t tmp; 2271 if (!msg->findInt32("frame-rate", &tmp)) { 2272 return INVALID_OPERATION; 2273 } 2274 frameRate = (float)tmp; 2275 } 2276 2277 status_t err = OK; 2278 int32_t intraRefreshMode = 0; 2279 if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) { 2280 err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode); 2281 if (err != OK) { 2282 ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x", 2283 err, intraRefreshMode); 2284 return err; 2285 } 2286 } 2287 2288 OMX_VIDEO_PARAM_AVCTYPE h264type; 2289 InitOMXParams(&h264type); 2290 h264type.nPortIndex = kPortIndexOutput; 2291 2292 err = mOMX->getParameter( 2293 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 2294 2295 if (err != OK) { 2296 return err; 2297 } 2298 2299 h264type.nAllowedPictureTypes = 2300 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 2301 2302 int32_t profile; 2303 if (msg->findInt32("profile", &profile)) { 2304 int32_t level; 2305 if (!msg->findInt32("level", &level)) { 2306 return INVALID_OPERATION; 2307 } 2308 2309 err = verifySupportForProfileAndLevel(profile, level); 2310 2311 if (err != OK) { 2312 return err; 2313 } 2314 2315 h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile); 2316 h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level); 2317 } 2318 2319 // XXX 2320 if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) { 2321 ALOGW("Use baseline profile instead of %d for AVC recording", 2322 h264type.eProfile); 2323 h264type.eProfile = OMX_VIDEO_AVCProfileBaseline; 2324 } 2325 2326 if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) { 2327 h264type.nSliceHeaderSpacing = 0; 2328 h264type.bUseHadamard = OMX_TRUE; 2329 h264type.nRefFrames = 1; 2330 h264type.nBFrames = 0; 2331 h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 2332 if (h264type.nPFrames == 0) { 2333 h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 2334 } 2335 h264type.nRefIdx10ActiveMinus1 = 0; 2336 h264type.nRefIdx11ActiveMinus1 = 0; 2337 h264type.bEntropyCodingCABAC = OMX_FALSE; 2338 h264type.bWeightedPPrediction = OMX_FALSE; 2339 h264type.bconstIpred = OMX_FALSE; 2340 h264type.bDirect8x8Inference = OMX_FALSE; 2341 h264type.bDirectSpatialTemporal = OMX_FALSE; 2342 h264type.nCabacInitIdc = 0; 2343 } 2344 2345 if (h264type.nBFrames != 0) { 2346 h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; 2347 } 2348 2349 h264type.bEnableUEP = OMX_FALSE; 2350 h264type.bEnableFMO = OMX_FALSE; 2351 h264type.bEnableASO = OMX_FALSE; 2352 h264type.bEnableRS = OMX_FALSE; 2353 h264type.bFrameMBsOnly = OMX_TRUE; 2354 h264type.bMBAFF = OMX_FALSE; 2355 h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; 2356 2357 err = mOMX->setParameter( 2358 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 2359 2360 if (err != OK) { 2361 return err; 2362 } 2363 2364 return configureBitrate(bitrate, bitrateMode); 2365} 2366 2367status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) { 2368 int32_t bitrate; 2369 int32_t iFrameInterval = 0; 2370 size_t tsLayers = 0; 2371 OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern = 2372 OMX_VIDEO_VPXTemporalLayerPatternNone; 2373 static const uint32_t kVp8LayerRateAlloction 2374 [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] 2375 [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = { 2376 {100, 100, 100}, // 1 layer 2377 { 60, 100, 100}, // 2 layers {60%, 40%} 2378 { 40, 60, 100}, // 3 layers {40%, 20%, 40%} 2379 }; 2380 if (!msg->findInt32("bitrate", &bitrate)) { 2381 return INVALID_OPERATION; 2382 } 2383 msg->findInt32("i-frame-interval", &iFrameInterval); 2384 2385 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 2386 2387 float frameRate; 2388 if (!msg->findFloat("frame-rate", &frameRate)) { 2389 int32_t tmp; 2390 if (!msg->findInt32("frame-rate", &tmp)) { 2391 return INVALID_OPERATION; 2392 } 2393 frameRate = (float)tmp; 2394 } 2395 2396 AString tsSchema; 2397 if (msg->findString("ts-schema", &tsSchema)) { 2398 if (tsSchema == "webrtc.vp8.1-layer") { 2399 pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 2400 tsLayers = 1; 2401 } else if (tsSchema == "webrtc.vp8.2-layer") { 2402 pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 2403 tsLayers = 2; 2404 } else if (tsSchema == "webrtc.vp8.3-layer") { 2405 pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC; 2406 tsLayers = 3; 2407 } else { 2408 ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str()); 2409 } 2410 } 2411 2412 OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type; 2413 InitOMXParams(&vp8type); 2414 vp8type.nPortIndex = kPortIndexOutput; 2415 status_t err = mOMX->getParameter( 2416 mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 2417 &vp8type, sizeof(vp8type)); 2418 2419 if (err == OK) { 2420 if (iFrameInterval > 0) { 2421 vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate); 2422 } 2423 vp8type.eTemporalPattern = pattern; 2424 vp8type.nTemporalLayerCount = tsLayers; 2425 if (tsLayers > 0) { 2426 for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) { 2427 vp8type.nTemporalLayerBitrateRatio[i] = 2428 kVp8LayerRateAlloction[tsLayers - 1][i]; 2429 } 2430 } 2431 if (bitrateMode == OMX_Video_ControlRateConstant) { 2432 vp8type.nMinQuantizer = 2; 2433 vp8type.nMaxQuantizer = 63; 2434 } 2435 2436 err = mOMX->setParameter( 2437 mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder, 2438 &vp8type, sizeof(vp8type)); 2439 if (err != OK) { 2440 ALOGW("Extended VP8 parameters set failed: %d", err); 2441 } 2442 } 2443 2444 return configureBitrate(bitrate, bitrateMode); 2445} 2446 2447status_t ACodec::verifySupportForProfileAndLevel( 2448 int32_t profile, int32_t level) { 2449 OMX_VIDEO_PARAM_PROFILELEVELTYPE params; 2450 InitOMXParams(¶ms); 2451 params.nPortIndex = kPortIndexOutput; 2452 2453 for (params.nProfileIndex = 0;; ++params.nProfileIndex) { 2454 status_t err = mOMX->getParameter( 2455 mNode, 2456 OMX_IndexParamVideoProfileLevelQuerySupported, 2457 ¶ms, 2458 sizeof(params)); 2459 2460 if (err != OK) { 2461 return err; 2462 } 2463 2464 int32_t supportedProfile = static_cast<int32_t>(params.eProfile); 2465 int32_t supportedLevel = static_cast<int32_t>(params.eLevel); 2466 2467 if (profile == supportedProfile && level <= supportedLevel) { 2468 return OK; 2469 } 2470 } 2471} 2472 2473status_t ACodec::configureBitrate( 2474 int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) { 2475 OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 2476 InitOMXParams(&bitrateType); 2477 bitrateType.nPortIndex = kPortIndexOutput; 2478 2479 status_t err = mOMX->getParameter( 2480 mNode, OMX_IndexParamVideoBitrate, 2481 &bitrateType, sizeof(bitrateType)); 2482 2483 if (err != OK) { 2484 return err; 2485 } 2486 2487 bitrateType.eControlRate = bitrateMode; 2488 bitrateType.nTargetBitrate = bitrate; 2489 2490 return mOMX->setParameter( 2491 mNode, OMX_IndexParamVideoBitrate, 2492 &bitrateType, sizeof(bitrateType)); 2493} 2494 2495status_t ACodec::setupErrorCorrectionParameters() { 2496 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; 2497 InitOMXParams(&errorCorrectionType); 2498 errorCorrectionType.nPortIndex = kPortIndexOutput; 2499 2500 status_t err = mOMX->getParameter( 2501 mNode, OMX_IndexParamVideoErrorCorrection, 2502 &errorCorrectionType, sizeof(errorCorrectionType)); 2503 2504 if (err != OK) { 2505 return OK; // Optional feature. Ignore this failure 2506 } 2507 2508 errorCorrectionType.bEnableHEC = OMX_FALSE; 2509 errorCorrectionType.bEnableResync = OMX_TRUE; 2510 errorCorrectionType.nResynchMarkerSpacing = 256; 2511 errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; 2512 errorCorrectionType.bEnableRVLC = OMX_FALSE; 2513 2514 return mOMX->setParameter( 2515 mNode, OMX_IndexParamVideoErrorCorrection, 2516 &errorCorrectionType, sizeof(errorCorrectionType)); 2517} 2518 2519status_t ACodec::setVideoFormatOnPort( 2520 OMX_U32 portIndex, 2521 int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) { 2522 OMX_PARAM_PORTDEFINITIONTYPE def; 2523 InitOMXParams(&def); 2524 def.nPortIndex = portIndex; 2525 2526 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2527 2528 status_t err = mOMX->getParameter( 2529 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2530 2531 CHECK_EQ(err, (status_t)OK); 2532 2533 if (portIndex == kPortIndexInput) { 2534 // XXX Need a (much) better heuristic to compute input buffer sizes. 2535 const size_t X = 64 * 1024; 2536 if (def.nBufferSize < X) { 2537 def.nBufferSize = X; 2538 } 2539 } 2540 2541 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 2542 2543 video_def->nFrameWidth = width; 2544 video_def->nFrameHeight = height; 2545 2546 if (portIndex == kPortIndexInput) { 2547 video_def->eCompressionFormat = compressionFormat; 2548 video_def->eColorFormat = OMX_COLOR_FormatUnused; 2549 } 2550 2551 err = mOMX->setParameter( 2552 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2553 2554 return err; 2555} 2556 2557status_t ACodec::initNativeWindow() { 2558 if (mNativeWindow != NULL) { 2559 return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE); 2560 } 2561 2562 mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE); 2563 return OK; 2564} 2565 2566size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const { 2567 size_t n = 0; 2568 2569 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 2570 const BufferInfo &info = mBuffers[portIndex].itemAt(i); 2571 2572 if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) { 2573 ++n; 2574 } 2575 } 2576 2577 return n; 2578} 2579 2580size_t ACodec::countBuffersOwnedByNativeWindow() const { 2581 size_t n = 0; 2582 2583 for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) { 2584 const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i); 2585 2586 if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 2587 ++n; 2588 } 2589 } 2590 2591 return n; 2592} 2593 2594void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() { 2595 if (mNativeWindow == NULL) { 2596 return; 2597 } 2598 2599 while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers 2600 && dequeueBufferFromNativeWindow() != NULL) { 2601 // these buffers will be submitted as regular buffers; account for this 2602 if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) { 2603 --mMetaDataBuffersToSubmit; 2604 } 2605 } 2606} 2607 2608bool ACodec::allYourBuffersAreBelongToUs( 2609 OMX_U32 portIndex) { 2610 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 2611 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 2612 2613 if (info->mStatus != BufferInfo::OWNED_BY_US 2614 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 2615 ALOGV("[%s] Buffer %u on port %u still has status %d", 2616 mComponentName.c_str(), 2617 info->mBufferID, portIndex, info->mStatus); 2618 return false; 2619 } 2620 } 2621 2622 return true; 2623} 2624 2625bool ACodec::allYourBuffersAreBelongToUs() { 2626 return allYourBuffersAreBelongToUs(kPortIndexInput) 2627 && allYourBuffersAreBelongToUs(kPortIndexOutput); 2628} 2629 2630void ACodec::deferMessage(const sp<AMessage> &msg) { 2631 bool wasEmptyBefore = mDeferredQueue.empty(); 2632 mDeferredQueue.push_back(msg); 2633} 2634 2635void ACodec::processDeferredMessages() { 2636 List<sp<AMessage> > queue = mDeferredQueue; 2637 mDeferredQueue.clear(); 2638 2639 List<sp<AMessage> >::iterator it = queue.begin(); 2640 while (it != queue.end()) { 2641 onMessageReceived(*it++); 2642 } 2643} 2644 2645status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) { 2646 // TODO: catch errors an return them instead of using CHECK 2647 OMX_PARAM_PORTDEFINITIONTYPE def; 2648 InitOMXParams(&def); 2649 def.nPortIndex = portIndex; 2650 2651 CHECK_EQ(mOMX->getParameter( 2652 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)), 2653 (status_t)OK); 2654 2655 CHECK_EQ((int)def.eDir, 2656 (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)); 2657 2658 switch (def.eDomain) { 2659 case OMX_PortDomainVideo: 2660 { 2661 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 2662 switch ((int)videoDef->eCompressionFormat) { 2663 case OMX_VIDEO_CodingUnused: 2664 { 2665 CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput)); 2666 notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW); 2667 2668 notify->setInt32("stride", videoDef->nStride); 2669 notify->setInt32("slice-height", videoDef->nSliceHeight); 2670 notify->setInt32("color-format", videoDef->eColorFormat); 2671 2672 OMX_CONFIG_RECTTYPE rect; 2673 InitOMXParams(&rect); 2674 rect.nPortIndex = kPortIndexOutput; 2675 2676 if (mOMX->getConfig( 2677 mNode, OMX_IndexConfigCommonOutputCrop, 2678 &rect, sizeof(rect)) != OK) { 2679 rect.nLeft = 0; 2680 rect.nTop = 0; 2681 rect.nWidth = videoDef->nFrameWidth; 2682 rect.nHeight = videoDef->nFrameHeight; 2683 } 2684 2685 CHECK_GE(rect.nLeft, 0); 2686 CHECK_GE(rect.nTop, 0); 2687 CHECK_GE(rect.nWidth, 0u); 2688 CHECK_GE(rect.nHeight, 0u); 2689 CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth); 2690 CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight); 2691 2692 notify->setRect( 2693 "crop", 2694 rect.nLeft, 2695 rect.nTop, 2696 rect.nLeft + rect.nWidth - 1, 2697 rect.nTop + rect.nHeight - 1); 2698 2699 break; 2700 } 2701 default: 2702 { 2703 CHECK(mIsEncoder ^ (portIndex == kPortIndexInput)); 2704 AString mime; 2705 if (GetMimeTypeForVideoCoding( 2706 videoDef->eCompressionFormat, &mime) != OK) { 2707 notify->setString("mime", "application/octet-stream"); 2708 } else { 2709 notify->setString("mime", mime.c_str()); 2710 } 2711 break; 2712 } 2713 } 2714 2715 notify->setInt32("width", videoDef->nFrameWidth); 2716 notify->setInt32("height", videoDef->nFrameHeight); 2717 break; 2718 } 2719 2720 case OMX_PortDomainAudio: 2721 { 2722 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 2723 2724 switch ((int)audioDef->eEncoding) { 2725 case OMX_AUDIO_CodingPCM: 2726 { 2727 OMX_AUDIO_PARAM_PCMMODETYPE params; 2728 InitOMXParams(¶ms); 2729 params.nPortIndex = portIndex; 2730 2731 CHECK_EQ(mOMX->getParameter( 2732 mNode, OMX_IndexParamAudioPcm, 2733 ¶ms, sizeof(params)), 2734 (status_t)OK); 2735 2736 CHECK_GT(params.nChannels, 0); 2737 CHECK(params.nChannels == 1 || params.bInterleaved); 2738 CHECK_EQ(params.nBitPerSample, 16u); 2739 2740 CHECK_EQ((int)params.eNumData, 2741 (int)OMX_NumericalDataSigned); 2742 2743 CHECK_EQ((int)params.ePCMMode, 2744 (int)OMX_AUDIO_PCMModeLinear); 2745 2746 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW); 2747 notify->setInt32("channel-count", params.nChannels); 2748 notify->setInt32("sample-rate", params.nSamplingRate); 2749 2750 if (mChannelMaskPresent) { 2751 notify->setInt32("channel-mask", mChannelMask); 2752 } 2753 break; 2754 } 2755 2756 case OMX_AUDIO_CodingAAC: 2757 { 2758 OMX_AUDIO_PARAM_AACPROFILETYPE params; 2759 InitOMXParams(¶ms); 2760 params.nPortIndex = portIndex; 2761 2762 CHECK_EQ(mOMX->getParameter( 2763 mNode, OMX_IndexParamAudioAac, 2764 ¶ms, sizeof(params)), 2765 (status_t)OK); 2766 2767 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 2768 notify->setInt32("channel-count", params.nChannels); 2769 notify->setInt32("sample-rate", params.nSampleRate); 2770 break; 2771 } 2772 2773 case OMX_AUDIO_CodingAMR: 2774 { 2775 OMX_AUDIO_PARAM_AMRTYPE params; 2776 InitOMXParams(¶ms); 2777 params.nPortIndex = portIndex; 2778 2779 CHECK_EQ(mOMX->getParameter( 2780 mNode, OMX_IndexParamAudioAmr, 2781 ¶ms, sizeof(params)), 2782 (status_t)OK); 2783 2784 notify->setInt32("channel-count", 1); 2785 if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) { 2786 notify->setString( 2787 "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB); 2788 2789 notify->setInt32("sample-rate", 16000); 2790 } else { 2791 notify->setString( 2792 "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB); 2793 2794 notify->setInt32("sample-rate", 8000); 2795 } 2796 break; 2797 } 2798 2799 case OMX_AUDIO_CodingFLAC: 2800 { 2801 OMX_AUDIO_PARAM_FLACTYPE params; 2802 InitOMXParams(¶ms); 2803 params.nPortIndex = portIndex; 2804 2805 CHECK_EQ(mOMX->getParameter( 2806 mNode, OMX_IndexParamAudioFlac, 2807 ¶ms, sizeof(params)), 2808 (status_t)OK); 2809 2810 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC); 2811 notify->setInt32("channel-count", params.nChannels); 2812 notify->setInt32("sample-rate", params.nSampleRate); 2813 break; 2814 } 2815 2816 case OMX_AUDIO_CodingMP3: 2817 { 2818 OMX_AUDIO_PARAM_MP3TYPE params; 2819 InitOMXParams(¶ms); 2820 params.nPortIndex = portIndex; 2821 2822 CHECK_EQ(mOMX->getParameter( 2823 mNode, OMX_IndexParamAudioMp3, 2824 ¶ms, sizeof(params)), 2825 (status_t)OK); 2826 2827 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG); 2828 notify->setInt32("channel-count", params.nChannels); 2829 notify->setInt32("sample-rate", params.nSampleRate); 2830 break; 2831 } 2832 2833 case OMX_AUDIO_CodingVORBIS: 2834 { 2835 OMX_AUDIO_PARAM_VORBISTYPE params; 2836 InitOMXParams(¶ms); 2837 params.nPortIndex = portIndex; 2838 2839 CHECK_EQ(mOMX->getParameter( 2840 mNode, OMX_IndexParamAudioVorbis, 2841 ¶ms, sizeof(params)), 2842 (status_t)OK); 2843 2844 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS); 2845 notify->setInt32("channel-count", params.nChannels); 2846 notify->setInt32("sample-rate", params.nSampleRate); 2847 break; 2848 } 2849 2850 case OMX_AUDIO_CodingAndroidAC3: 2851 { 2852 OMX_AUDIO_PARAM_ANDROID_AC3TYPE params; 2853 InitOMXParams(¶ms); 2854 params.nPortIndex = portIndex; 2855 2856 CHECK_EQ((status_t)OK, mOMX->getParameter( 2857 mNode, 2858 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, 2859 ¶ms, 2860 sizeof(params))); 2861 2862 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3); 2863 notify->setInt32("channel-count", params.nChannels); 2864 notify->setInt32("sample-rate", params.nSampleRate); 2865 break; 2866 } 2867 2868 default: 2869 ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding); 2870 TRESPASS(); 2871 } 2872 break; 2873 } 2874 2875 default: 2876 TRESPASS(); 2877 } 2878 2879 return OK; 2880} 2881 2882void ACodec::sendFormatChange(const sp<AMessage> &reply) { 2883 sp<AMessage> notify = mNotify->dup(); 2884 notify->setInt32("what", kWhatOutputFormatChanged); 2885 2886 CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK); 2887 2888 AString mime; 2889 CHECK(notify->findString("mime", &mime)); 2890 2891 int32_t left, top, right, bottom; 2892 if (mime == MEDIA_MIMETYPE_VIDEO_RAW && 2893 mNativeWindow != NULL && 2894 notify->findRect("crop", &left, &top, &right, &bottom)) { 2895 // notify renderer of the crop change 2896 // NOTE: native window uses extended right-bottom coordinate 2897 reply->setRect("crop", left, top, right + 1, bottom + 1); 2898 } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW && 2899 (mEncoderDelay || mEncoderPadding)) { 2900 int32_t channelCount; 2901 CHECK(notify->findInt32("channel-count", &channelCount)); 2902 size_t frameSize = channelCount * sizeof(int16_t); 2903 if (mSkipCutBuffer != NULL) { 2904 size_t prevbufsize = mSkipCutBuffer->size(); 2905 if (prevbufsize != 0) { 2906 ALOGW("Replacing SkipCutBuffer holding %d " 2907 "bytes", 2908 prevbufsize); 2909 } 2910 } 2911 mSkipCutBuffer = new SkipCutBuffer( 2912 mEncoderDelay * frameSize, 2913 mEncoderPadding * frameSize); 2914 } 2915 2916 notify->post(); 2917 2918 mSentFormat = true; 2919} 2920 2921void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) { 2922 sp<AMessage> notify = mNotify->dup(); 2923 notify->setInt32("what", ACodec::kWhatError); 2924 notify->setInt32("omx-error", error); 2925 notify->setInt32("err", internalError); 2926 notify->post(); 2927} 2928 2929status_t ACodec::pushBlankBuffersToNativeWindow() { 2930 status_t err = NO_ERROR; 2931 ANativeWindowBuffer* anb = NULL; 2932 int numBufs = 0; 2933 int minUndequeuedBufs = 0; 2934 2935 // We need to reconnect to the ANativeWindow as a CPU client to ensure that 2936 // no frames get dropped by SurfaceFlinger assuming that these are video 2937 // frames. 2938 err = native_window_api_disconnect(mNativeWindow.get(), 2939 NATIVE_WINDOW_API_MEDIA); 2940 if (err != NO_ERROR) { 2941 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", 2942 strerror(-err), -err); 2943 return err; 2944 } 2945 2946 err = native_window_api_connect(mNativeWindow.get(), 2947 NATIVE_WINDOW_API_CPU); 2948 if (err != NO_ERROR) { 2949 ALOGE("error pushing blank frames: api_connect failed: %s (%d)", 2950 strerror(-err), -err); 2951 return err; 2952 } 2953 2954 err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1, 2955 HAL_PIXEL_FORMAT_RGBX_8888); 2956 if (err != NO_ERROR) { 2957 ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)", 2958 strerror(-err), -err); 2959 goto error; 2960 } 2961 2962 err = native_window_set_scaling_mode(mNativeWindow.get(), 2963 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 2964 if (err != NO_ERROR) { 2965 ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)", 2966 strerror(-err), -err); 2967 goto error; 2968 } 2969 2970 err = native_window_set_usage(mNativeWindow.get(), 2971 GRALLOC_USAGE_SW_WRITE_OFTEN); 2972 if (err != NO_ERROR) { 2973 ALOGE("error pushing blank frames: set_usage failed: %s (%d)", 2974 strerror(-err), -err); 2975 goto error; 2976 } 2977 2978 err = mNativeWindow->query(mNativeWindow.get(), 2979 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); 2980 if (err != NO_ERROR) { 2981 ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query " 2982 "failed: %s (%d)", strerror(-err), -err); 2983 goto error; 2984 } 2985 2986 numBufs = minUndequeuedBufs + 1; 2987 err = native_window_set_buffer_count(mNativeWindow.get(), numBufs); 2988 if (err != NO_ERROR) { 2989 ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)", 2990 strerror(-err), -err); 2991 goto error; 2992 } 2993 2994 // We push numBufs + 1 buffers to ensure that we've drawn into the same 2995 // buffer twice. This should guarantee that the buffer has been displayed 2996 // on the screen and then been replaced, so an previous video frames are 2997 // guaranteed NOT to be currently displayed. 2998 for (int i = 0; i < numBufs + 1; i++) { 2999 int fenceFd = -1; 3000 err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb); 3001 if (err != NO_ERROR) { 3002 ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)", 3003 strerror(-err), -err); 3004 goto error; 3005 } 3006 3007 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 3008 3009 // Fill the buffer with the a 1x1 checkerboard pattern ;) 3010 uint32_t* img = NULL; 3011 err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 3012 if (err != NO_ERROR) { 3013 ALOGE("error pushing blank frames: lock failed: %s (%d)", 3014 strerror(-err), -err); 3015 goto error; 3016 } 3017 3018 *img = 0; 3019 3020 err = buf->unlock(); 3021 if (err != NO_ERROR) { 3022 ALOGE("error pushing blank frames: unlock failed: %s (%d)", 3023 strerror(-err), -err); 3024 goto error; 3025 } 3026 3027 err = mNativeWindow->queueBuffer(mNativeWindow.get(), 3028 buf->getNativeBuffer(), -1); 3029 if (err != NO_ERROR) { 3030 ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)", 3031 strerror(-err), -err); 3032 goto error; 3033 } 3034 3035 anb = NULL; 3036 } 3037 3038error: 3039 3040 if (err != NO_ERROR) { 3041 // Clean up after an error. 3042 if (anb != NULL) { 3043 mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1); 3044 } 3045 3046 native_window_api_disconnect(mNativeWindow.get(), 3047 NATIVE_WINDOW_API_CPU); 3048 native_window_api_connect(mNativeWindow.get(), 3049 NATIVE_WINDOW_API_MEDIA); 3050 3051 return err; 3052 } else { 3053 // Clean up after success. 3054 err = native_window_api_disconnect(mNativeWindow.get(), 3055 NATIVE_WINDOW_API_CPU); 3056 if (err != NO_ERROR) { 3057 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", 3058 strerror(-err), -err); 3059 return err; 3060 } 3061 3062 err = native_window_api_connect(mNativeWindow.get(), 3063 NATIVE_WINDOW_API_MEDIA); 3064 if (err != NO_ERROR) { 3065 ALOGE("error pushing blank frames: api_connect failed: %s (%d)", 3066 strerror(-err), -err); 3067 return err; 3068 } 3069 3070 return NO_ERROR; 3071 } 3072} 3073 3074//////////////////////////////////////////////////////////////////////////////// 3075 3076ACodec::PortDescription::PortDescription() { 3077} 3078 3079status_t ACodec::requestIDRFrame() { 3080 if (!mIsEncoder) { 3081 return ERROR_UNSUPPORTED; 3082 } 3083 3084 OMX_CONFIG_INTRAREFRESHVOPTYPE params; 3085 InitOMXParams(¶ms); 3086 3087 params.nPortIndex = kPortIndexOutput; 3088 params.IntraRefreshVOP = OMX_TRUE; 3089 3090 return mOMX->setConfig( 3091 mNode, 3092 OMX_IndexConfigVideoIntraVOPRefresh, 3093 ¶ms, 3094 sizeof(params)); 3095} 3096 3097void ACodec::PortDescription::addBuffer( 3098 IOMX::buffer_id id, const sp<ABuffer> &buffer) { 3099 mBufferIDs.push_back(id); 3100 mBuffers.push_back(buffer); 3101} 3102 3103size_t ACodec::PortDescription::countBuffers() { 3104 return mBufferIDs.size(); 3105} 3106 3107IOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const { 3108 return mBufferIDs.itemAt(index); 3109} 3110 3111sp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const { 3112 return mBuffers.itemAt(index); 3113} 3114 3115//////////////////////////////////////////////////////////////////////////////// 3116 3117ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState) 3118 : AState(parentState), 3119 mCodec(codec) { 3120} 3121 3122ACodec::BaseState::PortMode ACodec::BaseState::getPortMode( 3123 OMX_U32 /* portIndex */) { 3124 return KEEP_BUFFERS; 3125} 3126 3127bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { 3128 switch (msg->what()) { 3129 case kWhatInputBufferFilled: 3130 { 3131 onInputBufferFilled(msg); 3132 break; 3133 } 3134 3135 case kWhatOutputBufferDrained: 3136 { 3137 onOutputBufferDrained(msg); 3138 break; 3139 } 3140 3141 case ACodec::kWhatOMXMessage: 3142 { 3143 return onOMXMessage(msg); 3144 } 3145 3146 case ACodec::kWhatCreateInputSurface: 3147 case ACodec::kWhatSignalEndOfInputStream: 3148 { 3149 ALOGE("Message 0x%x was not handled", msg->what()); 3150 mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION); 3151 return true; 3152 } 3153 3154 case ACodec::kWhatOMXDied: 3155 { 3156 ALOGE("OMX/mediaserver died, signalling error!"); 3157 mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT); 3158 break; 3159 } 3160 3161 default: 3162 return false; 3163 } 3164 3165 return true; 3166} 3167 3168bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { 3169 int32_t type; 3170 CHECK(msg->findInt32("type", &type)); 3171 3172 // there is a possibility that this is an outstanding message for a 3173 // codec that we have already destroyed 3174 if (mCodec->mNode == NULL) { 3175 ALOGI("ignoring message as already freed component: %s", 3176 msg->debugString().c_str()); 3177 return true; 3178 } 3179 3180 IOMX::node_id nodeID; 3181 CHECK(msg->findInt32("node", (int32_t*)&nodeID)); 3182 CHECK_EQ(nodeID, mCodec->mNode); 3183 3184 switch (type) { 3185 case omx_message::EVENT: 3186 { 3187 int32_t event, data1, data2; 3188 CHECK(msg->findInt32("event", &event)); 3189 CHECK(msg->findInt32("data1", &data1)); 3190 CHECK(msg->findInt32("data2", &data2)); 3191 3192 if (event == OMX_EventCmdComplete 3193 && data1 == OMX_CommandFlush 3194 && data2 == (int32_t)OMX_ALL) { 3195 // Use of this notification is not consistent across 3196 // implementations. We'll drop this notification and rely 3197 // on flush-complete notifications on the individual port 3198 // indices instead. 3199 3200 return true; 3201 } 3202 3203 return onOMXEvent( 3204 static_cast<OMX_EVENTTYPE>(event), 3205 static_cast<OMX_U32>(data1), 3206 static_cast<OMX_U32>(data2)); 3207 } 3208 3209 case omx_message::EMPTY_BUFFER_DONE: 3210 { 3211 IOMX::buffer_id bufferID; 3212 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 3213 3214 return onOMXEmptyBufferDone(bufferID); 3215 } 3216 3217 case omx_message::FILL_BUFFER_DONE: 3218 { 3219 IOMX::buffer_id bufferID; 3220 CHECK(msg->findInt32("buffer", (int32_t*)&bufferID)); 3221 3222 int32_t rangeOffset, rangeLength, flags; 3223 int64_t timeUs; 3224 3225 CHECK(msg->findInt32("range_offset", &rangeOffset)); 3226 CHECK(msg->findInt32("range_length", &rangeLength)); 3227 CHECK(msg->findInt32("flags", &flags)); 3228 CHECK(msg->findInt64("timestamp", &timeUs)); 3229 3230 return onOMXFillBufferDone( 3231 bufferID, 3232 (size_t)rangeOffset, (size_t)rangeLength, 3233 (OMX_U32)flags, 3234 timeUs); 3235 } 3236 3237 default: 3238 TRESPASS(); 3239 break; 3240 } 3241} 3242 3243bool ACodec::BaseState::onOMXEvent( 3244 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 3245 if (event != OMX_EventError) { 3246 ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)", 3247 mCodec->mComponentName.c_str(), event, data1, data2); 3248 3249 return false; 3250 } 3251 3252 ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1); 3253 3254 mCodec->signalError((OMX_ERRORTYPE)data1); 3255 3256 return true; 3257} 3258 3259bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) { 3260 ALOGV("[%s] onOMXEmptyBufferDone %p", 3261 mCodec->mComponentName.c_str(), bufferID); 3262 3263 BufferInfo *info = 3264 mCodec->findBufferByID(kPortIndexInput, bufferID); 3265 3266 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT); 3267 info->mStatus = BufferInfo::OWNED_BY_US; 3268 3269 const sp<AMessage> &bufferMeta = info->mData->meta(); 3270 void *mediaBuffer; 3271 if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer) 3272 && mediaBuffer != NULL) { 3273 // We're in "store-metadata-in-buffers" mode, the underlying 3274 // OMX component had access to data that's implicitly refcounted 3275 // by this "mediaBuffer" object. Now that the OMX component has 3276 // told us that it's done with the input buffer, we can decrement 3277 // the mediaBuffer's reference count. 3278 3279 ALOGV("releasing mbuf %p", mediaBuffer); 3280 3281 ((MediaBuffer *)mediaBuffer)->release(); 3282 mediaBuffer = NULL; 3283 3284 bufferMeta->setPointer("mediaBuffer", NULL); 3285 } 3286 3287 PortMode mode = getPortMode(kPortIndexInput); 3288 3289 switch (mode) { 3290 case KEEP_BUFFERS: 3291 break; 3292 3293 case RESUBMIT_BUFFERS: 3294 postFillThisBuffer(info); 3295 break; 3296 3297 default: 3298 { 3299 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 3300 TRESPASS(); // Not currently used 3301 break; 3302 } 3303 } 3304 3305 return true; 3306} 3307 3308void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) { 3309 if (mCodec->mPortEOS[kPortIndexInput]) { 3310 return; 3311 } 3312 3313 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 3314 3315 sp<AMessage> notify = mCodec->mNotify->dup(); 3316 notify->setInt32("what", ACodec::kWhatFillThisBuffer); 3317 notify->setInt32("buffer-id", info->mBufferID); 3318 3319 info->mData->meta()->clear(); 3320 notify->setBuffer("buffer", info->mData); 3321 3322 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id()); 3323 reply->setInt32("buffer-id", info->mBufferID); 3324 3325 notify->setMessage("reply", reply); 3326 3327 notify->post(); 3328 3329 info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 3330} 3331 3332void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { 3333 IOMX::buffer_id bufferID; 3334 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 3335 sp<ABuffer> buffer; 3336 int32_t err = OK; 3337 bool eos = false; 3338 PortMode mode = getPortMode(kPortIndexInput); 3339 3340 if (!msg->findBuffer("buffer", &buffer)) { 3341 /* these are unfilled buffers returned by client */ 3342 CHECK(msg->findInt32("err", &err)); 3343 3344 if (err == OK) { 3345 /* buffers with no errors are returned on MediaCodec.flush */ 3346 mode = KEEP_BUFFERS; 3347 } else { 3348 ALOGV("[%s] saw error %d instead of an input buffer", 3349 mCodec->mComponentName.c_str(), err); 3350 eos = true; 3351 } 3352 3353 buffer.clear(); 3354 } 3355 3356 int32_t tmp; 3357 if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) { 3358 eos = true; 3359 err = ERROR_END_OF_STREAM; 3360 } 3361 3362 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 3363 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM); 3364 3365 info->mStatus = BufferInfo::OWNED_BY_US; 3366 3367 switch (mode) { 3368 case KEEP_BUFFERS: 3369 { 3370 if (eos) { 3371 if (!mCodec->mPortEOS[kPortIndexInput]) { 3372 mCodec->mPortEOS[kPortIndexInput] = true; 3373 mCodec->mInputEOSResult = err; 3374 } 3375 } 3376 break; 3377 } 3378 3379 case RESUBMIT_BUFFERS: 3380 { 3381 if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) { 3382 int64_t timeUs; 3383 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 3384 3385 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 3386 3387 int32_t isCSD; 3388 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) { 3389 flags |= OMX_BUFFERFLAG_CODECCONFIG; 3390 } 3391 3392 if (eos) { 3393 flags |= OMX_BUFFERFLAG_EOS; 3394 } 3395 3396 if (buffer != info->mData) { 3397 ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)", 3398 mCodec->mComponentName.c_str(), 3399 bufferID, 3400 buffer.get(), info->mData.get()); 3401 3402 CHECK_LE(buffer->size(), info->mData->capacity()); 3403 memcpy(info->mData->data(), buffer->data(), buffer->size()); 3404 } 3405 3406 if (flags & OMX_BUFFERFLAG_CODECCONFIG) { 3407 ALOGV("[%s] calling emptyBuffer %p w/ codec specific data", 3408 mCodec->mComponentName.c_str(), bufferID); 3409 } else if (flags & OMX_BUFFERFLAG_EOS) { 3410 ALOGV("[%s] calling emptyBuffer %p w/ EOS", 3411 mCodec->mComponentName.c_str(), bufferID); 3412 } else { 3413#if TRACK_BUFFER_TIMING 3414 ALOGI("[%s] calling emptyBuffer %p w/ time %lld us", 3415 mCodec->mComponentName.c_str(), bufferID, timeUs); 3416#else 3417 ALOGV("[%s] calling emptyBuffer %p w/ time %lld us", 3418 mCodec->mComponentName.c_str(), bufferID, timeUs); 3419#endif 3420 } 3421 3422#if TRACK_BUFFER_TIMING 3423 ACodec::BufferStats stats; 3424 stats.mEmptyBufferTimeUs = ALooper::GetNowUs(); 3425 stats.mFillBufferDoneTimeUs = -1ll; 3426 mCodec->mBufferStats.add(timeUs, stats); 3427#endif 3428 3429 if (mCodec->mStoreMetaDataInOutputBuffers) { 3430 // try to submit an output buffer for each input buffer 3431 PortMode outputMode = getPortMode(kPortIndexOutput); 3432 3433 ALOGV("MetaDataBuffersToSubmit=%u portMode=%s", 3434 mCodec->mMetaDataBuffersToSubmit, 3435 (outputMode == FREE_BUFFERS ? "FREE" : 3436 outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT")); 3437 if (outputMode == RESUBMIT_BUFFERS) { 3438 CHECK_EQ(mCodec->submitOutputMetaDataBuffer(), 3439 (status_t)OK); 3440 } 3441 } 3442 3443 CHECK_EQ(mCodec->mOMX->emptyBuffer( 3444 mCodec->mNode, 3445 bufferID, 3446 0, 3447 buffer->size(), 3448 flags, 3449 timeUs), 3450 (status_t)OK); 3451 3452 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 3453 3454 if (!eos) { 3455 getMoreInputDataIfPossible(); 3456 } else { 3457 ALOGV("[%s] Signalled EOS on the input port", 3458 mCodec->mComponentName.c_str()); 3459 3460 mCodec->mPortEOS[kPortIndexInput] = true; 3461 mCodec->mInputEOSResult = err; 3462 } 3463 } else if (!mCodec->mPortEOS[kPortIndexInput]) { 3464 if (err != ERROR_END_OF_STREAM) { 3465 ALOGV("[%s] Signalling EOS on the input port " 3466 "due to error %d", 3467 mCodec->mComponentName.c_str(), err); 3468 } else { 3469 ALOGV("[%s] Signalling EOS on the input port", 3470 mCodec->mComponentName.c_str()); 3471 } 3472 3473 ALOGV("[%s] calling emptyBuffer %p signalling EOS", 3474 mCodec->mComponentName.c_str(), bufferID); 3475 3476 CHECK_EQ(mCodec->mOMX->emptyBuffer( 3477 mCodec->mNode, 3478 bufferID, 3479 0, 3480 0, 3481 OMX_BUFFERFLAG_EOS, 3482 0), 3483 (status_t)OK); 3484 3485 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 3486 3487 mCodec->mPortEOS[kPortIndexInput] = true; 3488 mCodec->mInputEOSResult = err; 3489 } 3490 break; 3491 } 3492 3493 default: 3494 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 3495 break; 3496 } 3497} 3498 3499void ACodec::BaseState::getMoreInputDataIfPossible() { 3500 if (mCodec->mPortEOS[kPortIndexInput]) { 3501 return; 3502 } 3503 3504 BufferInfo *eligible = NULL; 3505 3506 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 3507 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 3508 3509#if 0 3510 if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 3511 // There's already a "read" pending. 3512 return; 3513 } 3514#endif 3515 3516 if (info->mStatus == BufferInfo::OWNED_BY_US) { 3517 eligible = info; 3518 } 3519 } 3520 3521 if (eligible == NULL) { 3522 return; 3523 } 3524 3525 postFillThisBuffer(eligible); 3526} 3527 3528bool ACodec::BaseState::onOMXFillBufferDone( 3529 IOMX::buffer_id bufferID, 3530 size_t rangeOffset, size_t rangeLength, 3531 OMX_U32 flags, 3532 int64_t timeUs) { 3533 ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x", 3534 mCodec->mComponentName.c_str(), bufferID, timeUs, flags); 3535 3536 ssize_t index; 3537 3538#if TRACK_BUFFER_TIMING 3539 index = mCodec->mBufferStats.indexOfKey(timeUs); 3540 if (index >= 0) { 3541 ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index); 3542 stats->mFillBufferDoneTimeUs = ALooper::GetNowUs(); 3543 3544 ALOGI("frame PTS %lld: %lld", 3545 timeUs, 3546 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs); 3547 3548 mCodec->mBufferStats.removeItemsAt(index); 3549 stats = NULL; 3550 } 3551#endif 3552 3553 BufferInfo *info = 3554 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 3555 3556 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT); 3557 3558 info->mDequeuedAt = ++mCodec->mDequeueCounter; 3559 info->mStatus = BufferInfo::OWNED_BY_US; 3560 3561 PortMode mode = getPortMode(kPortIndexOutput); 3562 3563 switch (mode) { 3564 case KEEP_BUFFERS: 3565 break; 3566 3567 case RESUBMIT_BUFFERS: 3568 { 3569 if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) { 3570 ALOGV("[%s] calling fillBuffer %u", 3571 mCodec->mComponentName.c_str(), info->mBufferID); 3572 3573 CHECK_EQ(mCodec->mOMX->fillBuffer( 3574 mCodec->mNode, info->mBufferID), 3575 (status_t)OK); 3576 3577 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 3578 break; 3579 } 3580 3581 sp<AMessage> reply = 3582 new AMessage(kWhatOutputBufferDrained, mCodec->id()); 3583 3584 if (!mCodec->mSentFormat && rangeLength > 0) { 3585 mCodec->sendFormatChange(reply); 3586 } 3587 3588 if (mCodec->mUseMetadataOnEncoderOutput) { 3589 native_handle_t* handle = 3590 *(native_handle_t**)(info->mData->data() + 4); 3591 info->mData->meta()->setPointer("handle", handle); 3592 info->mData->meta()->setInt32("rangeOffset", rangeOffset); 3593 info->mData->meta()->setInt32("rangeLength", rangeLength); 3594 } else { 3595 info->mData->setRange(rangeOffset, rangeLength); 3596 } 3597#if 0 3598 if (mCodec->mNativeWindow == NULL) { 3599 if (IsIDR(info->mData)) { 3600 ALOGI("IDR frame"); 3601 } 3602 } 3603#endif 3604 3605 if (mCodec->mSkipCutBuffer != NULL) { 3606 mCodec->mSkipCutBuffer->submit(info->mData); 3607 } 3608 info->mData->meta()->setInt64("timeUs", timeUs); 3609 3610 sp<AMessage> notify = mCodec->mNotify->dup(); 3611 notify->setInt32("what", ACodec::kWhatDrainThisBuffer); 3612 notify->setInt32("buffer-id", info->mBufferID); 3613 notify->setBuffer("buffer", info->mData); 3614 notify->setInt32("flags", flags); 3615 3616 reply->setInt32("buffer-id", info->mBufferID); 3617 3618 notify->setMessage("reply", reply); 3619 3620 notify->post(); 3621 3622 info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 3623 3624 if (flags & OMX_BUFFERFLAG_EOS) { 3625 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str()); 3626 3627 sp<AMessage> notify = mCodec->mNotify->dup(); 3628 notify->setInt32("what", ACodec::kWhatEOS); 3629 notify->setInt32("err", mCodec->mInputEOSResult); 3630 notify->post(); 3631 3632 mCodec->mPortEOS[kPortIndexOutput] = true; 3633 } 3634 break; 3635 } 3636 3637 default: 3638 { 3639 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 3640 3641 CHECK_EQ((status_t)OK, 3642 mCodec->freeBuffer(kPortIndexOutput, index)); 3643 break; 3644 } 3645 } 3646 3647 return true; 3648} 3649 3650void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 3651 IOMX::buffer_id bufferID; 3652 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 3653 ssize_t index; 3654 BufferInfo *info = 3655 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 3656 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM); 3657 3658 android_native_rect_t crop; 3659 if (msg->findRect("crop", 3660 &crop.left, &crop.top, &crop.right, &crop.bottom)) { 3661 CHECK_EQ(0, native_window_set_crop( 3662 mCodec->mNativeWindow.get(), &crop)); 3663 } 3664 3665 int32_t render; 3666 if (mCodec->mNativeWindow != NULL 3667 && msg->findInt32("render", &render) && render != 0 3668 && info->mData != NULL && info->mData->size() != 0) { 3669 ATRACE_NAME("render"); 3670 // The client wants this buffer to be rendered. 3671 3672 int64_t timestampNs = 0; 3673 if (!msg->findInt64("timestampNs", ×tampNs)) { 3674 // TODO: it seems like we should use the timestamp 3675 // in the (media)buffer as it potentially came from 3676 // an input surface, but we did not propagate it prior to 3677 // API 20. Perhaps check for target SDK version. 3678#if 0 3679 if (info->mData->meta()->findInt64("timeUs", ×tampNs)) { 3680 ALOGI("using buffer PTS of %" PRId64, timestampNs); 3681 timestampNs *= 1000; 3682 } 3683#endif 3684 } 3685 3686 status_t err; 3687 err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs); 3688 if (err != OK) { 3689 ALOGW("failed to set buffer timestamp: %d", err); 3690 } else { 3691 ALOGI("set PTS to %" PRId64, timestampNs); 3692 } 3693 3694 if ((err = mCodec->mNativeWindow->queueBuffer( 3695 mCodec->mNativeWindow.get(), 3696 info->mGraphicBuffer.get(), -1)) == OK) { 3697 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 3698 } else { 3699 mCodec->signalError(OMX_ErrorUndefined, err); 3700 info->mStatus = BufferInfo::OWNED_BY_US; 3701 } 3702 } else { 3703 if (mCodec->mNativeWindow != NULL && 3704 (info->mData == NULL || info->mData->size() != 0)) { 3705 ATRACE_NAME("frame-drop"); 3706 } 3707 info->mStatus = BufferInfo::OWNED_BY_US; 3708 } 3709 3710 PortMode mode = getPortMode(kPortIndexOutput); 3711 3712 switch (mode) { 3713 case KEEP_BUFFERS: 3714 { 3715 // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 3716 3717 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 3718 // We cannot resubmit the buffer we just rendered, dequeue 3719 // the spare instead. 3720 3721 info = mCodec->dequeueBufferFromNativeWindow(); 3722 } 3723 break; 3724 } 3725 3726 case RESUBMIT_BUFFERS: 3727 { 3728 if (!mCodec->mPortEOS[kPortIndexOutput]) { 3729 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 3730 // We cannot resubmit the buffer we just rendered, dequeue 3731 // the spare instead. 3732 3733 info = mCodec->dequeueBufferFromNativeWindow(); 3734 } 3735 3736 if (info != NULL) { 3737 ALOGV("[%s] calling fillBuffer %u", 3738 mCodec->mComponentName.c_str(), info->mBufferID); 3739 3740 CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), 3741 (status_t)OK); 3742 3743 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 3744 } 3745 } 3746 break; 3747 } 3748 3749 default: 3750 { 3751 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 3752 3753 CHECK_EQ((status_t)OK, 3754 mCodec->freeBuffer(kPortIndexOutput, index)); 3755 break; 3756 } 3757 } 3758} 3759 3760//////////////////////////////////////////////////////////////////////////////// 3761 3762ACodec::UninitializedState::UninitializedState(ACodec *codec) 3763 : BaseState(codec) { 3764} 3765 3766void ACodec::UninitializedState::stateEntered() { 3767 ALOGV("Now uninitialized"); 3768 3769 if (mDeathNotifier != NULL) { 3770 mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier); 3771 mDeathNotifier.clear(); 3772 } 3773 3774 mCodec->mNativeWindow.clear(); 3775 mCodec->mNode = NULL; 3776 mCodec->mOMX.clear(); 3777 mCodec->mQuirks = 0; 3778 mCodec->mFlags = 0; 3779 mCodec->mUseMetadataOnEncoderOutput = 0; 3780 mCodec->mComponentName.clear(); 3781} 3782 3783bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 3784 bool handled = false; 3785 3786 switch (msg->what()) { 3787 case ACodec::kWhatSetup: 3788 { 3789 onSetup(msg); 3790 3791 handled = true; 3792 break; 3793 } 3794 3795 case ACodec::kWhatAllocateComponent: 3796 { 3797 onAllocateComponent(msg); 3798 handled = true; 3799 break; 3800 } 3801 3802 case ACodec::kWhatShutdown: 3803 { 3804 int32_t keepComponentAllocated; 3805 CHECK(msg->findInt32( 3806 "keepComponentAllocated", &keepComponentAllocated)); 3807 ALOGW_IF(keepComponentAllocated, 3808 "cannot keep component allocated on shutdown in Uninitialized state"); 3809 3810 sp<AMessage> notify = mCodec->mNotify->dup(); 3811 notify->setInt32("what", ACodec::kWhatShutdownCompleted); 3812 notify->post(); 3813 3814 handled = true; 3815 break; 3816 } 3817 3818 case ACodec::kWhatFlush: 3819 { 3820 sp<AMessage> notify = mCodec->mNotify->dup(); 3821 notify->setInt32("what", ACodec::kWhatFlushCompleted); 3822 notify->post(); 3823 3824 handled = true; 3825 break; 3826 } 3827 3828 default: 3829 return BaseState::onMessageReceived(msg); 3830 } 3831 3832 return handled; 3833} 3834 3835void ACodec::UninitializedState::onSetup( 3836 const sp<AMessage> &msg) { 3837 if (onAllocateComponent(msg) 3838 && mCodec->mLoadedState->onConfigureComponent(msg)) { 3839 mCodec->mLoadedState->onStart(); 3840 } 3841} 3842 3843bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { 3844 ALOGV("onAllocateComponent"); 3845 3846 CHECK(mCodec->mNode == NULL); 3847 3848 OMXClient client; 3849 CHECK_EQ(client.connect(), (status_t)OK); 3850 3851 sp<IOMX> omx = client.interface(); 3852 3853 sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id()); 3854 3855 mDeathNotifier = new DeathNotifier(notify); 3856 if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) { 3857 // This was a local binder, if it dies so do we, we won't care 3858 // about any notifications in the afterlife. 3859 mDeathNotifier.clear(); 3860 } 3861 3862 Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs; 3863 3864 AString mime; 3865 3866 AString componentName; 3867 uint32_t quirks = 0; 3868 if (msg->findString("componentName", &componentName)) { 3869 ssize_t index = matchingCodecs.add(); 3870 OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index); 3871 entry->mName = String8(componentName.c_str()); 3872 3873 if (!OMXCodec::findCodecQuirks( 3874 componentName.c_str(), &entry->mQuirks)) { 3875 entry->mQuirks = 0; 3876 } 3877 } else { 3878 CHECK(msg->findString("mime", &mime)); 3879 3880 int32_t encoder; 3881 if (!msg->findInt32("encoder", &encoder)) { 3882 encoder = false; 3883 } 3884 3885 OMXCodec::findMatchingCodecs( 3886 mime.c_str(), 3887 encoder, // createEncoder 3888 NULL, // matchComponentName 3889 0, // flags 3890 &matchingCodecs); 3891 } 3892 3893 sp<CodecObserver> observer = new CodecObserver; 3894 IOMX::node_id node = NULL; 3895 3896 for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); 3897 ++matchIndex) { 3898 componentName = matchingCodecs.itemAt(matchIndex).mName.string(); 3899 quirks = matchingCodecs.itemAt(matchIndex).mQuirks; 3900 3901 pid_t tid = androidGetTid(); 3902 int prevPriority = androidGetThreadPriority(tid); 3903 androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); 3904 status_t err = omx->allocateNode(componentName.c_str(), observer, &node); 3905 androidSetThreadPriority(tid, prevPriority); 3906 3907 if (err == OK) { 3908 break; 3909 } 3910 3911 node = NULL; 3912 } 3913 3914 if (node == NULL) { 3915 if (!mime.empty()) { 3916 ALOGE("Unable to instantiate a decoder for type '%s'.", 3917 mime.c_str()); 3918 } else { 3919 ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str()); 3920 } 3921 3922 mCodec->signalError(OMX_ErrorComponentNotFound); 3923 return false; 3924 } 3925 3926 notify = new AMessage(kWhatOMXMessage, mCodec->id()); 3927 observer->setNotificationMessage(notify); 3928 3929 mCodec->mComponentName = componentName; 3930 mCodec->mFlags = 0; 3931 3932 if (componentName.endsWith(".secure")) { 3933 mCodec->mFlags |= kFlagIsSecure; 3934 mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; 3935 } 3936 3937 mCodec->mQuirks = quirks; 3938 mCodec->mOMX = omx; 3939 mCodec->mNode = node; 3940 3941 { 3942 sp<AMessage> notify = mCodec->mNotify->dup(); 3943 notify->setInt32("what", ACodec::kWhatComponentAllocated); 3944 notify->setString("componentName", mCodec->mComponentName.c_str()); 3945 notify->post(); 3946 } 3947 3948 mCodec->changeState(mCodec->mLoadedState); 3949 3950 return true; 3951} 3952 3953//////////////////////////////////////////////////////////////////////////////// 3954 3955ACodec::LoadedState::LoadedState(ACodec *codec) 3956 : BaseState(codec) { 3957} 3958 3959void ACodec::LoadedState::stateEntered() { 3960 ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 3961 3962 mCodec->mPortEOS[kPortIndexInput] = 3963 mCodec->mPortEOS[kPortIndexOutput] = false; 3964 3965 mCodec->mInputEOSResult = OK; 3966 3967 mCodec->mDequeueCounter = 0; 3968 mCodec->mMetaDataBuffersToSubmit = 0; 3969 mCodec->mRepeatFrameDelayUs = -1ll; 3970 mCodec->mInputFormat.clear(); 3971 mCodec->mOutputFormat.clear(); 3972 3973 if (mCodec->mShutdownInProgress) { 3974 bool keepComponentAllocated = mCodec->mKeepComponentAllocated; 3975 3976 mCodec->mShutdownInProgress = false; 3977 mCodec->mKeepComponentAllocated = false; 3978 3979 onShutdown(keepComponentAllocated); 3980 } 3981 mCodec->mExplicitShutdown = false; 3982} 3983 3984void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) { 3985 if (!keepComponentAllocated) { 3986 CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK); 3987 3988 mCodec->changeState(mCodec->mUninitializedState); 3989 } 3990 3991 if (mCodec->mExplicitShutdown) { 3992 sp<AMessage> notify = mCodec->mNotify->dup(); 3993 notify->setInt32("what", ACodec::kWhatShutdownCompleted); 3994 notify->post(); 3995 mCodec->mExplicitShutdown = false; 3996 } 3997} 3998 3999bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) { 4000 bool handled = false; 4001 4002 switch (msg->what()) { 4003 case ACodec::kWhatConfigureComponent: 4004 { 4005 onConfigureComponent(msg); 4006 handled = true; 4007 break; 4008 } 4009 4010 case ACodec::kWhatCreateInputSurface: 4011 { 4012 onCreateInputSurface(msg); 4013 handled = true; 4014 break; 4015 } 4016 4017 case ACodec::kWhatStart: 4018 { 4019 onStart(); 4020 handled = true; 4021 break; 4022 } 4023 4024 case ACodec::kWhatShutdown: 4025 { 4026 int32_t keepComponentAllocated; 4027 CHECK(msg->findInt32( 4028 "keepComponentAllocated", &keepComponentAllocated)); 4029 4030 mCodec->mExplicitShutdown = true; 4031 onShutdown(keepComponentAllocated); 4032 4033 handled = true; 4034 break; 4035 } 4036 4037 case ACodec::kWhatFlush: 4038 { 4039 sp<AMessage> notify = mCodec->mNotify->dup(); 4040 notify->setInt32("what", ACodec::kWhatFlushCompleted); 4041 notify->post(); 4042 4043 handled = true; 4044 break; 4045 } 4046 4047 default: 4048 return BaseState::onMessageReceived(msg); 4049 } 4050 4051 return handled; 4052} 4053 4054bool ACodec::LoadedState::onConfigureComponent( 4055 const sp<AMessage> &msg) { 4056 ALOGV("onConfigureComponent"); 4057 4058 CHECK(mCodec->mNode != NULL); 4059 4060 AString mime; 4061 CHECK(msg->findString("mime", &mime)); 4062 4063 status_t err = mCodec->configureCodec(mime.c_str(), msg); 4064 4065 if (err != OK) { 4066 ALOGE("[%s] configureCodec returning error %d", 4067 mCodec->mComponentName.c_str(), err); 4068 4069 mCodec->signalError(OMX_ErrorUndefined, err); 4070 return false; 4071 } 4072 4073 sp<RefBase> obj; 4074 if (msg->findObject("native-window", &obj) 4075 && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) { 4076 sp<NativeWindowWrapper> nativeWindow( 4077 static_cast<NativeWindowWrapper *>(obj.get())); 4078 CHECK(nativeWindow != NULL); 4079 mCodec->mNativeWindow = nativeWindow->getNativeWindow(); 4080 4081 native_window_set_scaling_mode( 4082 mCodec->mNativeWindow.get(), 4083 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 4084 } 4085 CHECK_EQ((status_t)OK, mCodec->initNativeWindow()); 4086 4087 { 4088 sp<AMessage> notify = mCodec->mNotify->dup(); 4089 notify->setInt32("what", ACodec::kWhatComponentConfigured); 4090 notify->setMessage("input-format", mCodec->mInputFormat); 4091 notify->setMessage("output-format", mCodec->mOutputFormat); 4092 notify->post(); 4093 } 4094 4095 return true; 4096} 4097 4098void ACodec::LoadedState::onCreateInputSurface( 4099 const sp<AMessage> & /* msg */) { 4100 ALOGV("onCreateInputSurface"); 4101 4102 sp<AMessage> notify = mCodec->mNotify->dup(); 4103 notify->setInt32("what", ACodec::kWhatInputSurfaceCreated); 4104 4105 sp<IGraphicBufferProducer> bufferProducer; 4106 status_t err; 4107 4108 err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput, 4109 &bufferProducer); 4110 4111 if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) { 4112 err = mCodec->mOMX->setInternalOption( 4113 mCodec->mNode, 4114 kPortIndexInput, 4115 IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY, 4116 &mCodec->mRepeatFrameDelayUs, 4117 sizeof(mCodec->mRepeatFrameDelayUs)); 4118 4119 if (err != OK) { 4120 ALOGE("[%s] Unable to configure option to repeat previous " 4121 "frames (err %d)", 4122 mCodec->mComponentName.c_str(), 4123 err); 4124 } 4125 } 4126 4127 if (err == OK && mCodec->mMaxPtsGapUs > 0ll) { 4128 err = mCodec->mOMX->setInternalOption( 4129 mCodec->mNode, 4130 kPortIndexInput, 4131 IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP, 4132 &mCodec->mMaxPtsGapUs, 4133 sizeof(mCodec->mMaxPtsGapUs)); 4134 4135 if (err != OK) { 4136 ALOGE("[%s] Unable to configure max timestamp gap (err %d)", 4137 mCodec->mComponentName.c_str(), 4138 err); 4139 } 4140 } 4141 4142 if (err == OK && mCodec->mTimePerCaptureUs > 0ll 4143 && mCodec->mTimePerFrameUs > 0ll) { 4144 int64_t timeLapse[2]; 4145 timeLapse[0] = mCodec->mTimePerFrameUs; 4146 timeLapse[1] = mCodec->mTimePerCaptureUs; 4147 err = mCodec->mOMX->setInternalOption( 4148 mCodec->mNode, 4149 kPortIndexInput, 4150 IOMX::INTERNAL_OPTION_TIME_LAPSE, 4151 &timeLapse[0], 4152 sizeof(timeLapse)); 4153 4154 if (err != OK) { 4155 ALOGE("[%s] Unable to configure time lapse (err %d)", 4156 mCodec->mComponentName.c_str(), 4157 err); 4158 } 4159 } 4160 4161 if (err == OK && mCodec->mCreateInputBuffersSuspended) { 4162 bool suspend = true; 4163 err = mCodec->mOMX->setInternalOption( 4164 mCodec->mNode, 4165 kPortIndexInput, 4166 IOMX::INTERNAL_OPTION_SUSPEND, 4167 &suspend, 4168 sizeof(suspend)); 4169 4170 if (err != OK) { 4171 ALOGE("[%s] Unable to configure option to suspend (err %d)", 4172 mCodec->mComponentName.c_str(), 4173 err); 4174 } 4175 } 4176 4177 if (err == OK) { 4178 notify->setObject("input-surface", 4179 new BufferProducerWrapper(bufferProducer)); 4180 } else { 4181 // Can't use mCodec->signalError() here -- MediaCodec won't forward 4182 // the error through because it's in the "configured" state. We 4183 // send a kWhatInputSurfaceCreated with an error value instead. 4184 ALOGE("[%s] onCreateInputSurface returning error %d", 4185 mCodec->mComponentName.c_str(), err); 4186 notify->setInt32("err", err); 4187 } 4188 notify->post(); 4189} 4190 4191void ACodec::LoadedState::onStart() { 4192 ALOGV("onStart"); 4193 4194 CHECK_EQ(mCodec->mOMX->sendCommand( 4195 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle), 4196 (status_t)OK); 4197 4198 mCodec->changeState(mCodec->mLoadedToIdleState); 4199} 4200 4201//////////////////////////////////////////////////////////////////////////////// 4202 4203ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 4204 : BaseState(codec) { 4205} 4206 4207void ACodec::LoadedToIdleState::stateEntered() { 4208 ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 4209 4210 status_t err; 4211 if ((err = allocateBuffers()) != OK) { 4212 ALOGE("Failed to allocate buffers after transitioning to IDLE state " 4213 "(error 0x%08x)", 4214 err); 4215 4216 mCodec->signalError(OMX_ErrorUndefined, err); 4217 4218 mCodec->changeState(mCodec->mLoadedState); 4219 } 4220} 4221 4222status_t ACodec::LoadedToIdleState::allocateBuffers() { 4223 status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 4224 4225 if (err != OK) { 4226 return err; 4227 } 4228 4229 return mCodec->allocateBuffersOnPort(kPortIndexOutput); 4230} 4231 4232bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 4233 switch (msg->what()) { 4234 case kWhatSetParameters: 4235 case kWhatShutdown: 4236 { 4237 mCodec->deferMessage(msg); 4238 return true; 4239 } 4240 4241 case kWhatSignalEndOfInputStream: 4242 { 4243 mCodec->onSignalEndOfInputStream(); 4244 return true; 4245 } 4246 4247 case kWhatResume: 4248 { 4249 // We'll be active soon enough. 4250 return true; 4251 } 4252 4253 case kWhatFlush: 4254 { 4255 // We haven't even started yet, so we're flushed alright... 4256 sp<AMessage> notify = mCodec->mNotify->dup(); 4257 notify->setInt32("what", ACodec::kWhatFlushCompleted); 4258 notify->post(); 4259 return true; 4260 } 4261 4262 default: 4263 return BaseState::onMessageReceived(msg); 4264 } 4265} 4266 4267bool ACodec::LoadedToIdleState::onOMXEvent( 4268 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4269 switch (event) { 4270 case OMX_EventCmdComplete: 4271 { 4272 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 4273 CHECK_EQ(data2, (OMX_U32)OMX_StateIdle); 4274 4275 CHECK_EQ(mCodec->mOMX->sendCommand( 4276 mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting), 4277 (status_t)OK); 4278 4279 mCodec->changeState(mCodec->mIdleToExecutingState); 4280 4281 return true; 4282 } 4283 4284 default: 4285 return BaseState::onOMXEvent(event, data1, data2); 4286 } 4287} 4288 4289//////////////////////////////////////////////////////////////////////////////// 4290 4291ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 4292 : BaseState(codec) { 4293} 4294 4295void ACodec::IdleToExecutingState::stateEntered() { 4296 ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 4297} 4298 4299bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 4300 switch (msg->what()) { 4301 case kWhatSetParameters: 4302 case kWhatShutdown: 4303 { 4304 mCodec->deferMessage(msg); 4305 return true; 4306 } 4307 4308 case kWhatResume: 4309 { 4310 // We'll be active soon enough. 4311 return true; 4312 } 4313 4314 case kWhatFlush: 4315 { 4316 // We haven't even started yet, so we're flushed alright... 4317 sp<AMessage> notify = mCodec->mNotify->dup(); 4318 notify->setInt32("what", ACodec::kWhatFlushCompleted); 4319 notify->post(); 4320 4321 return true; 4322 } 4323 4324 case kWhatSignalEndOfInputStream: 4325 { 4326 mCodec->onSignalEndOfInputStream(); 4327 return true; 4328 } 4329 4330 default: 4331 return BaseState::onMessageReceived(msg); 4332 } 4333} 4334 4335bool ACodec::IdleToExecutingState::onOMXEvent( 4336 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4337 switch (event) { 4338 case OMX_EventCmdComplete: 4339 { 4340 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 4341 CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting); 4342 4343 mCodec->mExecutingState->resume(); 4344 mCodec->changeState(mCodec->mExecutingState); 4345 4346 return true; 4347 } 4348 4349 default: 4350 return BaseState::onOMXEvent(event, data1, data2); 4351 } 4352} 4353 4354//////////////////////////////////////////////////////////////////////////////// 4355 4356ACodec::ExecutingState::ExecutingState(ACodec *codec) 4357 : BaseState(codec), 4358 mActive(false) { 4359} 4360 4361ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 4362 OMX_U32 /* portIndex */) { 4363 return RESUBMIT_BUFFERS; 4364} 4365 4366void ACodec::ExecutingState::submitOutputMetaBuffers() { 4367 // submit as many buffers as there are input buffers with the codec 4368 // in case we are in port reconfiguring 4369 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 4370 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 4371 4372 if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) { 4373 if (mCodec->submitOutputMetaDataBuffer() != OK) 4374 break; 4375 } 4376 } 4377 4378 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 4379 mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround(); 4380} 4381 4382void ACodec::ExecutingState::submitRegularOutputBuffers() { 4383 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 4384 BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 4385 4386 if (mCodec->mNativeWindow != NULL) { 4387 CHECK(info->mStatus == BufferInfo::OWNED_BY_US 4388 || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW); 4389 4390 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 4391 continue; 4392 } 4393 } else { 4394 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 4395 } 4396 4397 ALOGV("[%s] calling fillBuffer %p", 4398 mCodec->mComponentName.c_str(), info->mBufferID); 4399 4400 CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), 4401 (status_t)OK); 4402 4403 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 4404 } 4405} 4406 4407void ACodec::ExecutingState::submitOutputBuffers() { 4408 submitRegularOutputBuffers(); 4409 if (mCodec->mStoreMetaDataInOutputBuffers) { 4410 submitOutputMetaBuffers(); 4411 } 4412} 4413 4414void ACodec::ExecutingState::resume() { 4415 if (mActive) { 4416 ALOGV("[%s] We're already active, no need to resume.", 4417 mCodec->mComponentName.c_str()); 4418 4419 return; 4420 } 4421 4422 submitOutputBuffers(); 4423 4424 // Post the first input buffer. 4425 CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u); 4426 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0); 4427 4428 postFillThisBuffer(info); 4429 4430 mActive = true; 4431} 4432 4433void ACodec::ExecutingState::stateEntered() { 4434 ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 4435 4436 mCodec->processDeferredMessages(); 4437} 4438 4439bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 4440 bool handled = false; 4441 4442 switch (msg->what()) { 4443 case kWhatShutdown: 4444 { 4445 int32_t keepComponentAllocated; 4446 CHECK(msg->findInt32( 4447 "keepComponentAllocated", &keepComponentAllocated)); 4448 4449 mCodec->mShutdownInProgress = true; 4450 mCodec->mExplicitShutdown = true; 4451 mCodec->mKeepComponentAllocated = keepComponentAllocated; 4452 4453 mActive = false; 4454 4455 CHECK_EQ(mCodec->mOMX->sendCommand( 4456 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle), 4457 (status_t)OK); 4458 4459 mCodec->changeState(mCodec->mExecutingToIdleState); 4460 4461 handled = true; 4462 break; 4463 } 4464 4465 case kWhatFlush: 4466 { 4467 ALOGV("[%s] ExecutingState flushing now " 4468 "(codec owns %d/%d input, %d/%d output).", 4469 mCodec->mComponentName.c_str(), 4470 mCodec->countBuffersOwnedByComponent(kPortIndexInput), 4471 mCodec->mBuffers[kPortIndexInput].size(), 4472 mCodec->countBuffersOwnedByComponent(kPortIndexOutput), 4473 mCodec->mBuffers[kPortIndexOutput].size()); 4474 4475 mActive = false; 4476 4477 CHECK_EQ(mCodec->mOMX->sendCommand( 4478 mCodec->mNode, OMX_CommandFlush, OMX_ALL), 4479 (status_t)OK); 4480 4481 mCodec->changeState(mCodec->mFlushingState); 4482 handled = true; 4483 break; 4484 } 4485 4486 case kWhatResume: 4487 { 4488 resume(); 4489 4490 handled = true; 4491 break; 4492 } 4493 4494 case kWhatRequestIDRFrame: 4495 { 4496 status_t err = mCodec->requestIDRFrame(); 4497 if (err != OK) { 4498 ALOGW("Requesting an IDR frame failed."); 4499 } 4500 4501 handled = true; 4502 break; 4503 } 4504 4505 case kWhatSetParameters: 4506 { 4507 sp<AMessage> params; 4508 CHECK(msg->findMessage("params", ¶ms)); 4509 4510 status_t err = mCodec->setParameters(params); 4511 4512 sp<AMessage> reply; 4513 if (msg->findMessage("reply", &reply)) { 4514 reply->setInt32("err", err); 4515 reply->post(); 4516 } 4517 4518 handled = true; 4519 break; 4520 } 4521 4522 case ACodec::kWhatSignalEndOfInputStream: 4523 { 4524 mCodec->onSignalEndOfInputStream(); 4525 handled = true; 4526 break; 4527 } 4528 4529 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** 4530 case kWhatSubmitOutputMetaDataBufferIfEOS: 4531 { 4532 if (mCodec->mPortEOS[kPortIndexInput] && 4533 !mCodec->mPortEOS[kPortIndexOutput]) { 4534 status_t err = mCodec->submitOutputMetaDataBuffer(); 4535 if (err == OK) { 4536 mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround(); 4537 } 4538 } 4539 return true; 4540 } 4541 4542 default: 4543 handled = BaseState::onMessageReceived(msg); 4544 break; 4545 } 4546 4547 return handled; 4548} 4549 4550status_t ACodec::setParameters(const sp<AMessage> ¶ms) { 4551 int32_t videoBitrate; 4552 if (params->findInt32("video-bitrate", &videoBitrate)) { 4553 OMX_VIDEO_CONFIG_BITRATETYPE configParams; 4554 InitOMXParams(&configParams); 4555 configParams.nPortIndex = kPortIndexOutput; 4556 configParams.nEncodeBitrate = videoBitrate; 4557 4558 status_t err = mOMX->setConfig( 4559 mNode, 4560 OMX_IndexConfigVideoBitrate, 4561 &configParams, 4562 sizeof(configParams)); 4563 4564 if (err != OK) { 4565 ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d", 4566 videoBitrate, err); 4567 4568 return err; 4569 } 4570 } 4571 4572 int64_t skipFramesBeforeUs; 4573 if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) { 4574 status_t err = 4575 mOMX->setInternalOption( 4576 mNode, 4577 kPortIndexInput, 4578 IOMX::INTERNAL_OPTION_START_TIME, 4579 &skipFramesBeforeUs, 4580 sizeof(skipFramesBeforeUs)); 4581 4582 if (err != OK) { 4583 ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err); 4584 return err; 4585 } 4586 } 4587 4588 int32_t dropInputFrames; 4589 if (params->findInt32("drop-input-frames", &dropInputFrames)) { 4590 bool suspend = dropInputFrames != 0; 4591 4592 status_t err = 4593 mOMX->setInternalOption( 4594 mNode, 4595 kPortIndexInput, 4596 IOMX::INTERNAL_OPTION_SUSPEND, 4597 &suspend, 4598 sizeof(suspend)); 4599 4600 if (err != OK) { 4601 ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err); 4602 return err; 4603 } 4604 } 4605 4606 int32_t dummy; 4607 if (params->findInt32("request-sync", &dummy)) { 4608 status_t err = requestIDRFrame(); 4609 4610 if (err != OK) { 4611 ALOGE("Requesting a sync frame failed w/ err %d", err); 4612 return err; 4613 } 4614 } 4615 4616 return OK; 4617} 4618 4619void ACodec::onSignalEndOfInputStream() { 4620 sp<AMessage> notify = mNotify->dup(); 4621 notify->setInt32("what", ACodec::kWhatSignaledInputEOS); 4622 4623 status_t err = mOMX->signalEndOfInputStream(mNode); 4624 if (err != OK) { 4625 notify->setInt32("err", err); 4626 } 4627 notify->post(); 4628} 4629 4630bool ACodec::ExecutingState::onOMXEvent( 4631 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4632 switch (event) { 4633 case OMX_EventPortSettingsChanged: 4634 { 4635 CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 4636 4637 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 4638 mCodec->mMetaDataBuffersToSubmit = 0; 4639 CHECK_EQ(mCodec->mOMX->sendCommand( 4640 mCodec->mNode, 4641 OMX_CommandPortDisable, kPortIndexOutput), 4642 (status_t)OK); 4643 4644 mCodec->freeOutputBuffersNotOwnedByComponent(); 4645 4646 mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 4647 } else if (data2 == OMX_IndexConfigCommonOutputCrop) { 4648 mCodec->mSentFormat = false; 4649 } else { 4650 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx", 4651 mCodec->mComponentName.c_str(), data2); 4652 } 4653 4654 return true; 4655 } 4656 4657 case OMX_EventBufferFlag: 4658 { 4659 return true; 4660 } 4661 4662 default: 4663 return BaseState::onOMXEvent(event, data1, data2); 4664 } 4665} 4666 4667//////////////////////////////////////////////////////////////////////////////// 4668 4669ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 4670 ACodec *codec) 4671 : BaseState(codec) { 4672} 4673 4674ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 4675 OMX_U32 portIndex) { 4676 if (portIndex == kPortIndexOutput) { 4677 return FREE_BUFFERS; 4678 } 4679 4680 CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 4681 4682 return RESUBMIT_BUFFERS; 4683} 4684 4685bool ACodec::OutputPortSettingsChangedState::onMessageReceived( 4686 const sp<AMessage> &msg) { 4687 bool handled = false; 4688 4689 switch (msg->what()) { 4690 case kWhatFlush: 4691 case kWhatShutdown: 4692 case kWhatResume: 4693 { 4694 if (msg->what() == kWhatResume) { 4695 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 4696 } 4697 4698 mCodec->deferMessage(msg); 4699 handled = true; 4700 break; 4701 } 4702 4703 default: 4704 handled = BaseState::onMessageReceived(msg); 4705 break; 4706 } 4707 4708 return handled; 4709} 4710 4711void ACodec::OutputPortSettingsChangedState::stateEntered() { 4712 ALOGV("[%s] Now handling output port settings change", 4713 mCodec->mComponentName.c_str()); 4714} 4715 4716bool ACodec::OutputPortSettingsChangedState::onOMXEvent( 4717 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4718 switch (event) { 4719 case OMX_EventCmdComplete: 4720 { 4721 if (data1 == (OMX_U32)OMX_CommandPortDisable) { 4722 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput); 4723 4724 ALOGV("[%s] Output port now disabled.", 4725 mCodec->mComponentName.c_str()); 4726 4727 CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty()); 4728 mCodec->mDealer[kPortIndexOutput].clear(); 4729 4730 CHECK_EQ(mCodec->mOMX->sendCommand( 4731 mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput), 4732 (status_t)OK); 4733 4734 status_t err; 4735 if ((err = mCodec->allocateBuffersOnPort( 4736 kPortIndexOutput)) != OK) { 4737 ALOGE("Failed to allocate output port buffers after " 4738 "port reconfiguration (error 0x%08x)", 4739 err); 4740 4741 mCodec->signalError(OMX_ErrorUndefined, err); 4742 4743 // This is technically not correct, but appears to be 4744 // the only way to free the component instance. 4745 // Controlled transitioning from excecuting->idle 4746 // and idle->loaded seem impossible probably because 4747 // the output port never finishes re-enabling. 4748 mCodec->mShutdownInProgress = true; 4749 mCodec->mKeepComponentAllocated = false; 4750 mCodec->changeState(mCodec->mLoadedState); 4751 } 4752 4753 return true; 4754 } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 4755 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput); 4756 4757 mCodec->mSentFormat = false; 4758 4759 ALOGV("[%s] Output port now reenabled.", 4760 mCodec->mComponentName.c_str()); 4761 4762 if (mCodec->mExecutingState->active()) { 4763 mCodec->mExecutingState->submitOutputBuffers(); 4764 } 4765 4766 mCodec->changeState(mCodec->mExecutingState); 4767 4768 return true; 4769 } 4770 4771 return false; 4772 } 4773 4774 default: 4775 return false; 4776 } 4777} 4778 4779//////////////////////////////////////////////////////////////////////////////// 4780 4781ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 4782 : BaseState(codec), 4783 mComponentNowIdle(false) { 4784} 4785 4786bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 4787 bool handled = false; 4788 4789 switch (msg->what()) { 4790 case kWhatFlush: 4791 { 4792 // Don't send me a flush request if you previously wanted me 4793 // to shutdown. 4794 TRESPASS(); 4795 break; 4796 } 4797 4798 case kWhatShutdown: 4799 { 4800 // We're already doing that... 4801 4802 handled = true; 4803 break; 4804 } 4805 4806 default: 4807 handled = BaseState::onMessageReceived(msg); 4808 break; 4809 } 4810 4811 return handled; 4812} 4813 4814void ACodec::ExecutingToIdleState::stateEntered() { 4815 ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 4816 4817 mComponentNowIdle = false; 4818 mCodec->mSentFormat = false; 4819} 4820 4821bool ACodec::ExecutingToIdleState::onOMXEvent( 4822 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4823 switch (event) { 4824 case OMX_EventCmdComplete: 4825 { 4826 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 4827 CHECK_EQ(data2, (OMX_U32)OMX_StateIdle); 4828 4829 mComponentNowIdle = true; 4830 4831 changeStateIfWeOwnAllBuffers(); 4832 4833 return true; 4834 } 4835 4836 case OMX_EventPortSettingsChanged: 4837 case OMX_EventBufferFlag: 4838 { 4839 // We're shutting down and don't care about this anymore. 4840 return true; 4841 } 4842 4843 default: 4844 return BaseState::onOMXEvent(event, data1, data2); 4845 } 4846} 4847 4848void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 4849 if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) { 4850 CHECK_EQ(mCodec->mOMX->sendCommand( 4851 mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded), 4852 (status_t)OK); 4853 4854 CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK); 4855 CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK); 4856 4857 if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) 4858 && mCodec->mNativeWindow != NULL) { 4859 // We push enough 1x1 blank buffers to ensure that one of 4860 // them has made it to the display. This allows the OMX 4861 // component teardown to zero out any protected buffers 4862 // without the risk of scanning out one of those buffers. 4863 mCodec->pushBlankBuffersToNativeWindow(); 4864 } 4865 4866 mCodec->changeState(mCodec->mIdleToLoadedState); 4867 } 4868} 4869 4870void ACodec::ExecutingToIdleState::onInputBufferFilled( 4871 const sp<AMessage> &msg) { 4872 BaseState::onInputBufferFilled(msg); 4873 4874 changeStateIfWeOwnAllBuffers(); 4875} 4876 4877void ACodec::ExecutingToIdleState::onOutputBufferDrained( 4878 const sp<AMessage> &msg) { 4879 BaseState::onOutputBufferDrained(msg); 4880 4881 changeStateIfWeOwnAllBuffers(); 4882} 4883 4884//////////////////////////////////////////////////////////////////////////////// 4885 4886ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 4887 : BaseState(codec) { 4888} 4889 4890bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 4891 bool handled = false; 4892 4893 switch (msg->what()) { 4894 case kWhatShutdown: 4895 { 4896 // We're already doing that... 4897 4898 handled = true; 4899 break; 4900 } 4901 4902 case kWhatFlush: 4903 { 4904 // Don't send me a flush request if you previously wanted me 4905 // to shutdown. 4906 TRESPASS(); 4907 break; 4908 } 4909 4910 default: 4911 handled = BaseState::onMessageReceived(msg); 4912 break; 4913 } 4914 4915 return handled; 4916} 4917 4918void ACodec::IdleToLoadedState::stateEntered() { 4919 ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 4920} 4921 4922bool ACodec::IdleToLoadedState::onOMXEvent( 4923 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4924 switch (event) { 4925 case OMX_EventCmdComplete: 4926 { 4927 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 4928 CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded); 4929 4930 mCodec->changeState(mCodec->mLoadedState); 4931 4932 return true; 4933 } 4934 4935 default: 4936 return BaseState::onOMXEvent(event, data1, data2); 4937 } 4938} 4939 4940//////////////////////////////////////////////////////////////////////////////// 4941 4942ACodec::FlushingState::FlushingState(ACodec *codec) 4943 : BaseState(codec) { 4944} 4945 4946void ACodec::FlushingState::stateEntered() { 4947 ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 4948 4949 mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 4950} 4951 4952bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 4953 bool handled = false; 4954 4955 switch (msg->what()) { 4956 case kWhatShutdown: 4957 { 4958 mCodec->deferMessage(msg); 4959 break; 4960 } 4961 4962 case kWhatFlush: 4963 { 4964 // We're already doing this right now. 4965 handled = true; 4966 break; 4967 } 4968 4969 default: 4970 handled = BaseState::onMessageReceived(msg); 4971 break; 4972 } 4973 4974 return handled; 4975} 4976 4977bool ACodec::FlushingState::onOMXEvent( 4978 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4979 ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)", 4980 mCodec->mComponentName.c_str(), event, data1); 4981 4982 switch (event) { 4983 case OMX_EventCmdComplete: 4984 { 4985 CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush); 4986 4987 if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 4988 CHECK(!mFlushComplete[data2]); 4989 mFlushComplete[data2] = true; 4990 4991 if (mFlushComplete[kPortIndexInput] 4992 && mFlushComplete[kPortIndexOutput]) { 4993 changeStateIfWeOwnAllBuffers(); 4994 } 4995 } else { 4996 CHECK_EQ(data2, OMX_ALL); 4997 CHECK(mFlushComplete[kPortIndexInput]); 4998 CHECK(mFlushComplete[kPortIndexOutput]); 4999 5000 changeStateIfWeOwnAllBuffers(); 5001 } 5002 5003 return true; 5004 } 5005 5006 case OMX_EventPortSettingsChanged: 5007 { 5008 sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id()); 5009 msg->setInt32("type", omx_message::EVENT); 5010 msg->setInt32("node", mCodec->mNode); 5011 msg->setInt32("event", event); 5012 msg->setInt32("data1", data1); 5013 msg->setInt32("data2", data2); 5014 5015 ALOGV("[%s] Deferring OMX_EventPortSettingsChanged", 5016 mCodec->mComponentName.c_str()); 5017 5018 mCodec->deferMessage(msg); 5019 5020 return true; 5021 } 5022 5023 default: 5024 return BaseState::onOMXEvent(event, data1, data2); 5025 } 5026 5027 return true; 5028} 5029 5030void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 5031 BaseState::onOutputBufferDrained(msg); 5032 5033 changeStateIfWeOwnAllBuffers(); 5034} 5035 5036void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 5037 BaseState::onInputBufferFilled(msg); 5038 5039 changeStateIfWeOwnAllBuffers(); 5040} 5041 5042void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 5043 if (mFlushComplete[kPortIndexInput] 5044 && mFlushComplete[kPortIndexOutput] 5045 && mCodec->allYourBuffersAreBelongToUs()) { 5046 // We now own all buffers except possibly those still queued with 5047 // the native window for rendering. Let's get those back as well. 5048 mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs(); 5049 5050 sp<AMessage> notify = mCodec->mNotify->dup(); 5051 notify->setInt32("what", ACodec::kWhatFlushCompleted); 5052 notify->post(); 5053 5054 mCodec->mPortEOS[kPortIndexInput] = 5055 mCodec->mPortEOS[kPortIndexOutput] = false; 5056 5057 mCodec->mInputEOSResult = OK; 5058 5059 if (mCodec->mSkipCutBuffer != NULL) { 5060 mCodec->mSkipCutBuffer->clear(); 5061 } 5062 5063 mCodec->changeState(mCodec->mExecutingState); 5064 } 5065} 5066 5067} // namespace android 5068