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