componentbase.cpp revision 20d24dd0df20095a26ad14d06e0eb2a301f7f6a8
1/* 2 * Copyright (C) 2009 Wind River Systems. 3 */ 4 5#include <stdlib.h> 6#include <string.h> 7 8#include <pthread.h> 9 10#include <OMX_Core.h> 11#include <OMX_Component.h> 12 13#include <componentbase.h> 14 15#include <queue.h> 16#include <workqueue.h> 17 18#define LOG_TAG "componentbase" 19#include <log.h> 20 21/* 22 * CmdProcessWork 23 */ 24CmdProcessWork::CmdProcessWork(CmdHandlerInterface *ci) 25{ 26 this->ci = ci; 27 28 workq = new WorkQueue; 29 30 __queue_init(&q); 31 pthread_mutex_init(&lock, NULL); 32 33 workq->StartWork(); 34} 35 36CmdProcessWork::~CmdProcessWork() 37{ 38 workq->StopWork(); 39 delete workq; 40 41 pthread_mutex_lock(&lock); 42 queue_free_all(&q); 43 pthread_mutex_unlock(&lock); 44 45 pthread_mutex_destroy(&lock); 46} 47 48OMX_ERRORTYPE CmdProcessWork::PushCmdQueue(struct cmd_s *cmd) 49{ 50 int ret; 51 52 pthread_mutex_lock(&lock); 53 ret = queue_push_tail(&q, cmd); 54 if (ret) { 55 pthread_mutex_unlock(&lock); 56 return OMX_ErrorInsufficientResources; 57 } 58 59 workq->ScheduleWork(this); 60 pthread_mutex_unlock(&lock); 61 62 return OMX_ErrorNone; 63} 64 65struct cmd_s *CmdProcessWork::PopCmdQueue(void) 66{ 67 struct cmd_s *cmd; 68 69 pthread_mutex_lock(&lock); 70 cmd = (struct cmd_s *)queue_pop_head(&q); 71 pthread_mutex_unlock(&lock); 72 73 return cmd; 74} 75 76void CmdProcessWork::ScheduleIfAvailable(void) 77{ 78 bool avail; 79 80 pthread_mutex_lock(&lock); 81 avail = queue_length(&q) ? true : false; 82 pthread_mutex_unlock(&lock); 83 84 if (avail) 85 workq->ScheduleWork(this); 86} 87 88void CmdProcessWork::Work(void) 89{ 90 struct cmd_s *cmd; 91 92 cmd = PopCmdQueue(); 93 if (cmd) { 94 ci->CmdHandler(cmd); 95 free(cmd); 96 } 97 ScheduleIfAvailable(); 98} 99 100/* end of CmdProcessWork */ 101 102/* 103 * ComponentBase 104 */ 105/* 106 * constructor & destructor 107 */ 108void ComponentBase::__ComponentBase(void) 109{ 110 memset(name, 0, OMX_MAX_STRINGNAME_SIZE); 111 cmodule = NULL; 112 handle = NULL; 113 114 roles = NULL; 115 nr_roles = 0; 116 117 working_role = NULL; 118 119 ports = NULL; 120 nr_ports = 0; 121 memset(&portparam, 0, sizeof(portparam)); 122 123 state = OMX_StateUnloaded; 124 125 cmdwork = new CmdProcessWork(this); 126 127 executing = false; 128 pthread_mutex_init(&executing_lock, NULL); 129 pthread_cond_init(&executing_wait, NULL); 130 131 bufferwork = new WorkQueue(); 132 133 pthread_mutex_init(&ports_block, NULL); 134} 135 136ComponentBase::ComponentBase() 137{ 138 __ComponentBase(); 139} 140 141ComponentBase::ComponentBase(const OMX_STRING name) 142{ 143 __ComponentBase(); 144 SetName(name); 145} 146 147ComponentBase::~ComponentBase() 148{ 149 delete cmdwork; 150 151 delete bufferwork; 152 pthread_mutex_destroy(&executing_lock); 153 pthread_cond_destroy(&executing_wait); 154 155 pthread_mutex_destroy(&ports_block); 156 157 if (roles) { 158 OMX_U32 i; 159 160 for (i = 0; i < nr_roles; i++) 161 free(roles[i]); 162 163 free(roles); 164 } 165} 166 167/* end of constructor & destructor */ 168 169/* 170 * accessor 171 */ 172/* name */ 173void ComponentBase::SetName(const OMX_STRING name) 174{ 175 strncpy(this->name, name, OMX_MAX_STRINGNAME_SIZE); 176 this->name[OMX_MAX_STRINGNAME_SIZE-1] = '\0'; 177} 178 179const OMX_STRING ComponentBase::GetName(void) 180{ 181 return name; 182} 183 184/* component module */ 185void ComponentBase::SetCModule(CModule *cmodule) 186{ 187 this->cmodule = cmodule; 188} 189 190CModule *ComponentBase::GetCModule(void) 191{ 192 return cmodule; 193} 194 195/* end of accessor */ 196 197/* 198 * core methods & helpers 199 */ 200/* roles */ 201OMX_ERRORTYPE ComponentBase::SetRolesOfComponent(OMX_U32 nr_roles, 202 const OMX_U8 **roles) 203{ 204 OMX_U32 i; 205 206 this->roles = (OMX_U8 **)malloc(sizeof(OMX_STRING) * nr_roles); 207 if (!this->roles) 208 return OMX_ErrorInsufficientResources; 209 210 for (i = 0; i < nr_roles; i++) { 211 this->roles[i] = (OMX_U8 *)malloc(OMX_MAX_STRINGNAME_SIZE); 212 if (!this->roles[i]) { 213 int j; 214 215 for (j = (int )i-1; j >= 0; j--) 216 free(this->roles[j]); 217 free(this->roles); 218 219 return OMX_ErrorInsufficientResources; 220 } 221 222 strncpy((OMX_STRING)&this->roles[i][0], 223 (const OMX_STRING)&roles[i][0], 224 OMX_MAX_STRINGNAME_SIZE); 225 } 226 227 this->nr_roles = nr_roles; 228 return OMX_ErrorNone; 229} 230 231OMX_ERRORTYPE ComponentBase::GetRolesOfComponent(OMX_U32 *nr_roles, 232 OMX_U8 **roles) 233{ 234 OMX_U32 i; 235 OMX_U32 this_nr_roles = this->nr_roles; 236 237 if (!roles) { 238 *nr_roles = this_nr_roles; 239 return OMX_ErrorNone; 240 } 241 242 if (!nr_roles || (*nr_roles != this_nr_roles)) 243 return OMX_ErrorBadParameter; 244 245 for (i = 0; i < this_nr_roles; i++) { 246 if (!roles[i]) 247 break; 248 249 if (roles && roles[i]) 250 strncpy((OMX_STRING)&roles[i][0], 251 (const OMX_STRING)&this->roles[i][0], 252 OMX_MAX_STRINGNAME_SIZE); 253 } 254 255 if (i != this_nr_roles) 256 return OMX_ErrorBadParameter; 257 258 *nr_roles = this_nr_roles; 259 return OMX_ErrorNone; 260} 261 262bool ComponentBase::QueryHavingThisRole(const OMX_STRING role) 263{ 264 OMX_U32 i; 265 266 if (!roles || !role) 267 return false; 268 269 for (i = 0; i < nr_roles; i++) { 270 if (!strcmp((OMX_STRING)&roles[i][0], role)) 271 return true; 272 } 273 274 return false; 275} 276 277/* GetHandle & FreeHandle */ 278OMX_ERRORTYPE ComponentBase::GetHandle(OMX_HANDLETYPE *pHandle, 279 OMX_PTR pAppData, 280 OMX_CALLBACKTYPE *pCallBacks) 281{ 282 OMX_U32 i; 283 OMX_ERRORTYPE ret; 284 285 if (handle) 286 return OMX_ErrorUndefined; 287 288 handle = (OMX_COMPONENTTYPE *)calloc(1, sizeof(*handle)); 289 if (!handle) 290 return OMX_ErrorInsufficientResources; 291 292 /* handle initialization */ 293 SetTypeHeader(handle, sizeof(*handle)); 294 handle->pComponentPrivate = static_cast<OMX_PTR>(this); 295 handle->pApplicationPrivate = pAppData; 296 297 /* virtual - see derived class */ 298 ret = InitComponent(); 299 if (ret != OMX_ErrorNone) { 300 LOGE("failed to %s::InitComponent(), ret = 0x%08x\n", 301 name, ret); 302 goto free_handle; 303 } 304 305 for (i = 0; i < nr_ports; i++) { 306 ports[i]->SetOwner(handle); 307 ports[i]->SetCallbacks(handle, pCallBacks, pAppData); 308 } 309 310 /* connect handle's functions */ 311 handle->GetComponentVersion = GetComponentVersion; 312 handle->SendCommand = SendCommand; 313 handle->GetParameter = GetParameter; 314 handle->SetParameter = SetParameter; 315 handle->GetConfig = GetConfig; 316 handle->SetConfig = SetConfig; 317 handle->GetExtensionIndex = GetExtensionIndex; 318 handle->GetState = GetState; 319 handle->ComponentTunnelRequest = ComponentTunnelRequest; 320 handle->UseBuffer = UseBuffer; 321 handle->AllocateBuffer = AllocateBuffer; 322 handle->FreeBuffer = FreeBuffer; 323 handle->EmptyThisBuffer = EmptyThisBuffer; 324 handle->FillThisBuffer = FillThisBuffer; 325 handle->SetCallbacks = SetCallbacks; 326 handle->ComponentDeInit = ComponentDeInit; 327 handle->UseEGLImage = UseEGLImage; 328 handle->ComponentRoleEnum = ComponentRoleEnum; 329 330 appdata = pAppData; 331 callbacks = pCallBacks; 332 *pHandle = (OMX_HANDLETYPE *)handle; 333 334 state = OMX_StateLoaded; 335 return OMX_ErrorNone; 336 337free_handle: 338 free(this->handle); 339 this->handle = NULL; 340 341 return ret; 342} 343 344OMX_ERRORTYPE ComponentBase::FreeHandle(OMX_HANDLETYPE hComponent) 345{ 346 OMX_ERRORTYPE ret; 347 348 if (hComponent != handle) 349 return OMX_ErrorBadParameter; 350 351 /* virtual - see derived class */ 352 ret = ExitComponent(); 353 if (ret != OMX_ErrorNone) 354 return ret; 355 356 free(handle); 357 358 appdata = NULL; 359 callbacks = NULL; 360 361 state = OMX_StateUnloaded; 362 return OMX_ErrorNone; 363} 364 365/* end of core methods & helpers */ 366 367/* 368 * component methods & helpers 369 */ 370OMX_ERRORTYPE ComponentBase::GetComponentVersion( 371 OMX_IN OMX_HANDLETYPE hComponent, 372 OMX_OUT OMX_STRING pComponentName, 373 OMX_OUT OMX_VERSIONTYPE* pComponentVersion, 374 OMX_OUT OMX_VERSIONTYPE* pSpecVersion, 375 OMX_OUT OMX_UUIDTYPE* pComponentUUID) 376{ 377 ComponentBase *cbase; 378 379 if (!hComponent) 380 return OMX_ErrorBadParameter; 381 382 cbase = static_cast<ComponentBase *> 383 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 384 if (!cbase) 385 return OMX_ErrorBadParameter; 386 387 return cbase->CBaseGetComponentVersion(hComponent, 388 pComponentName, 389 pComponentVersion, 390 pSpecVersion, 391 pComponentUUID); 392} 393 394OMX_ERRORTYPE ComponentBase::CBaseGetComponentVersion( 395 OMX_IN OMX_HANDLETYPE hComponent, 396 OMX_OUT OMX_STRING pComponentName, 397 OMX_OUT OMX_VERSIONTYPE* pComponentVersion, 398 OMX_OUT OMX_VERSIONTYPE* pSpecVersion, 399 OMX_OUT OMX_UUIDTYPE* pComponentUUID) 400{ 401 /* 402 * Todo 403 */ 404 405 return OMX_ErrorNotImplemented; 406} 407 408OMX_ERRORTYPE ComponentBase::SendCommand( 409 OMX_IN OMX_HANDLETYPE hComponent, 410 OMX_IN OMX_COMMANDTYPE Cmd, 411 OMX_IN OMX_U32 nParam1, 412 OMX_IN OMX_PTR pCmdData) 413{ 414 ComponentBase *cbase; 415 416 if (!hComponent) 417 return OMX_ErrorBadParameter; 418 419 cbase = static_cast<ComponentBase *> 420 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 421 if (!cbase) 422 return OMX_ErrorBadParameter; 423 424 return cbase->CBaseSendCommand(hComponent, Cmd, nParam1, pCmdData); 425} 426 427OMX_ERRORTYPE ComponentBase::CBaseSendCommand( 428 OMX_IN OMX_HANDLETYPE hComponent, 429 OMX_IN OMX_COMMANDTYPE Cmd, 430 OMX_IN OMX_U32 nParam1, 431 OMX_IN OMX_PTR pCmdData) 432{ 433 struct cmd_s *cmd; 434 435 if (hComponent != handle) 436 return OMX_ErrorInvalidComponent; 437 438 /* basic error check */ 439 switch (Cmd) { 440 case OMX_CommandStateSet: 441 /* 442 * Todo 443 */ 444 break; 445 case OMX_CommandFlush: 446 /* 447 * Todo 448 */ 449 //break; 450 case OMX_CommandPortDisable: 451 /* 452 * Todo 453 */ 454 //break; 455 case OMX_CommandPortEnable: 456 /* 457 * Todo 458 */ 459 //break; 460 case OMX_CommandMarkBuffer: 461 /* 462 * Todo 463 */ 464 //break; 465 default: 466 LOGE("command %d not supported\n", Cmd); 467 return OMX_ErrorUnsupportedIndex; 468 } 469 470 cmd = (struct cmd_s *)malloc(sizeof(*cmd)); 471 if (!cmd) 472 return OMX_ErrorInsufficientResources; 473 474 cmd->cmd = Cmd; 475 cmd->param1 = nParam1; 476 cmd->cmddata = pCmdData; 477 478 return cmdwork->PushCmdQueue(cmd); 479} 480 481OMX_ERRORTYPE ComponentBase::GetParameter( 482 OMX_IN OMX_HANDLETYPE hComponent, 483 OMX_IN OMX_INDEXTYPE nParamIndex, 484 OMX_INOUT OMX_PTR pComponentParameterStructure) 485{ 486 ComponentBase *cbase; 487 488 if (!hComponent) 489 return OMX_ErrorBadParameter; 490 491 cbase = static_cast<ComponentBase *> 492 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 493 if (!cbase) 494 return OMX_ErrorBadParameter; 495 496 return cbase->CBaseGetParameter(hComponent, nParamIndex, 497 pComponentParameterStructure); 498} 499 500OMX_ERRORTYPE ComponentBase::CBaseGetParameter( 501 OMX_IN OMX_HANDLETYPE hComponent, 502 OMX_IN OMX_INDEXTYPE nParamIndex, 503 OMX_INOUT OMX_PTR pComponentParameterStructure) 504{ 505 OMX_ERRORTYPE ret = OMX_ErrorNone; 506 507 if (hComponent != handle) 508 return OMX_ErrorBadParameter; 509 510 switch (nParamIndex) { 511 case OMX_IndexParamAudioInit: 512 case OMX_IndexParamVideoInit: 513 case OMX_IndexParamImageInit: 514 case OMX_IndexParamOtherInit: { 515 OMX_PORT_PARAM_TYPE *p = 516 (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure; 517 518 memcpy(p, &portparam, sizeof(*p)); 519 break; 520 } 521 case OMX_IndexParamPortDefinition: { 522 OMX_PARAM_PORTDEFINITIONTYPE *p = 523 (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; 524 OMX_U32 index = p->nPortIndex; 525 PortBase *port = ports[index]; 526 527 memcpy(p, port->GetPortParam(), sizeof(*p)); 528 break; 529 } 530 case OMX_IndexParamAudioPortFormat: { 531 OMX_AUDIO_PARAM_PORTFORMATTYPE *p = 532 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure; 533 OMX_U32 index = p->nPortIndex; 534 PortBase *port = ports[index]; 535 536 memcpy(p, port->GetAudioPortParam(), sizeof(*p)); 537 break; 538 } 539 case OMX_IndexParamCompBufferSupplier: 540 /* 541 * Todo 542 */ 543 544 ret = OMX_ErrorUnsupportedIndex; 545 break; 546 default: 547 ret = ComponentGetParameter(nParamIndex, pComponentParameterStructure); 548 } /* switch */ 549 550 return ret; 551} 552 553OMX_ERRORTYPE ComponentBase::SetParameter( 554 OMX_IN OMX_HANDLETYPE hComponent, 555 OMX_IN OMX_INDEXTYPE nIndex, 556 OMX_IN OMX_PTR pComponentParameterStructure) 557{ 558 ComponentBase *cbase; 559 560 if (!hComponent) 561 return OMX_ErrorBadParameter; 562 563 cbase = static_cast<ComponentBase *> 564 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 565 if (!cbase) 566 return OMX_ErrorBadParameter; 567 568 return cbase->CBaseSetParameter(hComponent, nIndex, 569 pComponentParameterStructure); 570} 571 572OMX_ERRORTYPE ComponentBase::CBaseSetParameter( 573 OMX_IN OMX_HANDLETYPE hComponent, 574 OMX_IN OMX_INDEXTYPE nIndex, 575 OMX_IN OMX_PTR pComponentParameterStructure) 576{ 577 OMX_ERRORTYPE ret = OMX_ErrorNone; 578 579 if (hComponent != handle) 580 return OMX_ErrorBadParameter; 581 582 switch (nIndex) { 583 case OMX_IndexParamAudioInit: 584 case OMX_IndexParamVideoInit: 585 case OMX_IndexParamImageInit: 586 case OMX_IndexParamOtherInit: { 587 OMX_PORT_PARAM_TYPE *p = (OMX_PORT_PARAM_TYPE *) 588 pComponentParameterStructure; 589 590 memcpy(&portparam, p, sizeof(*p)); 591 break; 592 } 593 case OMX_IndexParamPortDefinition: { 594 OMX_PARAM_PORTDEFINITIONTYPE *p = 595 (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; 596 OMX_U32 index = p->nPortIndex; 597 PortBase *port = ports[index]; 598 599 port->SetPortParam(p); 600 break; 601 } 602 case OMX_IndexParamAudioPortFormat: { 603 OMX_AUDIO_PARAM_PORTFORMATTYPE *p = 604 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure; 605 OMX_U32 index = p->nPortIndex; 606 PortBase *port = ports[index]; 607 608 port->SetAudioPortParam(p); 609 break; 610 } 611 case OMX_IndexParamCompBufferSupplier: 612 /* 613 * Todo 614 */ 615 616 ret = OMX_ErrorUnsupportedIndex; 617 break; 618 case OMX_IndexParamStandardComponentRole: { 619 OMX_PARAM_COMPONENTROLETYPE *p = 620 (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; 621 622 ret = SetWorkingRole((OMX_STRING)p->cRole); 623 if (ret != OMX_ErrorNone) 624 return ret; 625 break; 626 } 627 default: 628 ret = ComponentSetParameter(nIndex, pComponentParameterStructure); 629 } /* switch */ 630 631 return ret; 632} 633 634OMX_ERRORTYPE ComponentBase::GetConfig( 635 OMX_IN OMX_HANDLETYPE hComponent, 636 OMX_IN OMX_INDEXTYPE nIndex, 637 OMX_INOUT OMX_PTR pComponentConfigStructure) 638{ 639 ComponentBase *cbase; 640 641 if (!hComponent) 642 return OMX_ErrorBadParameter; 643 644 cbase = static_cast<ComponentBase *> 645 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 646 if (!cbase) 647 return OMX_ErrorBadParameter; 648 649 return cbase->CBaseGetConfig(hComponent, nIndex, 650 pComponentConfigStructure); 651} 652 653OMX_ERRORTYPE ComponentBase::CBaseGetConfig( 654 OMX_IN OMX_HANDLETYPE hComponent, 655 OMX_IN OMX_INDEXTYPE nIndex, 656 OMX_INOUT OMX_PTR pComponentConfigStructure) 657{ 658 OMX_ERRORTYPE ret; 659 660 if (hComponent != handle) 661 return OMX_ErrorBadParameter; 662 663 switch (nIndex) { 664 default: 665 ret = ComponentGetConfig(nIndex, pComponentConfigStructure); 666 } 667 668 return ret; 669} 670 671OMX_ERRORTYPE ComponentBase::SetConfig( 672 OMX_IN OMX_HANDLETYPE hComponent, 673 OMX_IN OMX_INDEXTYPE nIndex, 674 OMX_IN OMX_PTR pComponentConfigStructure) 675{ 676 ComponentBase *cbase; 677 678 if (!hComponent) 679 return OMX_ErrorBadParameter; 680 681 cbase = static_cast<ComponentBase *> 682 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 683 if (!cbase) 684 return OMX_ErrorBadParameter; 685 686 return cbase->CBaseSetConfig(hComponent, nIndex, 687 pComponentConfigStructure); 688} 689 690OMX_ERRORTYPE ComponentBase::CBaseSetConfig( 691 OMX_IN OMX_HANDLETYPE hComponent, 692 OMX_IN OMX_INDEXTYPE nIndex, 693 OMX_IN OMX_PTR pComponentConfigStructure) 694{ 695 OMX_ERRORTYPE ret; 696 697 if (hComponent != handle) 698 return OMX_ErrorBadParameter; 699 700 switch (nIndex) { 701 default: 702 ret = ComponentSetConfig(nIndex, pComponentConfigStructure); 703 } 704 705 return ret; 706} 707 708OMX_ERRORTYPE ComponentBase::GetExtensionIndex( 709 OMX_IN OMX_HANDLETYPE hComponent, 710 OMX_IN OMX_STRING cParameterName, 711 OMX_OUT OMX_INDEXTYPE* pIndexType) 712{ 713 ComponentBase *cbase; 714 715 if (!hComponent) 716 return OMX_ErrorBadParameter; 717 718 cbase = static_cast<ComponentBase *> 719 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 720 if (!cbase) 721 return OMX_ErrorBadParameter; 722 723 return cbase->CBaseGetExtensionIndex(hComponent, cParameterName, 724 pIndexType); 725} 726 727OMX_ERRORTYPE ComponentBase::CBaseGetExtensionIndex( 728 OMX_IN OMX_HANDLETYPE hComponent, 729 OMX_IN OMX_STRING cParameterName, 730 OMX_OUT OMX_INDEXTYPE* pIndexType) 731{ 732 /* 733 * Todo 734 */ 735 736 return OMX_ErrorNotImplemented; 737} 738 739OMX_ERRORTYPE ComponentBase::GetState( 740 OMX_IN OMX_HANDLETYPE hComponent, 741 OMX_OUT OMX_STATETYPE* pState) 742{ 743 ComponentBase *cbase; 744 745 if (!hComponent) 746 return OMX_ErrorBadParameter; 747 748 cbase = static_cast<ComponentBase *> 749 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 750 if (!cbase) 751 return OMX_ErrorBadParameter; 752 753 return cbase->CBaseGetState(hComponent, pState); 754} 755 756OMX_ERRORTYPE ComponentBase::CBaseGetState( 757 OMX_IN OMX_HANDLETYPE hComponent, 758 OMX_OUT OMX_STATETYPE* pState) 759{ 760 if (hComponent != handle) 761 return OMX_ErrorBadParameter; 762 763 *pState = state; 764 return OMX_ErrorNone; 765} 766 767OMX_ERRORTYPE ComponentBase::ComponentTunnelRequest( 768 OMX_IN OMX_HANDLETYPE hComponent, 769 OMX_IN OMX_U32 nPort, 770 OMX_IN OMX_HANDLETYPE hTunneledComponent, 771 OMX_IN OMX_U32 nTunneledPort, 772 OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup) 773{ 774 ComponentBase *cbase; 775 776 if (!hComponent) 777 return OMX_ErrorBadParameter; 778 779 cbase = static_cast<ComponentBase *> 780 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 781 if (!cbase) 782 return OMX_ErrorBadParameter; 783 784 return cbase->CBaseComponentTunnelRequest(hComponent, nPort, 785 hTunneledComponent, 786 nTunneledPort, pTunnelSetup); 787} 788 789OMX_ERRORTYPE ComponentBase::CBaseComponentTunnelRequest( 790 OMX_IN OMX_HANDLETYPE hComp, 791 OMX_IN OMX_U32 nPort, 792 OMX_IN OMX_HANDLETYPE hTunneledComp, 793 OMX_IN OMX_U32 nTunneledPort, 794 OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup) 795{ 796 /* 797 * Todo 798 */ 799 800 return OMX_ErrorNotImplemented; 801} 802 803OMX_ERRORTYPE ComponentBase::UseBuffer( 804 OMX_IN OMX_HANDLETYPE hComponent, 805 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 806 OMX_IN OMX_U32 nPortIndex, 807 OMX_IN OMX_PTR pAppPrivate, 808 OMX_IN OMX_U32 nSizeBytes, 809 OMX_IN OMX_U8 *pBuffer) 810{ 811 ComponentBase *cbase; 812 813 if (!hComponent) 814 return OMX_ErrorBadParameter; 815 816 cbase = static_cast<ComponentBase *> 817 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 818 if (!cbase) 819 return OMX_ErrorBadParameter; 820 821 return cbase->CBaseUseBuffer(hComponent, ppBufferHdr, nPortIndex, 822 pAppPrivate, nSizeBytes, pBuffer); 823} 824 825OMX_ERRORTYPE ComponentBase::CBaseUseBuffer( 826 OMX_IN OMX_HANDLETYPE hComponent, 827 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 828 OMX_IN OMX_U32 nPortIndex, 829 OMX_IN OMX_PTR pAppPrivate, 830 OMX_IN OMX_U32 nSizeBytes, 831 OMX_IN OMX_U8 *pBuffer) 832{ 833 PortBase *port = NULL; 834 OMX_ERRORTYPE ret; 835 836 if (hComponent != handle) 837 return OMX_ErrorBadParameter; 838 839 if (ports) 840 if (nPortIndex < nr_ports) 841 port = ports[nPortIndex]; 842 843 if (!port) 844 return OMX_ErrorBadParameter; 845 846 return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, 847 pBuffer); 848} 849 850OMX_ERRORTYPE ComponentBase::AllocateBuffer( 851 OMX_IN OMX_HANDLETYPE hComponent, 852 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 853 OMX_IN OMX_U32 nPortIndex, 854 OMX_IN OMX_PTR pAppPrivate, 855 OMX_IN OMX_U32 nSizeBytes) 856{ 857 ComponentBase *cbase; 858 859 if (!hComponent) 860 return OMX_ErrorBadParameter; 861 862 cbase = static_cast<ComponentBase *> 863 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 864 if (!cbase) 865 return OMX_ErrorBadParameter; 866 867 return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex, 868 pAppPrivate, nSizeBytes); 869} 870 871OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer( 872 OMX_IN OMX_HANDLETYPE hComponent, 873 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 874 OMX_IN OMX_U32 nPortIndex, 875 OMX_IN OMX_PTR pAppPrivate, 876 OMX_IN OMX_U32 nSizeBytes) 877{ 878 PortBase *port = NULL; 879 OMX_ERRORTYPE ret; 880 881 if (hComponent != handle) 882 return OMX_ErrorBadParameter; 883 884 if (ports) 885 if (nPortIndex < nr_ports) 886 port = ports[nPortIndex]; 887 888 if (!port) 889 return OMX_ErrorBadParameter; 890 891 return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes); 892} 893 894OMX_ERRORTYPE ComponentBase::FreeBuffer( 895 OMX_IN OMX_HANDLETYPE hComponent, 896 OMX_IN OMX_U32 nPortIndex, 897 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 898{ 899 ComponentBase *cbase; 900 901 if (!hComponent) 902 return OMX_ErrorBadParameter; 903 904 cbase = static_cast<ComponentBase *> 905 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 906 if (!cbase) 907 return OMX_ErrorBadParameter; 908 909 return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer); 910} 911 912OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer( 913 OMX_IN OMX_HANDLETYPE hComponent, 914 OMX_IN OMX_U32 nPortIndex, 915 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 916{ 917 PortBase *port = NULL; 918 OMX_ERRORTYPE ret; 919 920 if (hComponent != handle) 921 return OMX_ErrorBadParameter; 922 923 if (ports) 924 if (nPortIndex < nr_ports) 925 port = ports[nPortIndex]; 926 927 if (!port) 928 return OMX_ErrorBadParameter; 929 930 return port->FreeBuffer(nPortIndex, pBuffer); 931} 932 933OMX_ERRORTYPE ComponentBase::EmptyThisBuffer( 934 OMX_IN OMX_HANDLETYPE hComponent, 935 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 936{ 937 ComponentBase *cbase; 938 939 if (!hComponent) 940 return OMX_ErrorBadParameter; 941 942 cbase = static_cast<ComponentBase *> 943 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 944 if (!cbase) 945 return OMX_ErrorBadParameter; 946 947 return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer); 948} 949 950OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer( 951 OMX_IN OMX_HANDLETYPE hComponent, 952 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 953{ 954 PortBase *port = NULL; 955 OMX_U32 port_index; 956 OMX_ERRORTYPE ret; 957 958 if ((hComponent != handle) || !pBuffer) 959 return OMX_ErrorBadParameter; 960 961 port_index = pBuffer->nInputPortIndex; 962 if (port_index == (OMX_U32)-1) 963 return OMX_ErrorBadParameter; 964 965 if (ports) 966 if (port_index < nr_ports) 967 port = ports[port_index]; 968 969 if (!port) 970 return OMX_ErrorBadParameter; 971 972 ret = port->PushThisBuffer(pBuffer); 973 if (ret == OMX_ErrorNone) 974 bufferwork->ScheduleWork(this); 975 976 return ret; 977} 978 979OMX_ERRORTYPE ComponentBase::FillThisBuffer( 980 OMX_IN OMX_HANDLETYPE hComponent, 981 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 982{ 983 ComponentBase *cbase; 984 985 if (!hComponent) 986 return OMX_ErrorBadParameter; 987 988 cbase = static_cast<ComponentBase *> 989 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 990 if (!cbase) 991 return OMX_ErrorBadParameter; 992 993 return cbase->CBaseFillThisBuffer(hComponent, pBuffer); 994} 995 996OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer( 997 OMX_IN OMX_HANDLETYPE hComponent, 998 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 999{ 1000 PortBase *port = NULL; 1001 OMX_U32 port_index; 1002 OMX_ERRORTYPE ret; 1003 1004 if ((hComponent != handle) || !pBuffer) 1005 return OMX_ErrorBadParameter; 1006 1007 port_index = pBuffer->nOutputPortIndex; 1008 if (port_index == (OMX_U32)-1) 1009 return OMX_ErrorBadParameter; 1010 1011 if (ports) 1012 if (port_index < nr_ports) 1013 port = ports[port_index]; 1014 1015 if (!port) 1016 return OMX_ErrorBadParameter; 1017 1018 ret = port->PushThisBuffer(pBuffer); 1019 if (ret == OMX_ErrorNone) 1020 bufferwork->ScheduleWork(this); 1021 1022 return ret; 1023} 1024 1025OMX_ERRORTYPE ComponentBase::SetCallbacks( 1026 OMX_IN OMX_HANDLETYPE hComponent, 1027 OMX_IN OMX_CALLBACKTYPE* pCallbacks, 1028 OMX_IN OMX_PTR pAppData) 1029{ 1030 ComponentBase *cbase; 1031 1032 if (!hComponent) 1033 return OMX_ErrorBadParameter; 1034 1035 cbase = static_cast<ComponentBase *> 1036 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1037 if (!cbase) 1038 return OMX_ErrorBadParameter; 1039 1040 return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData); 1041} 1042 1043OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks( 1044 OMX_IN OMX_HANDLETYPE hComponent, 1045 OMX_IN OMX_CALLBACKTYPE *pCallbacks, 1046 OMX_IN OMX_PTR pAppData) 1047{ 1048 if (hComponent != handle) 1049 return OMX_ErrorBadParameter; 1050 1051 appdata = pAppData; 1052 callbacks = pCallbacks; 1053 1054 return OMX_ErrorNone; 1055} 1056 1057OMX_ERRORTYPE ComponentBase::ComponentDeInit( 1058 OMX_IN OMX_HANDLETYPE hComponent) 1059{ 1060 ComponentBase *cbase; 1061 1062 if (!hComponent) 1063 return OMX_ErrorBadParameter; 1064 1065 cbase = static_cast<ComponentBase *> 1066 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1067 if (!cbase) 1068 return OMX_ErrorBadParameter; 1069 1070 return cbase->CBaseComponentDeInit(hComponent); 1071} 1072 1073OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit( 1074 OMX_IN OMX_HANDLETYPE hComponent) 1075{ 1076 /* 1077 * Todo 1078 */ 1079 1080 return OMX_ErrorNotImplemented; 1081} 1082 1083OMX_ERRORTYPE ComponentBase::UseEGLImage( 1084 OMX_IN OMX_HANDLETYPE hComponent, 1085 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1086 OMX_IN OMX_U32 nPortIndex, 1087 OMX_IN OMX_PTR pAppPrivate, 1088 OMX_IN void* eglImage) 1089{ 1090 ComponentBase *cbase; 1091 1092 if (!hComponent) 1093 return OMX_ErrorBadParameter; 1094 1095 cbase = static_cast<ComponentBase *> 1096 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1097 if (!cbase) 1098 return OMX_ErrorBadParameter; 1099 1100 return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex, 1101 pAppPrivate, eglImage); 1102} 1103 1104OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage( 1105 OMX_IN OMX_HANDLETYPE hComponent, 1106 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1107 OMX_IN OMX_U32 nPortIndex, 1108 OMX_IN OMX_PTR pAppPrivate, 1109 OMX_IN void* eglImage) 1110{ 1111 /* 1112 * Todo 1113 */ 1114 1115 return OMX_ErrorNotImplemented; 1116} 1117 1118OMX_ERRORTYPE ComponentBase::ComponentRoleEnum( 1119 OMX_IN OMX_HANDLETYPE hComponent, 1120 OMX_OUT OMX_U8 *cRole, 1121 OMX_IN OMX_U32 nIndex) 1122{ 1123 ComponentBase *cbase; 1124 1125 if (!hComponent) 1126 return OMX_ErrorBadParameter; 1127 1128 cbase = static_cast<ComponentBase *> 1129 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1130 if (!cbase) 1131 return OMX_ErrorBadParameter; 1132 1133 return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex); 1134} 1135 1136OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum( 1137 OMX_IN OMX_HANDLETYPE hComponent, 1138 OMX_OUT OMX_U8 *cRole, 1139 OMX_IN OMX_U32 nIndex) 1140{ 1141 if (hComponent != (OMX_HANDLETYPE *)this->handle) 1142 return OMX_ErrorBadParameter; 1143 1144 if (nIndex > nr_roles) 1145 return OMX_ErrorBadParameter; 1146 1147 strncpy((char *)cRole, (const char *)roles[nIndex], 1148 OMX_MAX_STRINGNAME_SIZE); 1149 return OMX_ErrorNone; 1150} 1151 1152/* implement CmdHandlerInterface */ 1153void ComponentBase::CmdHandler(struct cmd_s *cmd) 1154{ 1155 switch (cmd->cmd) { 1156 case OMX_CommandStateSet: { 1157 OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1; 1158 1159 TransState(transition); 1160 break; 1161 } 1162 case OMX_CommandFlush: 1163 /* 1164 * Todo 1165 */ 1166 break; 1167 case OMX_CommandPortDisable: 1168 /* 1169 * Todo 1170 */ 1171 break; 1172 case OMX_CommandPortEnable: 1173 /* 1174 * Todo 1175 */ 1176 break; 1177 case OMX_CommandMarkBuffer: 1178 /* 1179 * Todo 1180 */ 1181 break; 1182 } /* switch */ 1183} 1184 1185/* 1186 * SendCommand:OMX_CommandStateSet 1187 * called in CmdHandler or called in other parts of component for reporting 1188 * internal error (OMX_StateInvalid). 1189 */ 1190/* 1191 * Todo 1192 * Resource Management (OMX_StateWaitForResources) 1193 * for now, we never notify OMX_ErrorInsufficientResources, 1194 * so IL client doesn't try to set component' state OMX_StateWaitForResources 1195 */ 1196static const char *state_name[OMX_StateWaitForResources + 1] = { 1197 "OMX_StateInvalid", 1198 "OMX_StateLoaded", 1199 "OMX_StateIdle", 1200 "OMX_StateExecuting", 1201 "OMX_StatePause", 1202 "OMX_StateWaitForResources", 1203}; 1204 1205static inline const char *GetStateName(OMX_STATETYPE state) 1206{ 1207 if (state > OMX_StateWaitForResources) 1208 return "UnKnown"; 1209 1210 return state_name[state]; 1211} 1212 1213void ComponentBase::TransState(OMX_STATETYPE transition) 1214{ 1215 OMX_STATETYPE current = this->state; 1216 OMX_EVENTTYPE event; 1217 OMX_U32 data1; 1218 OMX_ERRORTYPE ret; 1219 1220 LOGD("current state = %s, transition state = %s\n", 1221 GetStateName(current), GetStateName(transition)); 1222 1223 /* same state */ 1224 if (current == transition) { 1225 ret = OMX_ErrorSameState; 1226 goto notify_event; 1227 } 1228 1229 /* invalid state */ 1230 if (current == OMX_StateInvalid) { 1231 ret = OMX_ErrorInvalidState; 1232 goto notify_event; 1233 } 1234 1235 if (transition == OMX_StateLoaded) 1236 ret = TransStateToLoaded(current); 1237 else if (transition == OMX_StateIdle) 1238 ret = TransStateToIdle(current); 1239 else if (transition == OMX_StateExecuting) 1240 ret = TransStateToExecuting(current); 1241 else if (transition == OMX_StatePause) 1242 ret = TransStateToPause(current); 1243 else if (transition == OMX_StateInvalid) 1244 ret = TransStateToInvalid(current); 1245 else if (transition == OMX_StateWaitForResources) 1246 ret = TransStateToWaitForResources(current); 1247 else 1248 ret = OMX_ErrorIncorrectStateTransition; 1249 1250notify_event: 1251 if (ret == OMX_ErrorNone) { 1252 event = OMX_EventCmdComplete; 1253 data1 = transition; 1254 1255 state = transition; 1256 LOGD("transition from %s to %s completed\n", 1257 GetStateName(current), GetStateName(transition)); 1258 } 1259 else { 1260 event = OMX_EventError; 1261 data1 = ret; 1262 1263 if (transition == OMX_StateInvalid) { 1264 state = transition; 1265 LOGD("transition from %s to %s completed\n", 1266 GetStateName(current), GetStateName(transition)); 1267 } 1268 } 1269 1270 callbacks->EventHandler(handle, appdata, event, data1, 0, NULL); 1271 1272 /* WaitForResources workaround */ 1273 if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources) 1274 callbacks->EventHandler(handle, appdata, 1275 OMX_EventResourcesAcquired, 0, 0, NULL); 1276} 1277 1278inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current) 1279{ 1280 OMX_ERRORTYPE ret; 1281 1282 if (current == OMX_StateIdle) { 1283 /* 1284 * Todo 1285 * 1. waits for completion of deallocation on each port 1286 * wokeup by FreeBuffer() 1287 * 2. deinitialize buffer process work 1288 * 3. deinitialize component's internal processor 1289 * (ex. deinitialize sw/hw codec) 1290 */ 1291 OMX_U32 i; 1292 1293 for (i = 0; i < nr_ports; i++) 1294 ports[i]->WaitPortBufferCompletion(); 1295 1296 ret = OMX_ErrorNone; 1297 } 1298 else if (current == OMX_StateWaitForResources) { 1299 LOGE("state transition's requested from WaitForResources to " 1300 "Loaded\n"); 1301 1302 /* 1303 * from WaitForResources to Loaded considered from Loaded to Loaded. 1304 * do nothing 1305 */ 1306 1307 ret = OMX_ErrorNone; 1308 } 1309 else 1310 ret = OMX_ErrorIncorrectStateOperation; 1311 1312 return ret; 1313} 1314 1315inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current) 1316{ 1317 OMX_ERRORTYPE ret; 1318 1319 if (current == OMX_StateLoaded) { 1320 /* 1321 * Todo 1322 * 1. waits for completion of allocation on each port. 1323 * wokeup by Allocate/UseBuffer() 1324 * 2. initialize buffer process work. 1325 * 3. initialize component's internal processor. 1326 * (ex. initialize sw/hw codec) 1327 */ 1328 OMX_U32 i; 1329 1330 for (i = 0; i < nr_ports; i++) 1331 ports[i]->WaitPortBufferCompletion(); 1332 1333 ret = OMX_ErrorNone; 1334 } 1335 else if (current == OMX_StateExecuting) { 1336 /* 1337 * Todo 1338 * 1. returns all buffers to thier suppliers. ! 1339 * call Fill/EmptyBufferDone() for all ports 1340 * 2. stop buffer process work ! 1341 * 3. stop component's internal processor 1342 */ 1343 OMX_U32 i; 1344 1345 pthread_mutex_lock(&ports_block); 1346 for (i = 0; i < nr_ports; i++) { 1347 ports[i]->FlushPort(); 1348 } 1349 pthread_mutex_unlock(&ports_block); 1350 1351 bufferwork->StopWork(); 1352 1353 ret = OMX_ErrorNone; 1354 } 1355 else if (current == OMX_StatePause) { 1356 /* 1357 * Todo 1358 * 1. returns all buffers to thier suppliers. ! 1359 * call Fill/EmptyBufferDone() for all ports 1360 * 2. discard queued work, stop buffer process work ! 1361 * 3. stop component's internal processor 1362 */ 1363 OMX_U32 i; 1364 1365 pthread_mutex_lock(&ports_block); 1366 for (i = 0; i < nr_ports; i++) { 1367 ports[i]->FlushPort(); 1368 } 1369 pthread_mutex_unlock(&ports_block); 1370 1371 bufferwork->CancelScheduledWork(this); 1372 bufferwork->StopWork(); 1373 1374 ret = OMX_ErrorNone; 1375 } 1376 else if (current == OMX_StateWaitForResources) { 1377 LOGE("state transition's requested from WaitForResources to Idle\n"); 1378 1379 /* same as Loaded to Idle BUT DO NOTHING for now */ 1380 1381 ret = OMX_ErrorNone; 1382 } 1383 else 1384 ret = OMX_ErrorIncorrectStateOperation; 1385 1386 return ret; 1387} 1388 1389inline OMX_ERRORTYPE 1390ComponentBase::TransStateToExecuting(OMX_STATETYPE current) 1391{ 1392 OMX_ERRORTYPE ret; 1393 1394 if (current == OMX_StateIdle) { 1395 /* 1396 * Todo 1397 * 1. start component's internal processor 1398 * 2. start processing buffers on each port ! 1399 */ 1400 1401 pthread_mutex_lock(&executing_lock); 1402 executing = true; 1403 pthread_mutex_unlock(&executing_lock); 1404 1405 bufferwork->StartWork(); 1406 ret = OMX_ErrorNone; 1407 } 1408 else if (current == OMX_StatePause) { 1409 /* 1410 * Todo 1411 * 1. resume component's internal processor 1412 * 2. resume buffer process work ! 1413 */ 1414 1415 pthread_mutex_lock(&executing_lock); 1416 executing = true; 1417 pthread_cond_signal(&executing_wait); 1418 pthread_mutex_unlock(&executing_lock); 1419 1420 ret = OMX_ErrorNone; 1421 } 1422 else 1423 ret = OMX_ErrorIncorrectStateOperation; 1424 1425 return ret; 1426} 1427 1428inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current) 1429{ 1430 OMX_ERRORTYPE ret; 1431 1432 if (current == OMX_StateIdle) { 1433 /* 1434 * Todo 1435 * 1. start(paused) component's internal processor 1436 * 2. start(paused) processing buffers on each port ! 1437 */ 1438 1439 /* turn off executing flag */ 1440 pthread_mutex_lock(&executing_lock); 1441 executing = false; 1442 pthread_mutex_unlock(&executing_lock); 1443 1444 bufferwork->StartWork(); 1445 1446 ret = OMX_ErrorNone; 1447 } 1448 else if (current == OMX_StateExecuting) { 1449 /* 1450 * Todo 1451 * 1. pause buffer process work ! 1452 * 2. pause component's internal processor 1453 */ 1454 1455 pthread_mutex_lock(&executing_lock); 1456 executing = false; 1457 pthread_mutex_unlock(&executing_lock); 1458 1459 ret = OMX_ErrorNone; 1460 } 1461 else 1462 ret = OMX_ErrorIncorrectStateOperation; 1463 1464 return ret; 1465} 1466 1467inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current) 1468{ 1469 OMX_ERRORTYPE ret = OMX_ErrorInvalidState; 1470 1471 /* 1472 * Todo 1473 * graceful escape 1474 */ 1475 1476 return ret; 1477} 1478 1479inline OMX_ERRORTYPE 1480ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current) 1481{ 1482 OMX_ERRORTYPE ret; 1483 1484 if (current == OMX_StateLoaded) { 1485 LOGE("state transition's requested from Loaded to WaitForResources\n"); 1486 ret = OMX_ErrorNone; 1487 } 1488 else 1489 ret = OMX_ErrorIncorrectStateOperation; 1490 1491 return ret; 1492} 1493 1494/* set working role */ 1495OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role) 1496{ 1497 OMX_U32 i; 1498 1499 if (!role) 1500 return OMX_ErrorBadParameter; 1501 1502 for (i = 0; i < nr_roles; i++) { 1503 if (!strcmp((char *)&roles[i][0], role)) { 1504 working_role = (OMX_STRING)&roles[i][0]; 1505 return OMX_ErrorNone; 1506 } 1507 } 1508 1509 return OMX_ErrorBadParameter; 1510} 1511 1512/* apply a working role for a component having multiple roles */ 1513OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void) 1514{ 1515 OMX_ERRORTYPE ret; 1516 1517 if (!working_role) 1518 return OMX_ErrorBadParameter; 1519 1520 ret = AllocatePorts(); 1521 if (ret != OMX_ErrorNone) { 1522 LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret); 1523 return ret; 1524 } 1525 1526 return OMX_ErrorNone; 1527} 1528 1529OMX_ERRORTYPE ComponentBase::AllocatePorts(void) 1530{ 1531 OMX_ERRORTYPE ret; 1532 OMX_U32 i; 1533 1534 if (ports) 1535 return OMX_ErrorBadParameter; 1536 1537 if (!callbacks || !appdata) 1538 return OMX_ErrorBadParameter; 1539 1540 ret = ComponentAllocatePorts(); 1541 if (ret != OMX_ErrorNone) { 1542 LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n", 1543 name, ret); 1544 return ret; 1545 } 1546 1547 /* now we can access ports */ 1548 for (i = 0; i < nr_ports; i++) { 1549 ports[i]->SetOwner(handle); 1550 ports[i]->SetCallbacks(handle, callbacks, appdata); 1551 } 1552 1553 return OMX_ErrorNone; 1554} 1555 1556/* called int FreeHandle() */ 1557OMX_ERRORTYPE ComponentBase::FreePorts(void) 1558{ 1559 if (ports) { 1560 OMX_U32 i, this_nr_ports = this->nr_ports; 1561 1562 for (i = 0; i < this_nr_ports; i++) { 1563 if (ports[i]) { 1564 delete ports[i]; 1565 ports[i] = NULL; 1566 } 1567 } 1568 delete []ports; 1569 ports = NULL; 1570 } 1571 1572 return OMX_ErrorNone; 1573} 1574 1575/* buffer processing */ 1576/* implement WorkableInterface */ 1577void ComponentBase::Work(void) 1578{ 1579 OMX_BUFFERHEADERTYPE **buffers = NULL; 1580 OMX_U32 i; 1581 bool avail = false; 1582 1583 pthread_mutex_lock(&executing_lock); 1584 if (!executing) 1585 pthread_cond_wait(&executing_wait, &executing_lock); 1586 pthread_mutex_unlock(&executing_lock); 1587 1588 pthread_mutex_lock(&ports_block); 1589 1590 avail = IsAllBufferAvailable(); 1591 if (avail) { 1592 buffers = (OMX_BUFFERHEADERTYPE **) 1593 calloc(nr_ports, sizeof(OMX_BUFFERHEADERTYPE *)); 1594 if (!buffers) { 1595 bufferwork->ScheduleWork(this); 1596 return; 1597 } 1598 1599 for (i = 0; i < nr_ports; i++) 1600 buffers[i] = ports[i]->PopBuffer(); 1601 } 1602 ScheduleIfAllBufferAvailable(); 1603 1604 pthread_mutex_unlock(&ports_block); 1605 1606 if (buffers) { 1607 ComponentProcessBuffers(buffers, nr_ports); 1608 1609 free(buffers); 1610 buffers = NULL; 1611 } 1612} 1613 1614bool ComponentBase::IsAllBufferAvailable(void) 1615{ 1616 OMX_U32 i; 1617 OMX_U32 nr_avail = 0; 1618 1619 for (i = 0; i < nr_ports; i++) { 1620 OMX_U32 length; 1621 1622 length = ports[i]->BufferQueueLength(); 1623 if (length) 1624 nr_avail++; 1625 } 1626 1627 if (nr_avail == nr_ports) 1628 return true; 1629 else 1630 return false; 1631} 1632 1633void ComponentBase::ScheduleIfAllBufferAvailable(void) 1634{ 1635 bool avail; 1636 1637 avail = IsAllBufferAvailable(); 1638 if (avail) 1639 bufferwork->ScheduleWork(this); 1640} 1641 1642/* end of component methods & helpers */ 1643 1644/* 1645 * omx header manipuation 1646 */ 1647void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size) 1648{ 1649 OMX_U32 *nsize; 1650 OMX_VERSIONTYPE *nversion; 1651 1652 if (!type) 1653 return; 1654 1655 nsize = (OMX_U32 *)type; 1656 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 1657 1658 *nsize = size; 1659 nversion->nVersion = OMX_SPEC_VERSION; 1660} 1661 1662OMX_ERRORTYPE ComponentBase::CheckTypeHeader(OMX_PTR type, OMX_U32 size) 1663{ 1664 OMX_U32 *nsize; 1665 OMX_VERSIONTYPE *nversion; 1666 1667 if (!type) 1668 return OMX_ErrorBadParameter; 1669 1670 nsize = (OMX_U32 *)type; 1671 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 1672 1673 if (*nsize != size) 1674 return OMX_ErrorBadParameter; 1675 1676 if (nversion->nVersion != OMX_SPEC_VERSION) 1677 return OMX_ErrorVersionMismatch; 1678 1679 return OMX_ErrorNone; 1680} 1681 1682/* end of ComponentBase */ 1683