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