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