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