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