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