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