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