componentbase.cpp revision abd679fdaba9c3c8230dbcbaa838a5100acb546d
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 /* 728 * Todo 729 */ 730 731 return OMX_ErrorNotImplemented; 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 /* 801 * Todo 802 */ 803 804 return OMX_ErrorNotImplemented; 805} 806 807OMX_ERRORTYPE ComponentBase::AllocateBuffer( 808 OMX_IN OMX_HANDLETYPE hComponent, 809 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer, 810 OMX_IN OMX_U32 nPortIndex, 811 OMX_IN OMX_PTR pAppPrivate, 812 OMX_IN OMX_U32 nSizeBytes) 813{ 814 ComponentBase *cbase; 815 816 if (!hComponent) 817 return OMX_ErrorBadParameter; 818 819 cbase = static_cast<ComponentBase *> 820 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 821 if (!cbase) 822 return OMX_ErrorBadParameter; 823 824 return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex, 825 pAppPrivate, nSizeBytes); 826} 827 828OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer( 829 OMX_IN OMX_HANDLETYPE hComponent, 830 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer, 831 OMX_IN OMX_U32 nPortIndex, 832 OMX_IN OMX_PTR pAppPrivate, 833 OMX_IN OMX_U32 nSizeBytes) 834{ 835 /* 836 * Todo 837 */ 838 839 return OMX_ErrorNotImplemented; 840} 841 842OMX_ERRORTYPE ComponentBase::FreeBuffer( 843 OMX_IN OMX_HANDLETYPE hComponent, 844 OMX_IN OMX_U32 nPortIndex, 845 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 846{ 847 ComponentBase *cbase; 848 849 if (!hComponent) 850 return OMX_ErrorBadParameter; 851 852 cbase = static_cast<ComponentBase *> 853 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 854 if (!cbase) 855 return OMX_ErrorBadParameter; 856 857 return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer); 858} 859 860OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer( 861 OMX_IN OMX_HANDLETYPE hComponent, 862 OMX_IN OMX_U32 nPortIndex, 863 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 864{ 865 /* 866 * Todo 867 */ 868 869 return OMX_ErrorNotImplemented; 870} 871 872OMX_ERRORTYPE ComponentBase::EmptyThisBuffer( 873 OMX_IN OMX_HANDLETYPE hComponent, 874 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 875{ 876 ComponentBase *cbase; 877 878 if (!hComponent) 879 return OMX_ErrorBadParameter; 880 881 cbase = static_cast<ComponentBase *> 882 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 883 if (!cbase) 884 return OMX_ErrorBadParameter; 885 886 return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer); 887} 888 889OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer( 890 OMX_IN OMX_HANDLETYPE hComponent, 891 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 892{ 893 /* 894 * Todo 895 */ 896 897 return OMX_ErrorNotImplemented; 898} 899 900OMX_ERRORTYPE ComponentBase::FillThisBuffer( 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->CBaseFillThisBuffer(hComponent, pBuffer); 915} 916 917OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer( 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::SetCallbacks( 929 OMX_IN OMX_HANDLETYPE hComponent, 930 OMX_IN OMX_CALLBACKTYPE* pCallbacks, 931 OMX_IN OMX_PTR pAppData) 932{ 933 ComponentBase *cbase; 934 935 if (!hComponent) 936 return OMX_ErrorBadParameter; 937 938 cbase = static_cast<ComponentBase *> 939 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 940 if (!cbase) 941 return OMX_ErrorBadParameter; 942 943 return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData); 944} 945 946OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks( 947 OMX_IN OMX_HANDLETYPE hComponent, 948 OMX_IN OMX_CALLBACKTYPE *pCallbacks, 949 OMX_IN OMX_PTR pAppData) 950{ 951 if (hComponent != handle) 952 return OMX_ErrorBadParameter; 953 954 appdata = pAppData; 955 callbacks = pCallbacks; 956 957 return OMX_ErrorNone; 958} 959 960OMX_ERRORTYPE ComponentBase::ComponentDeInit( 961 OMX_IN OMX_HANDLETYPE hComponent) 962{ 963 ComponentBase *cbase; 964 965 if (!hComponent) 966 return OMX_ErrorBadParameter; 967 968 cbase = static_cast<ComponentBase *> 969 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 970 if (!cbase) 971 return OMX_ErrorBadParameter; 972 973 return cbase->CBaseComponentDeInit(hComponent); 974} 975 976OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit( 977 OMX_IN OMX_HANDLETYPE hComponent) 978{ 979 /* 980 * Todo 981 */ 982 983 return OMX_ErrorNotImplemented; 984} 985 986OMX_ERRORTYPE ComponentBase::UseEGLImage( 987 OMX_IN OMX_HANDLETYPE hComponent, 988 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 989 OMX_IN OMX_U32 nPortIndex, 990 OMX_IN OMX_PTR pAppPrivate, 991 OMX_IN void* eglImage) 992{ 993 ComponentBase *cbase; 994 995 if (!hComponent) 996 return OMX_ErrorBadParameter; 997 998 cbase = static_cast<ComponentBase *> 999 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1000 if (!cbase) 1001 return OMX_ErrorBadParameter; 1002 1003 return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex, 1004 pAppPrivate, eglImage); 1005} 1006 1007OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage( 1008 OMX_IN OMX_HANDLETYPE hComponent, 1009 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1010 OMX_IN OMX_U32 nPortIndex, 1011 OMX_IN OMX_PTR pAppPrivate, 1012 OMX_IN void* eglImage) 1013{ 1014 /* 1015 * Todo 1016 */ 1017 1018 return OMX_ErrorNotImplemented; 1019} 1020 1021OMX_ERRORTYPE ComponentBase::ComponentRoleEnum( 1022 OMX_IN OMX_HANDLETYPE hComponent, 1023 OMX_OUT OMX_U8 *cRole, 1024 OMX_IN OMX_U32 nIndex) 1025{ 1026 ComponentBase *cbase; 1027 1028 if (!hComponent) 1029 return OMX_ErrorBadParameter; 1030 1031 cbase = static_cast<ComponentBase *> 1032 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1033 if (!cbase) 1034 return OMX_ErrorBadParameter; 1035 1036 return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex); 1037} 1038 1039OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum( 1040 OMX_IN OMX_HANDLETYPE hComponent, 1041 OMX_OUT OMX_U8 *cRole, 1042 OMX_IN OMX_U32 nIndex) 1043{ 1044 if (hComponent != (OMX_HANDLETYPE *)this->handle) 1045 return OMX_ErrorBadParameter; 1046 1047 if (nIndex > nr_roles) 1048 return OMX_ErrorBadParameter; 1049 1050 strncpy((char *)cRole, (const char *)roles[nIndex], 1051 OMX_MAX_STRINGNAME_SIZE); 1052 return OMX_ErrorNone; 1053} 1054 1055/* implement CmdHandlerInterface */ 1056void ComponentBase::CmdHandler(struct cmd_s *cmd) 1057{ 1058 switch (cmd->cmd) { 1059 case OMX_CommandStateSet: { 1060 OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1; 1061 1062 TransState(transition); 1063 break; 1064 } 1065 case OMX_CommandFlush: 1066 /* 1067 * Todo 1068 */ 1069 break; 1070 case OMX_CommandPortDisable: 1071 /* 1072 * Todo 1073 */ 1074 break; 1075 case OMX_CommandPortEnable: 1076 /* 1077 * Todo 1078 */ 1079 break; 1080 case OMX_CommandMarkBuffer: 1081 /* 1082 * Todo 1083 */ 1084 break; 1085 } /* switch */ 1086} 1087 1088/* 1089 * SendCommand:OMX_CommandStateSet 1090 * called in CmdHandler or called in other parts of component for reporting 1091 * internal error (OMX_StateInvalid). 1092 */ 1093/* 1094 * Todo 1095 * Resource Management (OMX_StateWaitForResources) 1096 * for now, we never notify OMX_ErrorInsufficientResources, 1097 * so IL client doesn't try to set component' state OMX_StateWaitForResources 1098 */ 1099void ComponentBase::TransState(OMX_STATETYPE transition) 1100{ 1101 OMX_STATETYPE current = this->state; 1102 OMX_EVENTTYPE event; 1103 OMX_U32 data1; 1104 OMX_ERRORTYPE ret; 1105 1106 LOGD("current state = %d, transition state = %d\n", current, transition); 1107 1108 /* same state */ 1109 if (current == transition) { 1110 ret = OMX_ErrorSameState; 1111 goto notify_event; 1112 } 1113 1114 /* invalid state */ 1115 if (current == OMX_StateInvalid) { 1116 ret = OMX_ErrorInvalidState; 1117 goto notify_event; 1118 } 1119 1120 if (transition == OMX_StateLoaded) 1121 ret = TransStateToLoaded(current); 1122 else if (transition == OMX_StateIdle) 1123 ret = TransStateToIdle(current); 1124 else if (transition == OMX_StateExecuting) 1125 ret = TransStateToExecuting(current); 1126 else if (transition == OMX_StatePause) 1127 ret = TransStateToPause(current); 1128 else if (transition == OMX_StateInvalid) 1129 ret = TransStateToInvalid(current); 1130 else if (transition == OMX_StateWaitForResources) 1131 ret = TransStateToWaitForResources(current); 1132 else 1133 ret = OMX_ErrorIncorrectStateTransition; 1134 1135notify_event: 1136 if (ret == OMX_ErrorNone) { 1137 event = OMX_EventCmdComplete; 1138 data1 = transition; 1139 1140 state = transition; 1141 LOGD("transition from %d to %d completed\n", current, transition); 1142 } 1143 else { 1144 event = OMX_EventError; 1145 data1 = ret; 1146 1147 if (transition == OMX_StateInvalid) { 1148 state = transition; 1149 LOGD("transition from %d to %d completed\n", current, transition); 1150 } 1151 } 1152 1153 callbacks->EventHandler(handle, appdata, event, data1, 0, NULL); 1154 1155 /* WaitForResources workaround */ 1156 if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources) 1157 callbacks->EventHandler(handle, appdata, 1158 OMX_EventResourcesAcquired, 0, 0, NULL); 1159} 1160 1161inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current) 1162{ 1163 OMX_ERRORTYPE ret; 1164 1165 if (current == OMX_StateIdle) { 1166 /* 1167 * Todo 1168 * 1. waits for completion of deallocation on each port 1169 * wokeup by FreeBuffer() 1170 * 2. deinitialize buffer process work 1171 * 3. deinitialize component's internal processor 1172 * (ex. deinitialize sw/hw codec) 1173 */ 1174 ret = OMX_ErrorNone; 1175 } 1176 else if (current == OMX_StateWaitForResources) { 1177 LOGE("state transition's requested from WaitForResources to " 1178 "Loaded\n"); 1179 1180 /* 1181 * from WaitForResources to Loaded considered from Loaded to Loaded. 1182 * do nothing 1183 */ 1184 1185 ret = OMX_ErrorNone; 1186 } 1187 else 1188 ret = OMX_ErrorIncorrectStateOperation; 1189 1190 return ret; 1191} 1192 1193inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current) 1194{ 1195 OMX_ERRORTYPE ret; 1196 1197 if (current == OMX_StateLoaded) { 1198 /* 1199 * Todo 1200 * 1. waits for completion of allocation on each port. 1201 * wokeup by Allocate/UseBuffer() 1202 * 2. initialize buffer process work. 1203 * 3. initialize component's internal processor. 1204 * (ex. initialize sw/hw codec) 1205 */ 1206 ret = OMX_ErrorNone; 1207 } 1208 else if (current == OMX_StateExecuting) { 1209 /* 1210 * Todo 1211 * 1. returns all buffers to thier suppliers. 1212 * call Fill/EmptyThisBuffer() for all ports 1213 * 2. stop buffer process work 1214 * 3. stop component's internal processor 1215 */ 1216 ret = OMX_ErrorNone; 1217 } 1218 else if (current == OMX_StatePause) { 1219 1220 /* same as Executing to Idle */ 1221 1222 ret = OMX_ErrorNone; 1223 } 1224 else if (current == OMX_StateWaitForResources) { 1225 LOGE("state transition's requested from WaitForResources to Idle\n"); 1226 1227 /* same as Loaded to Idle BUT DO NOTHING for now */ 1228 1229 ret = OMX_ErrorNone; 1230 } 1231 else 1232 ret = OMX_ErrorIncorrectStateOperation; 1233 1234 return ret; 1235} 1236 1237inline OMX_ERRORTYPE 1238ComponentBase::TransStateToExecuting(OMX_STATETYPE current) 1239{ 1240 OMX_ERRORTYPE ret; 1241 1242 if (current == OMX_StateIdle) { 1243 /* 1244 * Todo 1245 * 1. start component's internal processor 1246 * 2. start processing buffers on each port 1247 */ 1248 ret = OMX_ErrorNone; 1249 } 1250 else if (current == OMX_StatePause) { 1251 /* 1252 * Todo 1253 * 1. resume buffer process woraek 1254 * 2. resume component's internal processor 1255 */ 1256 ret = OMX_ErrorNone; 1257 } 1258 else 1259 ret = OMX_ErrorIncorrectStateOperation; 1260 1261 return ret; 1262} 1263 1264inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current) 1265{ 1266 OMX_ERRORTYPE ret; 1267 1268 if (current == OMX_StateIdle) { 1269 /* 1270 * same as Idle to Executing, 1271 * except for not starting buffer processing and internal processor 1272 */ 1273 ret = OMX_ErrorNone; 1274 } 1275 else if (current == OMX_StateExecuting) { 1276 /* 1277 * Todo 1278 * 1. pause buffer process work 1279 * 2. pause component's internal processor 1280 */ 1281 ret = OMX_ErrorNone; 1282 } 1283 else 1284 ret = OMX_ErrorIncorrectStateOperation; 1285 1286 return ret; 1287} 1288 1289inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current) 1290{ 1291 OMX_ERRORTYPE ret = OMX_ErrorInvalidState; 1292 1293 /* 1294 * Todo 1295 * graceful escape 1296 */ 1297 1298 return ret; 1299} 1300 1301inline OMX_ERRORTYPE 1302ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current) 1303{ 1304 OMX_ERRORTYPE ret; 1305 1306 if (current == OMX_StateLoaded) { 1307 LOGE("state transition's requested from Loaded to WaitForResources\n"); 1308 ret = OMX_ErrorNone; 1309 } 1310 else 1311 ret = OMX_ErrorIncorrectStateOperation; 1312 1313 return ret; 1314} 1315 1316/* end of component methods & helpers */ 1317 1318/* 1319 * omx header manipuation 1320 */ 1321void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size) 1322{ 1323 OMX_U32 *nsize; 1324 OMX_VERSIONTYPE *nversion; 1325 1326 if (!type) 1327 return; 1328 1329 nsize = (OMX_U32 *)type; 1330 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 1331 1332 *nsize = sizeof(size); 1333 nversion->nVersion = OMX_SPEC_VERSION; 1334} 1335 1336OMX_BOOL ComponentBase::CheckTypeHeader(OMX_PTR type, OMX_U32 size) 1337{ 1338 OMX_U32 *nsize; 1339 OMX_VERSIONTYPE *nversion; 1340 OMX_U8 mismatch = 0; 1341 1342 if (!type) 1343 return OMX_FALSE; 1344 1345 nsize = (OMX_U32 *)type; 1346 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 1347 1348 mismatch = (*nsize != sizeof(size)) ? 1 : 0; 1349 mismatch |= (nversion->nVersion != OMX_SPEC_VERSION) ? 1 : 0; 1350 1351 if (mismatch) 1352 return OMX_TRUE; 1353 else 1354 return OMX_FALSE; 1355} 1356 1357/* end of ComponentBase */ 1358