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