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