ACodec.cpp revision 349d3fcb4afacf754f7b5b5186d2f258f5bf35e7
1//#define LOG_NDEBUG 0 2#define LOG_TAG "ACodec" 3 4#include <media/stagefright/ACodec.h> 5 6#include <binder/MemoryDealer.h> 7 8#include <media/stagefright/foundation/hexdump.h> 9#include <media/stagefright/foundation/ABuffer.h> 10#include <media/stagefright/foundation/ADebug.h> 11#include <media/stagefright/foundation/AMessage.h> 12 13#include <media/stagefright/MediaDefs.h> 14#include <media/stagefright/OMXClient.h> 15 16#include <surfaceflinger/Surface.h> 17 18#include <OMX_Component.h> 19 20namespace android { 21 22template<class T> 23static void InitOMXParams(T *params) { 24 params->nSize = sizeof(T); 25 params->nVersion.s.nVersionMajor = 1; 26 params->nVersion.s.nVersionMinor = 0; 27 params->nVersion.s.nRevision = 0; 28 params->nVersion.s.nStep = 0; 29} 30 31struct CodecObserver : public BnOMXObserver { 32 CodecObserver() {} 33 34 void setNotificationMessage(const sp<AMessage> &msg) { 35 mNotify = msg; 36 } 37 38 // from IOMXObserver 39 virtual void onMessage(const omx_message &omx_msg) { 40 sp<AMessage> msg = mNotify->dup(); 41 42 msg->setInt32("type", omx_msg.type); 43 msg->setPointer("node", omx_msg.node); 44 45 switch (omx_msg.type) { 46 case omx_message::EVENT: 47 { 48 msg->setInt32("event", omx_msg.u.event_data.event); 49 msg->setInt32("data1", omx_msg.u.event_data.data1); 50 msg->setInt32("data2", omx_msg.u.event_data.data2); 51 break; 52 } 53 54 case omx_message::EMPTY_BUFFER_DONE: 55 { 56 msg->setPointer("buffer", omx_msg.u.buffer_data.buffer); 57 break; 58 } 59 60 case omx_message::FILL_BUFFER_DONE: 61 { 62 msg->setPointer( 63 "buffer", omx_msg.u.extended_buffer_data.buffer); 64 msg->setInt32( 65 "range_offset", 66 omx_msg.u.extended_buffer_data.range_offset); 67 msg->setInt32( 68 "range_length", 69 omx_msg.u.extended_buffer_data.range_length); 70 msg->setInt32( 71 "flags", 72 omx_msg.u.extended_buffer_data.flags); 73 msg->setInt64( 74 "timestamp", 75 omx_msg.u.extended_buffer_data.timestamp); 76 msg->setPointer( 77 "platform_private", 78 omx_msg.u.extended_buffer_data.platform_private); 79 msg->setPointer( 80 "data_ptr", 81 omx_msg.u.extended_buffer_data.data_ptr); 82 break; 83 } 84 85 default: 86 TRESPASS(); 87 break; 88 } 89 90 msg->post(); 91 } 92 93protected: 94 virtual ~CodecObserver() {} 95 96private: 97 sp<AMessage> mNotify; 98 99 DISALLOW_EVIL_CONSTRUCTORS(CodecObserver); 100}; 101 102//////////////////////////////////////////////////////////////////////////////// 103 104struct ACodec::BaseState : public AState { 105 BaseState(ACodec *codec, const sp<AState> &parentState = NULL); 106 107protected: 108 enum PortMode { 109 KEEP_BUFFERS, 110 RESUBMIT_BUFFERS, 111 FREE_BUFFERS, 112 }; 113 114 ACodec *mCodec; 115 116 virtual PortMode getPortMode(OMX_U32 portIndex); 117 118 virtual bool onMessageReceived(const sp<AMessage> &msg); 119 120 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 121 122 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 123 virtual void onInputBufferFilled(const sp<AMessage> &msg); 124 125 void postFillThisBuffer(BufferInfo *info); 126 127private: 128 bool onOMXMessage(const sp<AMessage> &msg); 129 130 bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID); 131 132 bool onOMXFillBufferDone( 133 IOMX::buffer_id bufferID, 134 size_t rangeOffset, size_t rangeLength, 135 OMX_U32 flags, 136 int64_t timeUs, 137 void *platformPrivate, 138 void *dataPtr); 139 140 void getMoreInputDataIfPossible(); 141 142 DISALLOW_EVIL_CONSTRUCTORS(BaseState); 143}; 144 145//////////////////////////////////////////////////////////////////////////////// 146 147struct ACodec::UninitializedState : public ACodec::BaseState { 148 UninitializedState(ACodec *codec); 149 150protected: 151 virtual bool onMessageReceived(const sp<AMessage> &msg); 152 153private: 154 void onSetup(const sp<AMessage> &msg); 155 156 DISALLOW_EVIL_CONSTRUCTORS(UninitializedState); 157}; 158 159//////////////////////////////////////////////////////////////////////////////// 160 161struct ACodec::LoadedToIdleState : public ACodec::BaseState { 162 LoadedToIdleState(ACodec *codec); 163 164protected: 165 virtual bool onMessageReceived(const sp<AMessage> &msg); 166 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 167 virtual void stateEntered(); 168 169private: 170 status_t allocateBuffers(); 171 172 DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState); 173}; 174 175//////////////////////////////////////////////////////////////////////////////// 176 177struct ACodec::IdleToExecutingState : public ACodec::BaseState { 178 IdleToExecutingState(ACodec *codec); 179 180protected: 181 virtual bool onMessageReceived(const sp<AMessage> &msg); 182 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 183 virtual void stateEntered(); 184 185private: 186 DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState); 187}; 188 189//////////////////////////////////////////////////////////////////////////////// 190 191struct ACodec::ExecutingState : public ACodec::BaseState { 192 ExecutingState(ACodec *codec); 193 194 void submitOutputBuffers(); 195 196 // Submit output buffers to the decoder, submit input buffers to client 197 // to fill with data. 198 void resume(); 199 200 // Returns true iff input and output buffers are in play. 201 bool active() const { return mActive; } 202 203protected: 204 virtual PortMode getPortMode(OMX_U32 portIndex); 205 virtual bool onMessageReceived(const sp<AMessage> &msg); 206 virtual void stateEntered(); 207 208 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 209 210private: 211 bool mActive; 212 213 DISALLOW_EVIL_CONSTRUCTORS(ExecutingState); 214}; 215 216//////////////////////////////////////////////////////////////////////////////// 217 218struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState { 219 OutputPortSettingsChangedState(ACodec *codec); 220 221protected: 222 virtual PortMode getPortMode(OMX_U32 portIndex); 223 virtual bool onMessageReceived(const sp<AMessage> &msg); 224 virtual void stateEntered(); 225 226 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 227 228private: 229 DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState); 230}; 231 232//////////////////////////////////////////////////////////////////////////////// 233 234struct ACodec::ExecutingToIdleState : public ACodec::BaseState { 235 ExecutingToIdleState(ACodec *codec); 236 237protected: 238 virtual bool onMessageReceived(const sp<AMessage> &msg); 239 virtual void stateEntered(); 240 241 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 242 243 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 244 virtual void onInputBufferFilled(const sp<AMessage> &msg); 245 246private: 247 void changeStateIfWeOwnAllBuffers(); 248 249 DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState); 250}; 251 252//////////////////////////////////////////////////////////////////////////////// 253 254struct ACodec::IdleToLoadedState : public ACodec::BaseState { 255 IdleToLoadedState(ACodec *codec); 256 257protected: 258 virtual bool onMessageReceived(const sp<AMessage> &msg); 259 virtual void stateEntered(); 260 261 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 262 263private: 264 DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState); 265}; 266 267//////////////////////////////////////////////////////////////////////////////// 268 269struct ACodec::ErrorState : public ACodec::BaseState { 270 ErrorState(ACodec *codec); 271 272protected: 273 virtual bool onMessageReceived(const sp<AMessage> &msg); 274 virtual void stateEntered(); 275 276 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 277 278private: 279 DISALLOW_EVIL_CONSTRUCTORS(ErrorState); 280}; 281 282//////////////////////////////////////////////////////////////////////////////// 283 284struct ACodec::FlushingState : public ACodec::BaseState { 285 FlushingState(ACodec *codec); 286 287protected: 288 virtual bool onMessageReceived(const sp<AMessage> &msg); 289 virtual void stateEntered(); 290 291 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 292 293 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 294 virtual void onInputBufferFilled(const sp<AMessage> &msg); 295 296private: 297 bool mFlushComplete[2]; 298 299 void changeStateIfWeOwnAllBuffers(); 300 301 DISALLOW_EVIL_CONSTRUCTORS(FlushingState); 302}; 303 304//////////////////////////////////////////////////////////////////////////////// 305 306ACodec::ACodec() 307 : mNode(NULL), 308 mSentFormat(false) { 309 mUninitializedState = new UninitializedState(this); 310 mLoadedToIdleState = new LoadedToIdleState(this); 311 mIdleToExecutingState = new IdleToExecutingState(this); 312 mExecutingState = new ExecutingState(this); 313 314 mOutputPortSettingsChangedState = 315 new OutputPortSettingsChangedState(this); 316 317 mExecutingToIdleState = new ExecutingToIdleState(this); 318 mIdleToLoadedState = new IdleToLoadedState(this); 319 mErrorState = new ErrorState(this); 320 mFlushingState = new FlushingState(this); 321 322 mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false; 323 324 changeState(mUninitializedState); 325} 326 327ACodec::~ACodec() { 328} 329 330void ACodec::setNotificationMessage(const sp<AMessage> &msg) { 331 mNotify = msg; 332} 333 334void ACodec::initiateSetup(const sp<AMessage> &msg) { 335 msg->setWhat(kWhatSetup); 336 msg->setTarget(id()); 337 msg->post(); 338} 339 340void ACodec::signalFlush() { 341 (new AMessage(kWhatFlush, id()))->post(); 342} 343 344void ACodec::signalResume() { 345 (new AMessage(kWhatResume, id()))->post(); 346} 347 348void ACodec::initiateShutdown() { 349 (new AMessage(kWhatShutdown, id()))->post(); 350} 351 352status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) { 353 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 354 355 CHECK(mDealer[portIndex] == NULL); 356 CHECK(mBuffers[portIndex].isEmpty()); 357 358 if (mNativeWindow != NULL && portIndex == kPortIndexOutput) { 359 return allocateOutputBuffersFromNativeWindow(); 360 } 361 362 OMX_PARAM_PORTDEFINITIONTYPE def; 363 InitOMXParams(&def); 364 def.nPortIndex = portIndex; 365 366 status_t err = mOMX->getParameter( 367 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 368 369 if (err != OK) { 370 return err; 371 } 372 373 LOGV("[%s] Allocating %lu buffers of size %lu on %s port", 374 mComponentName.c_str(), 375 def.nBufferCountActual, def.nBufferSize, 376 portIndex == kPortIndexInput ? "input" : "output"); 377 378 size_t totalSize = def.nBufferCountActual * def.nBufferSize; 379 mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec"); 380 381 for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { 382 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); 383 CHECK(mem.get() != NULL); 384 385 IOMX::buffer_id buffer; 386#if 0 387 err = mOMX->allocateBufferWithBackup(mNode, portIndex, mem, &buffer); 388#else 389 err = mOMX->useBuffer(mNode, portIndex, mem, &buffer); 390#endif 391 392 if (err != OK) { 393 return err; 394 } 395 396 BufferInfo info; 397 info.mBufferID = buffer; 398 info.mStatus = BufferInfo::OWNED_BY_US; 399 info.mData = new ABuffer(mem->pointer(), def.nBufferSize); 400 mBuffers[portIndex].push(info); 401 } 402 403 return OK; 404} 405 406status_t ACodec::allocateOutputBuffersFromNativeWindow() { 407 OMX_PARAM_PORTDEFINITIONTYPE def; 408 InitOMXParams(&def); 409 def.nPortIndex = kPortIndexOutput; 410 411 status_t err = mOMX->getParameter( 412 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 413 414 if (err != OK) { 415 return err; 416 } 417 418 err = native_window_set_buffers_geometry( 419 mNativeWindow.get(), 420 def.format.video.nFrameWidth, 421 def.format.video.nFrameHeight, 422 def.format.video.eColorFormat); 423 424 if (err != 0) { 425 LOGE("native_window_set_buffers_geometry failed: %s (%d)", 426 strerror(-err), -err); 427 return err; 428 } 429 430 // Increase the buffer count by one to allow for the ANativeWindow to hold 431 // on to one of the buffers. 432 def.nBufferCountActual++; 433 err = mOMX->setParameter( 434 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 435 436 if (err != OK) { 437 return err; 438 } 439 440 // Set up the native window. 441 // XXX TODO: Get the gralloc usage flags from the OMX plugin! 442 err = native_window_set_usage( 443 mNativeWindow.get(), 444 GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP); 445 446 if (err != 0) { 447 LOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err); 448 return err; 449 } 450 451 err = native_window_set_buffer_count( 452 mNativeWindow.get(), def.nBufferCountActual); 453 454 if (err != 0) { 455 LOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 456 -err); 457 return err; 458 } 459 460 // XXX TODO: Do something so the ANativeWindow knows that we'll need to get 461 // the same set of buffers. 462 463 LOGV("[%s] Allocating %lu buffers from a native window of size %lu on " 464 "output port", 465 mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize); 466 467 // Dequeue buffers and send them to OMX 468 OMX_U32 i; 469 for (i = 0; i < def.nBufferCountActual; i++) { 470 android_native_buffer_t *buf; 471 err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf); 472 if (err != 0) { 473 LOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 474 break; 475 } 476 477 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 478 IOMX::buffer_id bufferId; 479 err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer, 480 &bufferId); 481 if (err != 0) { 482 break; 483 } 484 485 LOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)", 486 mComponentName.c_str(), 487 bufferId, graphicBuffer.get()); 488 489 BufferInfo info; 490 info.mBufferID = bufferId; 491 info.mStatus = BufferInfo::OWNED_BY_US; 492 info.mData = new ABuffer(0); 493 info.mGraphicBuffer = graphicBuffer; 494 mBuffers[kPortIndexOutput].push(info); 495 } 496 497 OMX_U32 cancelStart; 498 OMX_U32 cancelEnd; 499 500 if (err != 0) { 501 // If an error occurred while dequeuing we need to cancel any buffers 502 // that were dequeued. 503 cancelStart = 0; 504 cancelEnd = i; 505 } else { 506 // Return the last two buffers to the native window. 507 // XXX TODO: The number of buffers the native window owns should 508 // probably be queried from it when we put the native window in 509 // fixed buffer pool mode (which needs to be implemented). 510 // Currently it's hard-coded to 2. 511 cancelStart = def.nBufferCountActual - 2; 512 cancelEnd = def.nBufferCountActual; 513 } 514 515 for (OMX_U32 i = cancelStart; i < cancelEnd; i++) { 516 BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 517 cancelBufferToNativeWindow(info); 518 } 519 520 return err; 521} 522 523status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) { 524 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 525 526 LOGV("[%s] Calling cancelBuffer on buffer %p", 527 mComponentName.c_str(), info->mBufferID); 528 529 int err = mNativeWindow->cancelBuffer( 530 mNativeWindow.get(), info->mGraphicBuffer.get()); 531 532 CHECK_EQ(err, 0); 533 534 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 535 536 return OK; 537} 538 539ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() { 540 android_native_buffer_t *buf; 541 CHECK_EQ(mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf), 0); 542 543 for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { 544 BufferInfo *info = 545 &mBuffers[kPortIndexOutput].editItemAt(i); 546 547 if (info->mGraphicBuffer->handle == buf->handle) { 548 CHECK_EQ((int)info->mStatus, 549 (int)BufferInfo::OWNED_BY_NATIVE_WINDOW); 550 551 info->mStatus = BufferInfo::OWNED_BY_US; 552 553 return info; 554 } 555 } 556 557 TRESPASS(); 558 559 return NULL; 560} 561 562status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) { 563 for (size_t i = mBuffers[portIndex].size(); i-- > 0;) { 564 CHECK_EQ((status_t)OK, freeBuffer(portIndex, i)); 565 } 566 567 mDealer[portIndex].clear(); 568 569 return OK; 570} 571 572status_t ACodec::freeOutputBuffersNotOwnedByComponent() { 573 for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { 574 BufferInfo *info = 575 &mBuffers[kPortIndexOutput].editItemAt(i); 576 577 if (info->mStatus != 578 BufferInfo::OWNED_BY_COMPONENT) { 579 // We shouldn't have sent out any buffers to the client at this 580 // point. 581 CHECK_NE((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM); 582 583 CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i)); 584 } 585 } 586 587 return OK; 588} 589 590status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) { 591 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 592 593 CHECK(info->mStatus == BufferInfo::OWNED_BY_US 594 || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW); 595 596 if (portIndex == kPortIndexOutput && mNativeWindow != NULL 597 && info->mStatus == BufferInfo::OWNED_BY_US) { 598 CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info)); 599 } 600 601 CHECK_EQ(mOMX->freeBuffer( 602 mNode, portIndex, info->mBufferID), 603 (status_t)OK); 604 605 mBuffers[portIndex].removeAt(i); 606 607 return OK; 608} 609 610ACodec::BufferInfo *ACodec::findBufferByID( 611 uint32_t portIndex, IOMX::buffer_id bufferID, 612 ssize_t *index) { 613 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 614 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 615 616 if (info->mBufferID == bufferID) { 617 if (index != NULL) { 618 *index = i; 619 } 620 return info; 621 } 622 } 623 624 TRESPASS(); 625 626 return NULL; 627} 628 629void ACodec::setComponentRole( 630 bool isEncoder, const char *mime) { 631 struct MimeToRole { 632 const char *mime; 633 const char *decoderRole; 634 const char *encoderRole; 635 }; 636 637 static const MimeToRole kMimeToRole[] = { 638 { MEDIA_MIMETYPE_AUDIO_MPEG, 639 "audio_decoder.mp3", "audio_encoder.mp3" }, 640 { MEDIA_MIMETYPE_AUDIO_AMR_NB, 641 "audio_decoder.amrnb", "audio_encoder.amrnb" }, 642 { MEDIA_MIMETYPE_AUDIO_AMR_WB, 643 "audio_decoder.amrwb", "audio_encoder.amrwb" }, 644 { MEDIA_MIMETYPE_AUDIO_AAC, 645 "audio_decoder.aac", "audio_encoder.aac" }, 646 { MEDIA_MIMETYPE_VIDEO_AVC, 647 "video_decoder.avc", "video_encoder.avc" }, 648 { MEDIA_MIMETYPE_VIDEO_MPEG4, 649 "video_decoder.mpeg4", "video_encoder.mpeg4" }, 650 { MEDIA_MIMETYPE_VIDEO_H263, 651 "video_decoder.h263", "video_encoder.h263" }, 652 }; 653 654 static const size_t kNumMimeToRole = 655 sizeof(kMimeToRole) / sizeof(kMimeToRole[0]); 656 657 size_t i; 658 for (i = 0; i < kNumMimeToRole; ++i) { 659 if (!strcasecmp(mime, kMimeToRole[i].mime)) { 660 break; 661 } 662 } 663 664 if (i == kNumMimeToRole) { 665 return; 666 } 667 668 const char *role = 669 isEncoder ? kMimeToRole[i].encoderRole 670 : kMimeToRole[i].decoderRole; 671 672 if (role != NULL) { 673 OMX_PARAM_COMPONENTROLETYPE roleParams; 674 InitOMXParams(&roleParams); 675 676 strncpy((char *)roleParams.cRole, 677 role, OMX_MAX_STRINGNAME_SIZE - 1); 678 679 roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 680 681 status_t err = mOMX->setParameter( 682 mNode, OMX_IndexParamStandardComponentRole, 683 &roleParams, sizeof(roleParams)); 684 685 if (err != OK) { 686 LOGW("[%s] Failed to set standard component role '%s'.", 687 mComponentName.c_str(), role); 688 } 689 } 690} 691 692void ACodec::configureCodec( 693 const char *mime, const sp<AMessage> &msg) { 694 setComponentRole(false /* isEncoder */, mime); 695 696 if (!strncasecmp(mime, "video/", 6)) { 697 int32_t width, height; 698 CHECK(msg->findInt32("width", &width)); 699 CHECK(msg->findInt32("height", &height)); 700 701 CHECK_EQ(setupVideoDecoder(mime, width, height), 702 (status_t)OK); 703 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 704 int32_t numChannels, sampleRate; 705 CHECK(msg->findInt32("channel-count", &numChannels)); 706 CHECK(msg->findInt32("sample-rate", &sampleRate)); 707 708 CHECK_EQ(setupAACDecoder(numChannels, sampleRate), (status_t)OK); 709 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { 710 } else { 711 TRESPASS(); 712 } 713 714 int32_t maxInputSize; 715 if (msg->findInt32("max-input-size", &maxInputSize)) { 716 CHECK_EQ(setMinBufferSize(kPortIndexInput, (size_t)maxInputSize), 717 (status_t)OK); 718 } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) { 719 CHECK_EQ(setMinBufferSize(kPortIndexInput, 8192), // XXX 720 (status_t)OK); 721 } 722} 723 724status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) { 725 OMX_PARAM_PORTDEFINITIONTYPE def; 726 InitOMXParams(&def); 727 def.nPortIndex = portIndex; 728 729 status_t err = mOMX->getParameter( 730 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 731 732 if (err != OK) { 733 return err; 734 } 735 736 if (def.nBufferSize >= size) { 737 return OK; 738 } 739 740 def.nBufferSize = size; 741 742 err = mOMX->setParameter( 743 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 744 745 if (err != OK) { 746 return err; 747 } 748 749 err = mOMX->getParameter( 750 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 751 752 if (err != OK) { 753 return err; 754 } 755 756 CHECK(def.nBufferSize >= size); 757 758 return OK; 759} 760 761status_t ACodec::setupAACDecoder(int32_t numChannels, int32_t sampleRate) { 762 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 763 InitOMXParams(&profile); 764 profile.nPortIndex = kPortIndexInput; 765 766 status_t err = mOMX->getParameter( 767 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 768 769 if (err != OK) { 770 return err; 771 } 772 773 profile.nChannels = numChannels; 774 profile.nSampleRate = sampleRate; 775 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; 776 777 err = mOMX->setParameter( 778 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 779 780 return err; 781} 782 783status_t ACodec::setVideoPortFormatType( 784 OMX_U32 portIndex, 785 OMX_VIDEO_CODINGTYPE compressionFormat, 786 OMX_COLOR_FORMATTYPE colorFormat) { 787 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 788 InitOMXParams(&format); 789 format.nPortIndex = portIndex; 790 format.nIndex = 0; 791 bool found = false; 792 793 OMX_U32 index = 0; 794 for (;;) { 795 format.nIndex = index; 796 status_t err = mOMX->getParameter( 797 mNode, OMX_IndexParamVideoPortFormat, 798 &format, sizeof(format)); 799 800 if (err != OK) { 801 return err; 802 } 803 804 // The following assertion is violated by TI's video decoder. 805 // CHECK_EQ(format.nIndex, index); 806 807 if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) { 808 if (portIndex == kPortIndexInput 809 && colorFormat == format.eColorFormat) { 810 // eCompressionFormat does not seem right. 811 found = true; 812 break; 813 } 814 if (portIndex == kPortIndexOutput 815 && compressionFormat == format.eCompressionFormat) { 816 // eColorFormat does not seem right. 817 found = true; 818 break; 819 } 820 } 821 822 if (format.eCompressionFormat == compressionFormat 823 && format.eColorFormat == colorFormat) { 824 found = true; 825 break; 826 } 827 828 ++index; 829 } 830 831 if (!found) { 832 return UNKNOWN_ERROR; 833 } 834 835 status_t err = mOMX->setParameter( 836 mNode, OMX_IndexParamVideoPortFormat, 837 &format, sizeof(format)); 838 839 return err; 840} 841 842status_t ACodec::setSupportedOutputFormat() { 843 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 844 InitOMXParams(&format); 845 format.nPortIndex = kPortIndexOutput; 846 format.nIndex = 0; 847 848 status_t err = mOMX->getParameter( 849 mNode, OMX_IndexParamVideoPortFormat, 850 &format, sizeof(format)); 851 CHECK_EQ(err, (status_t)OK); 852 CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused); 853 854 static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; 855 856 CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar 857 || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar 858 || format.eColorFormat == OMX_COLOR_FormatCbYCrY 859 || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar); 860 861 return mOMX->setParameter( 862 mNode, OMX_IndexParamVideoPortFormat, 863 &format, sizeof(format)); 864} 865 866status_t ACodec::setupVideoDecoder( 867 const char *mime, int32_t width, int32_t height) { 868 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 869 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 870 compressionFormat = OMX_VIDEO_CodingAVC; 871 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 872 compressionFormat = OMX_VIDEO_CodingMPEG4; 873 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 874 compressionFormat = OMX_VIDEO_CodingH263; 875 } else { 876 TRESPASS(); 877 } 878 879 status_t err = setVideoPortFormatType( 880 kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 881 882 if (err != OK) { 883 return err; 884 } 885 886 err = setSupportedOutputFormat(); 887 888 if (err != OK) { 889 return err; 890 } 891 892 err = setVideoFormatOnPort( 893 kPortIndexInput, width, height, compressionFormat); 894 895 if (err != OK) { 896 return err; 897 } 898 899 err = setVideoFormatOnPort( 900 kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused); 901 902 if (err != OK) { 903 return err; 904 } 905 906 return OK; 907} 908 909status_t ACodec::setVideoFormatOnPort( 910 OMX_U32 portIndex, 911 int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) { 912 OMX_PARAM_PORTDEFINITIONTYPE def; 913 InitOMXParams(&def); 914 def.nPortIndex = portIndex; 915 916 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 917 918 status_t err = mOMX->getParameter( 919 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 920 921 CHECK_EQ(err, (status_t)OK); 922 923 if (portIndex == kPortIndexInput) { 924 // XXX Need a (much) better heuristic to compute input buffer sizes. 925 const size_t X = 64 * 1024; 926 if (def.nBufferSize < X) { 927 def.nBufferSize = X; 928 } 929 } 930 931 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 932 933 video_def->nFrameWidth = width; 934 video_def->nFrameHeight = height; 935 936 if (portIndex == kPortIndexInput) { 937 video_def->eCompressionFormat = compressionFormat; 938 video_def->eColorFormat = OMX_COLOR_FormatUnused; 939 } 940 941 err = mOMX->setParameter( 942 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 943 944 return err; 945} 946 947status_t ACodec::initNativeWindow() { 948 if (mNativeWindow != NULL) { 949 return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE); 950 } 951 952 mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE); 953 return OK; 954} 955 956bool ACodec::allYourBuffersAreBelongToUs( 957 OMX_U32 portIndex) { 958 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 959 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 960 961 if (info->mStatus != BufferInfo::OWNED_BY_US 962 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 963 LOGV("[%s] Buffer %p on port %ld still has status %d", 964 mComponentName.c_str(), 965 info->mBufferID, portIndex, info->mStatus); 966 return false; 967 } 968 } 969 970 return true; 971} 972 973bool ACodec::allYourBuffersAreBelongToUs() { 974 return allYourBuffersAreBelongToUs(kPortIndexInput) 975 && allYourBuffersAreBelongToUs(kPortIndexOutput); 976} 977 978void ACodec::deferMessage(const sp<AMessage> &msg) { 979 bool wasEmptyBefore = mDeferredQueue.empty(); 980 mDeferredQueue.push_back(msg); 981} 982 983void ACodec::processDeferredMessages() { 984 List<sp<AMessage> > queue = mDeferredQueue; 985 mDeferredQueue.clear(); 986 987 List<sp<AMessage> >::iterator it = queue.begin(); 988 while (it != queue.end()) { 989 onMessageReceived(*it++); 990 } 991} 992 993void ACodec::sendFormatChange() { 994 sp<AMessage> notify = mNotify->dup(); 995 notify->setInt32("what", kWhatOutputFormatChanged); 996 997 OMX_PARAM_PORTDEFINITIONTYPE def; 998 InitOMXParams(&def); 999 def.nPortIndex = kPortIndexOutput; 1000 1001 CHECK_EQ(mOMX->getParameter( 1002 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)), 1003 (status_t)OK); 1004 1005 CHECK_EQ((int)def.eDir, (int)OMX_DirOutput); 1006 1007 switch (def.eDomain) { 1008 case OMX_PortDomainVideo: 1009 { 1010 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 1011 1012 notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW); 1013 notify->setInt32("width", videoDef->nFrameWidth); 1014 notify->setInt32("height", videoDef->nFrameHeight); 1015 1016 OMX_CONFIG_RECTTYPE rect; 1017 InitOMXParams(&rect); 1018 rect.nPortIndex = kPortIndexOutput; 1019 1020 if (mOMX->getConfig( 1021 mNode, OMX_IndexConfigCommonOutputCrop, 1022 &rect, sizeof(rect)) != OK) { 1023 rect.nLeft = 0; 1024 rect.nTop = 0; 1025 rect.nWidth = videoDef->nFrameWidth; 1026 rect.nHeight = videoDef->nFrameHeight; 1027 } 1028 1029 CHECK_GE(rect.nLeft, 0); 1030 CHECK_GE(rect.nTop, 0); 1031 CHECK_GE(rect.nWidth, 0u); 1032 CHECK_GE(rect.nHeight, 0u); 1033 CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth); 1034 CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight); 1035 1036 notify->setRect( 1037 "crop", 1038 rect.nLeft, 1039 rect.nTop, 1040 rect.nLeft + rect.nWidth - 1, 1041 rect.nTop + rect.nHeight - 1); 1042 1043 if (mNativeWindow != NULL) { 1044 android_native_rect_t crop; 1045 crop.left = rect.nLeft; 1046 crop.top = rect.nTop; 1047 crop.right = rect.nLeft + rect.nWidth - 1; 1048 crop.bottom = rect.nTop + rect.nHeight - 1; 1049 1050 CHECK_EQ(0, native_window_set_crop( 1051 mNativeWindow.get(), &crop)); 1052 } 1053 break; 1054 } 1055 1056 case OMX_PortDomainAudio: 1057 { 1058 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 1059 CHECK_EQ((int)audioDef->eEncoding, (int)OMX_AUDIO_CodingPCM); 1060 1061 OMX_AUDIO_PARAM_PCMMODETYPE params; 1062 InitOMXParams(¶ms); 1063 params.nPortIndex = kPortIndexOutput; 1064 1065 CHECK_EQ(mOMX->getParameter( 1066 mNode, OMX_IndexParamAudioPcm, 1067 ¶ms, sizeof(params)), 1068 (status_t)OK); 1069 1070 CHECK(params.nChannels == 1 || params.bInterleaved); 1071 CHECK_EQ(params.nBitPerSample, 16u); 1072 CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned); 1073 CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear); 1074 1075 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW); 1076 notify->setInt32("channel-count", params.nChannels); 1077 notify->setInt32("sample-rate", params.nSamplingRate); 1078 break; 1079 } 1080 1081 default: 1082 TRESPASS(); 1083 } 1084 1085 notify->post(); 1086 1087 mSentFormat = true; 1088} 1089 1090//////////////////////////////////////////////////////////////////////////////// 1091 1092ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState) 1093 : AState(parentState), 1094 mCodec(codec) { 1095} 1096 1097ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) { 1098 return KEEP_BUFFERS; 1099} 1100 1101bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { 1102 switch (msg->what()) { 1103 case kWhatInputBufferFilled: 1104 { 1105 onInputBufferFilled(msg); 1106 break; 1107 } 1108 1109 case kWhatOutputBufferDrained: 1110 { 1111 onOutputBufferDrained(msg); 1112 break; 1113 } 1114 1115 case ACodec::kWhatOMXMessage: 1116 { 1117 return onOMXMessage(msg); 1118 } 1119 1120 default: 1121 return false; 1122 } 1123 1124 return true; 1125} 1126 1127bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { 1128 int32_t type; 1129 CHECK(msg->findInt32("type", &type)); 1130 1131 IOMX::node_id nodeID; 1132 CHECK(msg->findPointer("node", &nodeID)); 1133 CHECK_EQ(nodeID, mCodec->mNode); 1134 1135 switch (type) { 1136 case omx_message::EVENT: 1137 { 1138 int32_t event, data1, data2; 1139 CHECK(msg->findInt32("event", &event)); 1140 CHECK(msg->findInt32("data1", &data1)); 1141 CHECK(msg->findInt32("data2", &data2)); 1142 1143 return onOMXEvent( 1144 static_cast<OMX_EVENTTYPE>(event), 1145 static_cast<OMX_U32>(data1), 1146 static_cast<OMX_U32>(data2)); 1147 } 1148 1149 case omx_message::EMPTY_BUFFER_DONE: 1150 { 1151 IOMX::buffer_id bufferID; 1152 CHECK(msg->findPointer("buffer", &bufferID)); 1153 1154 return onOMXEmptyBufferDone(bufferID); 1155 } 1156 1157 case omx_message::FILL_BUFFER_DONE: 1158 { 1159 IOMX::buffer_id bufferID; 1160 CHECK(msg->findPointer("buffer", &bufferID)); 1161 1162 int32_t rangeOffset, rangeLength, flags; 1163 int64_t timeUs; 1164 void *platformPrivate; 1165 void *dataPtr; 1166 1167 CHECK(msg->findInt32("range_offset", &rangeOffset)); 1168 CHECK(msg->findInt32("range_length", &rangeLength)); 1169 CHECK(msg->findInt32("flags", &flags)); 1170 CHECK(msg->findInt64("timestamp", &timeUs)); 1171 CHECK(msg->findPointer("platform_private", &platformPrivate)); 1172 CHECK(msg->findPointer("data_ptr", &dataPtr)); 1173 1174 return onOMXFillBufferDone( 1175 bufferID, 1176 (size_t)rangeOffset, (size_t)rangeLength, 1177 (OMX_U32)flags, 1178 timeUs, 1179 platformPrivate, 1180 dataPtr); 1181 } 1182 1183 default: 1184 TRESPASS(); 1185 break; 1186 } 1187} 1188 1189bool ACodec::BaseState::onOMXEvent( 1190 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1191 if (event != OMX_EventError) { 1192 LOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)", 1193 mCodec->mComponentName.c_str(), event, data1, data2); 1194 1195 return false; 1196 } 1197 1198 LOGE("[%s] ERROR(0x%08lx, 0x%08lx)", 1199 mCodec->mComponentName.c_str(), data1, data2); 1200 1201 mCodec->changeState(mCodec->mErrorState); 1202 1203 return true; 1204} 1205 1206bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) { 1207 LOGV("[%s] onOMXEmptyBufferDone %p", 1208 mCodec->mComponentName.c_str(), bufferID); 1209 1210 BufferInfo *info = 1211 mCodec->findBufferByID(kPortIndexInput, bufferID); 1212 1213 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT); 1214 info->mStatus = BufferInfo::OWNED_BY_US; 1215 1216 PortMode mode = getPortMode(kPortIndexInput); 1217 1218 switch (mode) { 1219 case KEEP_BUFFERS: 1220 break; 1221 1222 case RESUBMIT_BUFFERS: 1223 postFillThisBuffer(info); 1224 break; 1225 1226 default: 1227 { 1228 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 1229 TRESPASS(); // Not currently used 1230 break; 1231 } 1232 } 1233 1234 return true; 1235} 1236 1237void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) { 1238 if (mCodec->mPortEOS[kPortIndexInput]) { 1239 return; 1240 } 1241 1242 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 1243 1244 sp<AMessage> notify = mCodec->mNotify->dup(); 1245 notify->setInt32("what", ACodec::kWhatFillThisBuffer); 1246 notify->setPointer("buffer-id", info->mBufferID); 1247 1248 info->mData->meta()->clear(); 1249 notify->setObject("buffer", info->mData); 1250 1251 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id()); 1252 reply->setPointer("buffer-id", info->mBufferID); 1253 1254 notify->setMessage("reply", reply); 1255 1256 notify->post(); 1257 1258 info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 1259} 1260 1261void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { 1262 IOMX::buffer_id bufferID; 1263 CHECK(msg->findPointer("buffer-id", &bufferID)); 1264 1265 sp<RefBase> obj; 1266 int32_t err = OK; 1267 if (!msg->findObject("buffer", &obj)) { 1268 CHECK(msg->findInt32("err", &err)); 1269 1270 LOGV("[%s] saw error %d instead of an input buffer", 1271 mCodec->mComponentName.c_str(), err); 1272 1273 obj.clear(); 1274 } 1275 1276 sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get()); 1277 1278 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 1279 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM); 1280 1281 info->mStatus = BufferInfo::OWNED_BY_US; 1282 1283 PortMode mode = getPortMode(kPortIndexInput); 1284 1285 switch (mode) { 1286 case KEEP_BUFFERS: 1287 { 1288 if (buffer == NULL) { 1289 mCodec->mPortEOS[kPortIndexInput] = true; 1290 } 1291 break; 1292 } 1293 1294 case RESUBMIT_BUFFERS: 1295 { 1296 if (buffer != NULL) { 1297 CHECK(!mCodec->mPortEOS[kPortIndexInput]); 1298 1299 int64_t timeUs; 1300 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 1301 1302 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 1303 1304 int32_t isCSD; 1305 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) { 1306 flags |= OMX_BUFFERFLAG_CODECCONFIG; 1307 } 1308 1309 if (buffer != info->mData) { 1310 if (0 && !(flags & OMX_BUFFERFLAG_CODECCONFIG)) { 1311 LOGV("[%s] Needs to copy input data.", 1312 mCodec->mComponentName.c_str()); 1313 } 1314 1315 CHECK_LE(buffer->size(), info->mData->capacity()); 1316 memcpy(info->mData->data(), buffer->data(), buffer->size()); 1317 } 1318 1319 LOGV("[%s] calling emptyBuffer %p", 1320 mCodec->mComponentName.c_str(), bufferID); 1321 1322 CHECK_EQ(mCodec->mOMX->emptyBuffer( 1323 mCodec->mNode, 1324 bufferID, 1325 0, 1326 buffer->size(), 1327 flags, 1328 timeUs), 1329 (status_t)OK); 1330 1331 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 1332 1333 getMoreInputDataIfPossible(); 1334 } else if (!mCodec->mPortEOS[kPortIndexInput]) { 1335 LOGV("[%s] Signalling EOS on the input port", 1336 mCodec->mComponentName.c_str()); 1337 1338 LOGV("[%s] calling emptyBuffer %p", 1339 mCodec->mComponentName.c_str(), bufferID); 1340 1341 CHECK_EQ(mCodec->mOMX->emptyBuffer( 1342 mCodec->mNode, 1343 bufferID, 1344 0, 1345 0, 1346 OMX_BUFFERFLAG_EOS, 1347 0), 1348 (status_t)OK); 1349 1350 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 1351 1352 mCodec->mPortEOS[kPortIndexInput] = true; 1353 } 1354 break; 1355 1356 default: 1357 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 1358 break; 1359 } 1360 } 1361} 1362 1363void ACodec::BaseState::getMoreInputDataIfPossible() { 1364 if (mCodec->mPortEOS[kPortIndexInput]) { 1365 return; 1366 } 1367 1368 BufferInfo *eligible = NULL; 1369 1370 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 1371 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 1372 1373#if 0 1374 if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 1375 // There's already a "read" pending. 1376 return; 1377 } 1378#endif 1379 1380 if (info->mStatus == BufferInfo::OWNED_BY_US) { 1381 eligible = info; 1382 } 1383 } 1384 1385 if (eligible == NULL) { 1386 return; 1387 } 1388 1389 postFillThisBuffer(eligible); 1390} 1391 1392bool ACodec::BaseState::onOMXFillBufferDone( 1393 IOMX::buffer_id bufferID, 1394 size_t rangeOffset, size_t rangeLength, 1395 OMX_U32 flags, 1396 int64_t timeUs, 1397 void *platformPrivate, 1398 void *dataPtr) { 1399 LOGV("[%s] onOMXFillBufferDone %p", 1400 mCodec->mComponentName.c_str(), bufferID); 1401 1402 ssize_t index; 1403 BufferInfo *info = 1404 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 1405 1406 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT); 1407 1408 info->mStatus = BufferInfo::OWNED_BY_US; 1409 1410 PortMode mode = getPortMode(kPortIndexOutput); 1411 1412 switch (mode) { 1413 case KEEP_BUFFERS: 1414 break; 1415 1416 case RESUBMIT_BUFFERS: 1417 { 1418 if (rangeLength == 0) { 1419 if (!(flags & OMX_BUFFERFLAG_EOS)) { 1420 LOGV("[%s] calling fillBuffer %p", 1421 mCodec->mComponentName.c_str(), info->mBufferID); 1422 1423 CHECK_EQ(mCodec->mOMX->fillBuffer( 1424 mCodec->mNode, info->mBufferID), 1425 (status_t)OK); 1426 1427 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 1428 } 1429 } else { 1430 if (!mCodec->mSentFormat) { 1431 mCodec->sendFormatChange(); 1432 } 1433 1434 if (mCodec->mNativeWindow == NULL) { 1435 info->mData->setRange(rangeOffset, rangeLength); 1436 } 1437 1438 info->mData->meta()->setInt64("timeUs", timeUs); 1439 1440 sp<AMessage> notify = mCodec->mNotify->dup(); 1441 notify->setInt32("what", ACodec::kWhatDrainThisBuffer); 1442 notify->setPointer("buffer-id", info->mBufferID); 1443 notify->setObject("buffer", info->mData); 1444 1445 sp<AMessage> reply = 1446 new AMessage(kWhatOutputBufferDrained, mCodec->id()); 1447 1448 reply->setPointer("buffer-id", info->mBufferID); 1449 1450 notify->setMessage("reply", reply); 1451 1452 notify->post(); 1453 1454 info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 1455 } 1456 1457 if (flags & OMX_BUFFERFLAG_EOS) { 1458 sp<AMessage> notify = mCodec->mNotify->dup(); 1459 notify->setInt32("what", ACodec::kWhatEOS); 1460 notify->post(); 1461 1462 mCodec->mPortEOS[kPortIndexOutput] = true; 1463 } 1464 break; 1465 } 1466 1467 default: 1468 { 1469 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 1470 1471 CHECK_EQ((status_t)OK, 1472 mCodec->freeBuffer(kPortIndexOutput, index)); 1473 break; 1474 } 1475 } 1476 1477 return true; 1478} 1479 1480void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 1481 IOMX::buffer_id bufferID; 1482 CHECK(msg->findPointer("buffer-id", &bufferID)); 1483 1484 ssize_t index; 1485 BufferInfo *info = 1486 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 1487 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM); 1488 1489 int32_t render; 1490 if (mCodec->mNativeWindow != NULL 1491 && msg->findInt32("render", &render) && render != 0) { 1492 // The client wants this buffer to be rendered. 1493 1494 CHECK_EQ(mCodec->mNativeWindow->queueBuffer( 1495 mCodec->mNativeWindow.get(), 1496 info->mGraphicBuffer.get()), 1497 0); 1498 1499 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 1500 } else { 1501 info->mStatus = BufferInfo::OWNED_BY_US; 1502 } 1503 1504 PortMode mode = getPortMode(kPortIndexOutput); 1505 1506 switch (mode) { 1507 case KEEP_BUFFERS: 1508 { 1509 // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 1510 1511 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 1512 // We cannot resubmit the buffer we just rendered, dequeue 1513 // the spare instead. 1514 1515 info = mCodec->dequeueBufferFromNativeWindow(); 1516 } 1517 break; 1518 } 1519 1520 case RESUBMIT_BUFFERS: 1521 { 1522 if (!mCodec->mPortEOS[kPortIndexOutput]) { 1523 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 1524 // We cannot resubmit the buffer we just rendered, dequeue 1525 // the spare instead. 1526 1527 info = mCodec->dequeueBufferFromNativeWindow(); 1528 } 1529 1530 LOGV("[%s] calling fillBuffer %p", 1531 mCodec->mComponentName.c_str(), info->mBufferID); 1532 1533 CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), 1534 (status_t)OK); 1535 1536 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 1537 } 1538 break; 1539 } 1540 1541 default: 1542 { 1543 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 1544 1545 CHECK_EQ((status_t)OK, 1546 mCodec->freeBuffer(kPortIndexOutput, index)); 1547 break; 1548 } 1549 } 1550} 1551 1552//////////////////////////////////////////////////////////////////////////////// 1553 1554ACodec::UninitializedState::UninitializedState(ACodec *codec) 1555 : BaseState(codec) { 1556} 1557 1558bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 1559 bool handled = false; 1560 1561 switch (msg->what()) { 1562 case ACodec::kWhatSetup: 1563 { 1564 onSetup(msg); 1565 1566 handled = true; 1567 break; 1568 } 1569 1570 case ACodec::kWhatShutdown: 1571 { 1572 sp<AMessage> notify = mCodec->mNotify->dup(); 1573 notify->setInt32("what", ACodec::kWhatShutdownCompleted); 1574 notify->post(); 1575 1576 handled = true; 1577 } 1578 1579 case ACodec::kWhatFlush: 1580 { 1581 sp<AMessage> notify = mCodec->mNotify->dup(); 1582 notify->setInt32("what", ACodec::kWhatFlushCompleted); 1583 notify->post(); 1584 1585 handled = true; 1586 } 1587 1588 default: 1589 return BaseState::onMessageReceived(msg); 1590 } 1591 1592 return handled; 1593} 1594 1595void ACodec::UninitializedState::onSetup( 1596 const sp<AMessage> &msg) { 1597 OMXClient client; 1598 CHECK_EQ(client.connect(), (status_t)OK); 1599 1600 sp<IOMX> omx = client.interface(); 1601 1602 AString mime; 1603 CHECK(msg->findString("mime", &mime)); 1604 1605 AString componentName; 1606 1607 if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 1608 componentName = "OMX.Nvidia.h264.decode"; 1609 } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 1610 componentName = "OMX.Nvidia.aac.decoder"; 1611 } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_MPEG)) { 1612 componentName = "OMX.Nvidia.mp3.decoder"; 1613 } else { 1614 TRESPASS(); 1615 } 1616 1617 sp<CodecObserver> observer = new CodecObserver; 1618 1619 IOMX::node_id node; 1620 CHECK_EQ(omx->allocateNode(componentName.c_str(), observer, &node), 1621 (status_t)OK); 1622 1623 sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id()); 1624 observer->setNotificationMessage(notify); 1625 1626 mCodec->mComponentName = componentName; 1627 mCodec->mOMX = omx; 1628 mCodec->mNode = node; 1629 1630 mCodec->mPortEOS[kPortIndexInput] = 1631 mCodec->mPortEOS[kPortIndexOutput] = false; 1632 1633 mCodec->configureCodec(mime.c_str(), msg); 1634 1635 sp<RefBase> obj; 1636 if (msg->findObject("surface", &obj)) { 1637 mCodec->mNativeWindow = static_cast<Surface *>(obj.get()); 1638 } 1639 1640 CHECK_EQ((status_t)OK, mCodec->initNativeWindow()); 1641 1642 CHECK_EQ(omx->sendCommand(node, OMX_CommandStateSet, OMX_StateIdle), 1643 (status_t)OK); 1644 1645 mCodec->changeState(mCodec->mLoadedToIdleState); 1646} 1647 1648//////////////////////////////////////////////////////////////////////////////// 1649 1650ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 1651 : BaseState(codec) { 1652} 1653 1654void ACodec::LoadedToIdleState::stateEntered() { 1655 LOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 1656 1657 CHECK_EQ(allocateBuffers(), (status_t)OK); 1658} 1659 1660status_t ACodec::LoadedToIdleState::allocateBuffers() { 1661 status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 1662 1663 if (err != OK) { 1664 return err; 1665 } 1666 1667 return mCodec->allocateBuffersOnPort(kPortIndexOutput); 1668} 1669 1670bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 1671 switch (msg->what()) { 1672 case kWhatShutdown: 1673 { 1674 mCodec->deferMessage(msg); 1675 return true; 1676 } 1677 1678 default: 1679 return BaseState::onMessageReceived(msg); 1680 } 1681} 1682 1683bool ACodec::LoadedToIdleState::onOMXEvent( 1684 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1685 switch (event) { 1686 case OMX_EventCmdComplete: 1687 { 1688 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 1689 CHECK_EQ(data2, (OMX_U32)OMX_StateIdle); 1690 1691 CHECK_EQ(mCodec->mOMX->sendCommand( 1692 mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting), 1693 (status_t)OK); 1694 1695 mCodec->changeState(mCodec->mIdleToExecutingState); 1696 1697 return true; 1698 } 1699 1700 default: 1701 return BaseState::onOMXEvent(event, data1, data2); 1702 } 1703} 1704 1705//////////////////////////////////////////////////////////////////////////////// 1706 1707ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 1708 : BaseState(codec) { 1709} 1710 1711void ACodec::IdleToExecutingState::stateEntered() { 1712 LOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 1713} 1714 1715bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 1716 switch (msg->what()) { 1717 case kWhatShutdown: 1718 { 1719 mCodec->deferMessage(msg); 1720 return true; 1721 } 1722 1723 default: 1724 return BaseState::onMessageReceived(msg); 1725 } 1726} 1727 1728bool ACodec::IdleToExecutingState::onOMXEvent( 1729 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1730 switch (event) { 1731 case OMX_EventCmdComplete: 1732 { 1733 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 1734 CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting); 1735 1736 mCodec->mExecutingState->resume(); 1737 mCodec->changeState(mCodec->mExecutingState); 1738 1739 return true; 1740 } 1741 1742 default: 1743 return BaseState::onOMXEvent(event, data1, data2); 1744 } 1745} 1746 1747//////////////////////////////////////////////////////////////////////////////// 1748 1749ACodec::ExecutingState::ExecutingState(ACodec *codec) 1750 : BaseState(codec), 1751 mActive(false) { 1752} 1753 1754ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 1755 OMX_U32 portIndex) { 1756 return RESUBMIT_BUFFERS; 1757} 1758 1759void ACodec::ExecutingState::submitOutputBuffers() { 1760 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 1761 BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 1762 1763 if (mCodec->mNativeWindow != NULL) { 1764 CHECK(info->mStatus == BufferInfo::OWNED_BY_US 1765 || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW); 1766 1767 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 1768 continue; 1769 } 1770 1771 status_t err = mCodec->mNativeWindow->lockBuffer( 1772 mCodec->mNativeWindow.get(), 1773 info->mGraphicBuffer.get()); 1774 CHECK_EQ(err, (status_t)OK); 1775 } else { 1776 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 1777 } 1778 1779 LOGV("[%s] calling fillBuffer %p", 1780 mCodec->mComponentName.c_str(), info->mBufferID); 1781 1782 CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), 1783 (status_t)OK); 1784 1785 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 1786 } 1787} 1788 1789void ACodec::ExecutingState::resume() { 1790 if (mActive) { 1791 LOGV("[%s] We're already active, no need to resume.", 1792 mCodec->mComponentName.c_str()); 1793 1794 return; 1795 } 1796 1797 submitOutputBuffers(); 1798 1799 // Post the first input buffer. 1800 CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u); 1801 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0); 1802 1803 postFillThisBuffer(info); 1804 1805 mActive = true; 1806} 1807 1808void ACodec::ExecutingState::stateEntered() { 1809 LOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 1810 1811 mCodec->processDeferredMessages(); 1812} 1813 1814bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 1815 bool handled = false; 1816 1817 switch (msg->what()) { 1818 case kWhatShutdown: 1819 { 1820 mActive = false; 1821 1822 CHECK_EQ(mCodec->mOMX->sendCommand( 1823 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle), 1824 (status_t)OK); 1825 1826 mCodec->changeState(mCodec->mExecutingToIdleState); 1827 1828 handled = true; 1829 break; 1830 } 1831 1832 case kWhatFlush: 1833 { 1834 mActive = false; 1835 1836 CHECK_EQ(mCodec->mOMX->sendCommand( 1837 mCodec->mNode, OMX_CommandFlush, OMX_ALL), 1838 (status_t)OK); 1839 1840 mCodec->changeState(mCodec->mFlushingState); 1841 1842 handled = true; 1843 break; 1844 } 1845 1846 case kWhatResume: 1847 { 1848 resume(); 1849 1850 handled = true; 1851 break; 1852 } 1853 1854 default: 1855 handled = BaseState::onMessageReceived(msg); 1856 break; 1857 } 1858 1859 return handled; 1860} 1861 1862bool ACodec::ExecutingState::onOMXEvent( 1863 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1864 switch (event) { 1865 case OMX_EventPortSettingsChanged: 1866 { 1867 CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 1868 1869 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 1870 CHECK_EQ(mCodec->mOMX->sendCommand( 1871 mCodec->mNode, 1872 OMX_CommandPortDisable, kPortIndexOutput), 1873 (status_t)OK); 1874 1875 mCodec->freeOutputBuffersNotOwnedByComponent(); 1876 1877 mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 1878 } else if (data2 == OMX_IndexConfigCommonOutputCrop) { 1879 mCodec->mSentFormat = false; 1880 } else { 1881 LOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx", 1882 mCodec->mComponentName.c_str(), data2); 1883 } 1884 1885 return true; 1886 } 1887 1888 case OMX_EventBufferFlag: 1889 { 1890 return true; 1891 } 1892 1893 default: 1894 return BaseState::onOMXEvent(event, data1, data2); 1895 } 1896} 1897 1898//////////////////////////////////////////////////////////////////////////////// 1899 1900ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 1901 ACodec *codec) 1902 : BaseState(codec) { 1903} 1904 1905ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 1906 OMX_U32 portIndex) { 1907 if (portIndex == kPortIndexOutput) { 1908 return FREE_BUFFERS; 1909 } 1910 1911 CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 1912 1913 return RESUBMIT_BUFFERS; 1914} 1915 1916bool ACodec::OutputPortSettingsChangedState::onMessageReceived( 1917 const sp<AMessage> &msg) { 1918 bool handled = false; 1919 1920 switch (msg->what()) { 1921 case kWhatFlush: 1922 case kWhatShutdown: 1923 case kWhatResume: 1924 { 1925 if (msg->what() == kWhatResume) { 1926 LOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 1927 } 1928 1929 mCodec->deferMessage(msg); 1930 handled = true; 1931 break; 1932 } 1933 1934 default: 1935 handled = BaseState::onMessageReceived(msg); 1936 break; 1937 } 1938 1939 return handled; 1940} 1941 1942void ACodec::OutputPortSettingsChangedState::stateEntered() { 1943 LOGV("[%s] Now handling output port settings change", 1944 mCodec->mComponentName.c_str()); 1945} 1946 1947bool ACodec::OutputPortSettingsChangedState::onOMXEvent( 1948 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 1949 switch (event) { 1950 case OMX_EventCmdComplete: 1951 { 1952 if (data1 == (OMX_U32)OMX_CommandPortDisable) { 1953 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput); 1954 1955 LOGV("[%s] Output port now disabled.", 1956 mCodec->mComponentName.c_str()); 1957 1958 CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty()); 1959 mCodec->mDealer[kPortIndexOutput].clear(); 1960 1961 CHECK_EQ(mCodec->mOMX->sendCommand( 1962 mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput), 1963 (status_t)OK); 1964 1965 CHECK_EQ(mCodec->allocateBuffersOnPort(kPortIndexOutput), 1966 (status_t)OK); 1967 1968 return true; 1969 } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 1970 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput); 1971 1972 mCodec->mSentFormat = false; 1973 1974 LOGV("[%s] Output port now reenabled.", 1975 mCodec->mComponentName.c_str()); 1976 1977 if (mCodec->mExecutingState->active()) { 1978 mCodec->mExecutingState->submitOutputBuffers(); 1979 } 1980 1981 mCodec->changeState(mCodec->mExecutingState); 1982 1983 return true; 1984 } 1985 1986 return false; 1987 } 1988 1989 default: 1990 return false; 1991 } 1992} 1993 1994//////////////////////////////////////////////////////////////////////////////// 1995 1996ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 1997 : BaseState(codec) { 1998} 1999 2000bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 2001 bool handled = false; 2002 2003 switch (msg->what()) { 2004 case kWhatFlush: 2005 { 2006 // Don't send me a flush request if you previously wanted me 2007 // to shutdown. 2008 TRESPASS(); 2009 break; 2010 } 2011 2012 case kWhatShutdown: 2013 { 2014 // We're already doing that... 2015 2016 handled = true; 2017 break; 2018 } 2019 2020 default: 2021 handled = BaseState::onMessageReceived(msg); 2022 break; 2023 } 2024 2025 return handled; 2026} 2027 2028void ACodec::ExecutingToIdleState::stateEntered() { 2029 LOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 2030 2031 mCodec->mSentFormat = false; 2032} 2033 2034bool ACodec::ExecutingToIdleState::onOMXEvent( 2035 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 2036 switch (event) { 2037 case OMX_EventCmdComplete: 2038 { 2039 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 2040 CHECK_EQ(data2, (OMX_U32)OMX_StateIdle); 2041 2042 changeStateIfWeOwnAllBuffers(); 2043 2044 return true; 2045 } 2046 2047 case OMX_EventPortSettingsChanged: 2048 case OMX_EventBufferFlag: 2049 { 2050 // We're shutting down and don't care about this anymore. 2051 return true; 2052 } 2053 2054 default: 2055 return BaseState::onOMXEvent(event, data1, data2); 2056 } 2057} 2058void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 2059 if (mCodec->allYourBuffersAreBelongToUs()) { 2060 CHECK_EQ(mCodec->mOMX->sendCommand( 2061 mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded), 2062 (status_t)OK); 2063 2064 CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK); 2065 CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK); 2066 2067 mCodec->changeState(mCodec->mIdleToLoadedState); 2068 } 2069} 2070 2071void ACodec::ExecutingToIdleState::onInputBufferFilled( 2072 const sp<AMessage> &msg) { 2073 BaseState::onInputBufferFilled(msg); 2074 2075 changeStateIfWeOwnAllBuffers(); 2076} 2077 2078void ACodec::ExecutingToIdleState::onOutputBufferDrained( 2079 const sp<AMessage> &msg) { 2080 BaseState::onOutputBufferDrained(msg); 2081 2082 changeStateIfWeOwnAllBuffers(); 2083} 2084 2085//////////////////////////////////////////////////////////////////////////////// 2086 2087ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 2088 : BaseState(codec) { 2089} 2090 2091bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 2092 bool handled = false; 2093 2094 switch (msg->what()) { 2095 case kWhatShutdown: 2096 { 2097 // We're already doing that... 2098 2099 handled = true; 2100 break; 2101 } 2102 2103 case kWhatFlush: 2104 { 2105 // Don't send me a flush request if you previously wanted me 2106 // to shutdown. 2107 TRESPASS(); 2108 break; 2109 } 2110 2111 default: 2112 handled = BaseState::onMessageReceived(msg); 2113 break; 2114 } 2115 2116 return handled; 2117} 2118 2119void ACodec::IdleToLoadedState::stateEntered() { 2120 LOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 2121} 2122 2123bool ACodec::IdleToLoadedState::onOMXEvent( 2124 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 2125 switch (event) { 2126 case OMX_EventCmdComplete: 2127 { 2128 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 2129 CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded); 2130 2131 LOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 2132 2133 CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK); 2134 2135 mCodec->mNativeWindow.clear(); 2136 mCodec->mNode = NULL; 2137 mCodec->mOMX.clear(); 2138 mCodec->mComponentName.clear(); 2139 2140 mCodec->changeState(mCodec->mUninitializedState); 2141 2142 sp<AMessage> notify = mCodec->mNotify->dup(); 2143 notify->setInt32("what", ACodec::kWhatShutdownCompleted); 2144 notify->post(); 2145 2146 return true; 2147 } 2148 2149 default: 2150 return BaseState::onOMXEvent(event, data1, data2); 2151 } 2152} 2153 2154//////////////////////////////////////////////////////////////////////////////// 2155 2156ACodec::ErrorState::ErrorState(ACodec *codec) 2157 : BaseState(codec) { 2158} 2159 2160bool ACodec::ErrorState::onMessageReceived(const sp<AMessage> &msg) { 2161 return BaseState::onMessageReceived(msg); 2162} 2163 2164void ACodec::ErrorState::stateEntered() { 2165 LOGV("[%s] Now in ErrorState", mCodec->mComponentName.c_str()); 2166} 2167 2168bool ACodec::ErrorState::onOMXEvent( 2169 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 2170 LOGV("EVENT(%d, 0x%08lx, 0x%08lx)", event, data1, data2); 2171 return true; 2172} 2173 2174//////////////////////////////////////////////////////////////////////////////// 2175 2176ACodec::FlushingState::FlushingState(ACodec *codec) 2177 : BaseState(codec) { 2178} 2179 2180void ACodec::FlushingState::stateEntered() { 2181 LOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 2182 2183 mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 2184} 2185 2186bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 2187 bool handled = false; 2188 2189 switch (msg->what()) { 2190 case kWhatShutdown: 2191 { 2192 mCodec->deferMessage(msg); 2193 break; 2194 } 2195 2196 case kWhatFlush: 2197 { 2198 // We're already doing this right now. 2199 handled = true; 2200 break; 2201 } 2202 2203 default: 2204 handled = BaseState::onMessageReceived(msg); 2205 break; 2206 } 2207 2208 return handled; 2209} 2210 2211bool ACodec::FlushingState::onOMXEvent( 2212 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 2213 switch (event) { 2214 case OMX_EventCmdComplete: 2215 { 2216 CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush); 2217 2218 if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 2219 CHECK(!mFlushComplete[data2]); 2220 mFlushComplete[data2] = true; 2221 } else { 2222 CHECK_EQ(data2, OMX_ALL); 2223 CHECK(mFlushComplete[kPortIndexInput]); 2224 CHECK(mFlushComplete[kPortIndexOutput]); 2225 2226 changeStateIfWeOwnAllBuffers(); 2227 } 2228 2229 return true; 2230 } 2231 2232 case OMX_EventPortSettingsChanged: 2233 { 2234 sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id()); 2235 msg->setInt32("type", omx_message::EVENT); 2236 msg->setPointer("node", mCodec->mNode); 2237 msg->setInt32("event", event); 2238 msg->setInt32("data1", data1); 2239 msg->setInt32("data2", data2); 2240 2241 LOGV("[%s] Deferring OMX_EventPortSettingsChanged", 2242 mCodec->mComponentName.c_str()); 2243 2244 mCodec->deferMessage(msg); 2245 2246 return true; 2247 } 2248 2249 default: 2250 return BaseState::onOMXEvent(event, data1, data2); 2251 } 2252 2253 return true; 2254} 2255 2256void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 2257 BaseState::onOutputBufferDrained(msg); 2258 2259 changeStateIfWeOwnAllBuffers(); 2260} 2261 2262void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 2263 BaseState::onInputBufferFilled(msg); 2264 2265 changeStateIfWeOwnAllBuffers(); 2266} 2267 2268void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 2269 if (mFlushComplete[kPortIndexInput] 2270 && mFlushComplete[kPortIndexOutput] 2271 && mCodec->allYourBuffersAreBelongToUs()) { 2272 sp<AMessage> notify = mCodec->mNotify->dup(); 2273 notify->setInt32("what", ACodec::kWhatFlushCompleted); 2274 notify->post(); 2275 2276 mCodec->mPortEOS[kPortIndexInput] = 2277 mCodec->mPortEOS[kPortIndexOutput] = false; 2278 2279 mCodec->changeState(mCodec->mExecutingState); 2280 } 2281} 2282 2283} // namespace android 2284 2285