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