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