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