componentbase.cpp revision d2d7fc5745af2532cd7aaf9bd88148cf29501900
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 /* preventing clients from setting OMX_PORT_PARAM_TYPE */ 572 ret = OMX_ErrorUnsupportedIndex; 573 break; 574 case OMX_IndexParamPortDefinition: { 575 OMX_PARAM_PORTDEFINITIONTYPE *p = 576 (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; 577 OMX_U32 index = p->nPortIndex; 578 PortBase *port = NULL; 579 580 ret = CheckTypeHeader(p, sizeof(*p)); 581 if (ret != OMX_ErrorNone) 582 return ret; 583 584 if (index < nr_ports) 585 port = ports[index]; 586 587 if (!port) 588 return OMX_ErrorBadParameter; 589 590 if (port->IsEnabled()) { 591 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 592 return OMX_ErrorIncorrectStateOperation; 593 } 594 595 port->SetPortParam(p); 596 break; 597 } 598 case OMX_IndexParamAudioPortFormat: { 599 OMX_AUDIO_PARAM_PORTFORMATTYPE *p = 600 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure; 601 OMX_U32 index = p->nPortIndex; 602 PortBase *port = NULL; 603 604 ret = CheckTypeHeader(p, sizeof(*p)); 605 if (ret != OMX_ErrorNone) 606 return ret; 607 608 if (index < nr_ports) 609 port = ports[index]; 610 611 if (!port) 612 return OMX_ErrorBadParameter; 613 614 if (port->IsEnabled()) { 615 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 616 return OMX_ErrorIncorrectStateOperation; 617 } 618 619 port->SetAudioPortParam(p); 620 break; 621 } 622 case OMX_IndexParamCompBufferSupplier: 623 /* 624 * Todo 625 */ 626 627 ret = OMX_ErrorUnsupportedIndex; 628 break; 629 case OMX_IndexParamStandardComponentRole: { 630 OMX_PARAM_COMPONENTROLETYPE *p = 631 (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; 632 633 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 634 return OMX_ErrorIncorrectStateOperation; 635 636 ret = CheckTypeHeader(p, sizeof(*p)); 637 if (ret != OMX_ErrorNone) 638 return ret; 639 640 ret = SetWorkingRole((OMX_STRING)p->cRole); 641 if (ret != OMX_ErrorNone) 642 return ret; 643 644 if (ports) 645 FreePorts(); 646 647 ret = ApplyWorkingRole(); 648 if (ret != OMX_ErrorNone) { 649 SetWorkingRole(NULL); 650 return ret; 651 } 652 break; 653 } 654 default: 655 ret = ComponentSetParameter(nIndex, pComponentParameterStructure); 656 } /* switch */ 657 658 return ret; 659} 660 661OMX_ERRORTYPE ComponentBase::GetConfig( 662 OMX_IN OMX_HANDLETYPE hComponent, 663 OMX_IN OMX_INDEXTYPE nIndex, 664 OMX_INOUT OMX_PTR pComponentConfigStructure) 665{ 666 ComponentBase *cbase; 667 668 if (!hComponent) 669 return OMX_ErrorBadParameter; 670 671 cbase = static_cast<ComponentBase *> 672 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 673 if (!cbase) 674 return OMX_ErrorBadParameter; 675 676 return cbase->CBaseGetConfig(hComponent, nIndex, 677 pComponentConfigStructure); 678} 679 680OMX_ERRORTYPE ComponentBase::CBaseGetConfig( 681 OMX_IN OMX_HANDLETYPE hComponent, 682 OMX_IN OMX_INDEXTYPE nIndex, 683 OMX_INOUT OMX_PTR pComponentConfigStructure) 684{ 685 OMX_ERRORTYPE ret; 686 687 if (hComponent != handle) 688 return OMX_ErrorBadParameter; 689 690 switch (nIndex) { 691 default: 692 ret = ComponentGetConfig(nIndex, pComponentConfigStructure); 693 } 694 695 return ret; 696} 697 698OMX_ERRORTYPE ComponentBase::SetConfig( 699 OMX_IN OMX_HANDLETYPE hComponent, 700 OMX_IN OMX_INDEXTYPE nIndex, 701 OMX_IN OMX_PTR pComponentConfigStructure) 702{ 703 ComponentBase *cbase; 704 705 if (!hComponent) 706 return OMX_ErrorBadParameter; 707 708 cbase = static_cast<ComponentBase *> 709 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 710 if (!cbase) 711 return OMX_ErrorBadParameter; 712 713 return cbase->CBaseSetConfig(hComponent, nIndex, 714 pComponentConfigStructure); 715} 716 717OMX_ERRORTYPE ComponentBase::CBaseSetConfig( 718 OMX_IN OMX_HANDLETYPE hComponent, 719 OMX_IN OMX_INDEXTYPE nIndex, 720 OMX_IN OMX_PTR pComponentConfigStructure) 721{ 722 OMX_ERRORTYPE ret; 723 724 if (hComponent != handle) 725 return OMX_ErrorBadParameter; 726 727 switch (nIndex) { 728 default: 729 ret = ComponentSetConfig(nIndex, pComponentConfigStructure); 730 } 731 732 return ret; 733} 734 735OMX_ERRORTYPE ComponentBase::GetExtensionIndex( 736 OMX_IN OMX_HANDLETYPE hComponent, 737 OMX_IN OMX_STRING cParameterName, 738 OMX_OUT OMX_INDEXTYPE* pIndexType) 739{ 740 ComponentBase *cbase; 741 742 if (!hComponent) 743 return OMX_ErrorBadParameter; 744 745 cbase = static_cast<ComponentBase *> 746 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 747 if (!cbase) 748 return OMX_ErrorBadParameter; 749 750 return cbase->CBaseGetExtensionIndex(hComponent, cParameterName, 751 pIndexType); 752} 753 754OMX_ERRORTYPE ComponentBase::CBaseGetExtensionIndex( 755 OMX_IN OMX_HANDLETYPE hComponent, 756 OMX_IN OMX_STRING cParameterName, 757 OMX_OUT OMX_INDEXTYPE* pIndexType) 758{ 759 /* 760 * Todo 761 */ 762 763 return OMX_ErrorNotImplemented; 764} 765 766OMX_ERRORTYPE ComponentBase::GetState( 767 OMX_IN OMX_HANDLETYPE hComponent, 768 OMX_OUT OMX_STATETYPE* pState) 769{ 770 ComponentBase *cbase; 771 772 if (!hComponent) 773 return OMX_ErrorBadParameter; 774 775 cbase = static_cast<ComponentBase *> 776 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 777 if (!cbase) 778 return OMX_ErrorBadParameter; 779 780 return cbase->CBaseGetState(hComponent, pState); 781} 782 783OMX_ERRORTYPE ComponentBase::CBaseGetState( 784 OMX_IN OMX_HANDLETYPE hComponent, 785 OMX_OUT OMX_STATETYPE* pState) 786{ 787 if (hComponent != handle) 788 return OMX_ErrorBadParameter; 789 790 *pState = state; 791 return OMX_ErrorNone; 792} 793 794OMX_ERRORTYPE ComponentBase::ComponentTunnelRequest( 795 OMX_IN OMX_HANDLETYPE hComponent, 796 OMX_IN OMX_U32 nPort, 797 OMX_IN OMX_HANDLETYPE hTunneledComponent, 798 OMX_IN OMX_U32 nTunneledPort, 799 OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup) 800{ 801 ComponentBase *cbase; 802 803 if (!hComponent) 804 return OMX_ErrorBadParameter; 805 806 cbase = static_cast<ComponentBase *> 807 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 808 if (!cbase) 809 return OMX_ErrorBadParameter; 810 811 return cbase->CBaseComponentTunnelRequest(hComponent, nPort, 812 hTunneledComponent, 813 nTunneledPort, pTunnelSetup); 814} 815 816OMX_ERRORTYPE ComponentBase::CBaseComponentTunnelRequest( 817 OMX_IN OMX_HANDLETYPE hComp, 818 OMX_IN OMX_U32 nPort, 819 OMX_IN OMX_HANDLETYPE hTunneledComp, 820 OMX_IN OMX_U32 nTunneledPort, 821 OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup) 822{ 823 /* 824 * Todo 825 */ 826 827 return OMX_ErrorNotImplemented; 828} 829 830OMX_ERRORTYPE ComponentBase::UseBuffer( 831 OMX_IN OMX_HANDLETYPE hComponent, 832 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 833 OMX_IN OMX_U32 nPortIndex, 834 OMX_IN OMX_PTR pAppPrivate, 835 OMX_IN OMX_U32 nSizeBytes, 836 OMX_IN OMX_U8 *pBuffer) 837{ 838 ComponentBase *cbase; 839 840 if (!hComponent) 841 return OMX_ErrorBadParameter; 842 843 cbase = static_cast<ComponentBase *> 844 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 845 if (!cbase) 846 return OMX_ErrorBadParameter; 847 848 return cbase->CBaseUseBuffer(hComponent, ppBufferHdr, nPortIndex, 849 pAppPrivate, nSizeBytes, pBuffer); 850} 851 852OMX_ERRORTYPE ComponentBase::CBaseUseBuffer( 853 OMX_IN OMX_HANDLETYPE hComponent, 854 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 855 OMX_IN OMX_U32 nPortIndex, 856 OMX_IN OMX_PTR pAppPrivate, 857 OMX_IN OMX_U32 nSizeBytes, 858 OMX_IN OMX_U8 *pBuffer) 859{ 860 PortBase *port = NULL; 861 OMX_ERRORTYPE ret; 862 863 if (hComponent != handle) 864 return OMX_ErrorBadParameter; 865 866 if (!ppBufferHdr) 867 return OMX_ErrorBadParameter; 868 *ppBufferHdr = NULL; 869 870 if (!pBuffer) 871 return OMX_ErrorBadParameter; 872 873 if (ports) 874 if (nPortIndex < nr_ports) 875 port = ports[nPortIndex]; 876 877 if (!port) 878 return OMX_ErrorBadParameter; 879 880 if (port->IsEnabled()) { 881 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 882 return OMX_ErrorIncorrectStateOperation; 883 } 884 885 return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, 886 pBuffer); 887} 888 889OMX_ERRORTYPE ComponentBase::AllocateBuffer( 890 OMX_IN OMX_HANDLETYPE hComponent, 891 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 892 OMX_IN OMX_U32 nPortIndex, 893 OMX_IN OMX_PTR pAppPrivate, 894 OMX_IN OMX_U32 nSizeBytes) 895{ 896 ComponentBase *cbase; 897 898 if (!hComponent) 899 return OMX_ErrorBadParameter; 900 901 cbase = static_cast<ComponentBase *> 902 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 903 if (!cbase) 904 return OMX_ErrorBadParameter; 905 906 return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex, 907 pAppPrivate, nSizeBytes); 908} 909 910OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer( 911 OMX_IN OMX_HANDLETYPE hComponent, 912 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 913 OMX_IN OMX_U32 nPortIndex, 914 OMX_IN OMX_PTR pAppPrivate, 915 OMX_IN OMX_U32 nSizeBytes) 916{ 917 PortBase *port = NULL; 918 OMX_ERRORTYPE ret; 919 920 if (hComponent != handle) 921 return OMX_ErrorBadParameter; 922 923 if (!ppBuffer) 924 return OMX_ErrorBadParameter; 925 *ppBuffer = NULL; 926 927 if (ports) 928 if (nPortIndex < nr_ports) 929 port = ports[nPortIndex]; 930 931 if (!port) 932 return OMX_ErrorBadParameter; 933 934 if (port->IsEnabled()) { 935 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 936 return OMX_ErrorIncorrectStateOperation; 937 } 938 939 return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes); 940} 941 942OMX_ERRORTYPE ComponentBase::FreeBuffer( 943 OMX_IN OMX_HANDLETYPE hComponent, 944 OMX_IN OMX_U32 nPortIndex, 945 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 946{ 947 ComponentBase *cbase; 948 949 if (!hComponent) 950 return OMX_ErrorBadParameter; 951 952 cbase = static_cast<ComponentBase *> 953 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 954 if (!cbase) 955 return OMX_ErrorBadParameter; 956 957 return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer); 958} 959 960OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer( 961 OMX_IN OMX_HANDLETYPE hComponent, 962 OMX_IN OMX_U32 nPortIndex, 963 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 964{ 965 PortBase *port = NULL; 966 OMX_ERRORTYPE ret; 967 968 if (hComponent != handle) 969 return OMX_ErrorBadParameter; 970 971 if (!pBuffer) 972 return OMX_ErrorBadParameter; 973 974 if (ports) 975 if (nPortIndex < nr_ports) 976 port = ports[nPortIndex]; 977 978 if (!port) 979 return OMX_ErrorBadParameter; 980 981 return port->FreeBuffer(nPortIndex, pBuffer); 982} 983 984OMX_ERRORTYPE ComponentBase::EmptyThisBuffer( 985 OMX_IN OMX_HANDLETYPE hComponent, 986 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 987{ 988 ComponentBase *cbase; 989 990 if (!hComponent) 991 return OMX_ErrorBadParameter; 992 993 cbase = static_cast<ComponentBase *> 994 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 995 if (!cbase) 996 return OMX_ErrorBadParameter; 997 998 return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer); 999} 1000 1001OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer( 1002 OMX_IN OMX_HANDLETYPE hComponent, 1003 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 1004{ 1005 PortBase *port = NULL; 1006 OMX_U32 port_index; 1007 OMX_ERRORTYPE ret; 1008 1009 if ((hComponent != handle) || !pBuffer) 1010 return OMX_ErrorBadParameter; 1011 1012 ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); 1013 if (ret != OMX_ErrorNone) 1014 return ret; 1015 1016 port_index = pBuffer->nInputPortIndex; 1017 if (port_index == (OMX_U32)-1) 1018 return OMX_ErrorBadParameter; 1019 1020 if (ports) 1021 if (port_index < nr_ports) 1022 port = ports[port_index]; 1023 1024 if (!port) 1025 return OMX_ErrorBadParameter; 1026 1027 if (pBuffer->pInputPortPrivate != port) 1028 return OMX_ErrorBadParameter; 1029 1030 if (port->IsEnabled()) { 1031 if (state != OMX_StateIdle && state != OMX_StateExecuting && 1032 state != OMX_StatePause) 1033 return OMX_ErrorIncorrectStateOperation; 1034 } 1035 1036 ret = port->PushThisBuffer(pBuffer); 1037 if (ret == OMX_ErrorNone) 1038 bufferwork->ScheduleWork(this); 1039 1040 return ret; 1041} 1042 1043OMX_ERRORTYPE ComponentBase::FillThisBuffer( 1044 OMX_IN OMX_HANDLETYPE hComponent, 1045 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 1046{ 1047 ComponentBase *cbase; 1048 1049 if (!hComponent) 1050 return OMX_ErrorBadParameter; 1051 1052 cbase = static_cast<ComponentBase *> 1053 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1054 if (!cbase) 1055 return OMX_ErrorBadParameter; 1056 1057 return cbase->CBaseFillThisBuffer(hComponent, pBuffer); 1058} 1059 1060OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer( 1061 OMX_IN OMX_HANDLETYPE hComponent, 1062 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 1063{ 1064 PortBase *port = NULL; 1065 OMX_U32 port_index; 1066 OMX_ERRORTYPE ret; 1067 1068 if ((hComponent != handle) || !pBuffer) 1069 return OMX_ErrorBadParameter; 1070 1071 ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); 1072 if (ret != OMX_ErrorNone) 1073 return ret; 1074 1075 port_index = pBuffer->nOutputPortIndex; 1076 if (port_index == (OMX_U32)-1) 1077 return OMX_ErrorBadParameter; 1078 1079 if (ports) 1080 if (port_index < nr_ports) 1081 port = ports[port_index]; 1082 1083 if (!port) 1084 return OMX_ErrorBadParameter; 1085 1086 if (pBuffer->pOutputPortPrivate != port) 1087 return OMX_ErrorBadParameter; 1088 1089 if (port->IsEnabled()) { 1090 if (state != OMX_StateIdle && state != OMX_StateExecuting && 1091 state != OMX_StatePause) 1092 return OMX_ErrorIncorrectStateOperation; 1093 } 1094 1095 ret = port->PushThisBuffer(pBuffer); 1096 if (ret == OMX_ErrorNone) 1097 bufferwork->ScheduleWork(this); 1098 1099 return ret; 1100} 1101 1102OMX_ERRORTYPE ComponentBase::SetCallbacks( 1103 OMX_IN OMX_HANDLETYPE hComponent, 1104 OMX_IN OMX_CALLBACKTYPE* pCallbacks, 1105 OMX_IN OMX_PTR pAppData) 1106{ 1107 ComponentBase *cbase; 1108 1109 if (!hComponent) 1110 return OMX_ErrorBadParameter; 1111 1112 cbase = static_cast<ComponentBase *> 1113 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1114 if (!cbase) 1115 return OMX_ErrorBadParameter; 1116 1117 return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData); 1118} 1119 1120OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks( 1121 OMX_IN OMX_HANDLETYPE hComponent, 1122 OMX_IN OMX_CALLBACKTYPE *pCallbacks, 1123 OMX_IN OMX_PTR pAppData) 1124{ 1125 if (hComponent != handle) 1126 return OMX_ErrorBadParameter; 1127 1128 appdata = pAppData; 1129 callbacks = pCallbacks; 1130 1131 return OMX_ErrorNone; 1132} 1133 1134OMX_ERRORTYPE ComponentBase::ComponentDeInit( 1135 OMX_IN OMX_HANDLETYPE hComponent) 1136{ 1137 ComponentBase *cbase; 1138 1139 if (!hComponent) 1140 return OMX_ErrorBadParameter; 1141 1142 cbase = static_cast<ComponentBase *> 1143 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1144 if (!cbase) 1145 return OMX_ErrorBadParameter; 1146 1147 return cbase->CBaseComponentDeInit(hComponent); 1148} 1149 1150OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit( 1151 OMX_IN OMX_HANDLETYPE hComponent) 1152{ 1153 /* 1154 * Todo 1155 */ 1156 1157 return OMX_ErrorNotImplemented; 1158} 1159 1160OMX_ERRORTYPE ComponentBase::UseEGLImage( 1161 OMX_IN OMX_HANDLETYPE hComponent, 1162 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1163 OMX_IN OMX_U32 nPortIndex, 1164 OMX_IN OMX_PTR pAppPrivate, 1165 OMX_IN void* eglImage) 1166{ 1167 ComponentBase *cbase; 1168 1169 if (!hComponent) 1170 return OMX_ErrorBadParameter; 1171 1172 cbase = static_cast<ComponentBase *> 1173 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1174 if (!cbase) 1175 return OMX_ErrorBadParameter; 1176 1177 return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex, 1178 pAppPrivate, eglImage); 1179} 1180 1181OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage( 1182 OMX_IN OMX_HANDLETYPE hComponent, 1183 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1184 OMX_IN OMX_U32 nPortIndex, 1185 OMX_IN OMX_PTR pAppPrivate, 1186 OMX_IN void* eglImage) 1187{ 1188 /* 1189 * Todo 1190 */ 1191 1192 return OMX_ErrorNotImplemented; 1193} 1194 1195OMX_ERRORTYPE ComponentBase::ComponentRoleEnum( 1196 OMX_IN OMX_HANDLETYPE hComponent, 1197 OMX_OUT OMX_U8 *cRole, 1198 OMX_IN OMX_U32 nIndex) 1199{ 1200 ComponentBase *cbase; 1201 1202 if (!hComponent) 1203 return OMX_ErrorBadParameter; 1204 1205 cbase = static_cast<ComponentBase *> 1206 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1207 if (!cbase) 1208 return OMX_ErrorBadParameter; 1209 1210 return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex); 1211} 1212 1213OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum( 1214 OMX_IN OMX_HANDLETYPE hComponent, 1215 OMX_OUT OMX_U8 *cRole, 1216 OMX_IN OMX_U32 nIndex) 1217{ 1218 if (hComponent != (OMX_HANDLETYPE *)this->handle) 1219 return OMX_ErrorBadParameter; 1220 1221 if (nIndex > nr_roles) 1222 return OMX_ErrorBadParameter; 1223 1224 strncpy((char *)cRole, (const char *)roles[nIndex], 1225 OMX_MAX_STRINGNAME_SIZE); 1226 return OMX_ErrorNone; 1227} 1228 1229/* implement CmdHandlerInterface */ 1230void ComponentBase::CmdHandler(struct cmd_s *cmd) 1231{ 1232 switch (cmd->cmd) { 1233 case OMX_CommandStateSet: { 1234 OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1; 1235 1236 TransState(transition); 1237 break; 1238 } 1239 case OMX_CommandFlush: 1240 /* 1241 * Todo 1242 */ 1243 break; 1244 case OMX_CommandPortDisable: 1245 /* 1246 * Todo 1247 */ 1248 break; 1249 case OMX_CommandPortEnable: 1250 /* 1251 * Todo 1252 */ 1253 break; 1254 case OMX_CommandMarkBuffer: 1255 OMX_U32 port_index = (OMX_U32)cmd->param1; 1256 OMX_MARKTYPE *mark = (OMX_MARKTYPE *)cmd->cmddata; 1257 1258 PushThisMark(port_index, mark); 1259 break; 1260 } /* switch */ 1261} 1262 1263/* 1264 * SendCommand:OMX_CommandStateSet 1265 * called in CmdHandler or called in other parts of component for reporting 1266 * internal error (OMX_StateInvalid). 1267 */ 1268/* 1269 * Todo 1270 * Resource Management (OMX_StateWaitForResources) 1271 * for now, we never notify OMX_ErrorInsufficientResources, 1272 * so IL client doesn't try to set component' state OMX_StateWaitForResources 1273 */ 1274static const char *state_name[OMX_StateWaitForResources + 1] = { 1275 "OMX_StateInvalid", 1276 "OMX_StateLoaded", 1277 "OMX_StateIdle", 1278 "OMX_StateExecuting", 1279 "OMX_StatePause", 1280 "OMX_StateWaitForResources", 1281}; 1282 1283static inline const char *GetStateName(OMX_STATETYPE state) 1284{ 1285 if (state > OMX_StateWaitForResources) 1286 return "UnKnown"; 1287 1288 return state_name[state]; 1289} 1290 1291void ComponentBase::TransState(OMX_STATETYPE transition) 1292{ 1293 OMX_STATETYPE current = this->state; 1294 OMX_EVENTTYPE event; 1295 OMX_U32 data1, data2; 1296 OMX_ERRORTYPE ret; 1297 1298 LOGD("current state = %s, transition state = %s\n", 1299 GetStateName(current), GetStateName(transition)); 1300 1301 /* same state */ 1302 if (current == transition) { 1303 ret = OMX_ErrorSameState; 1304 goto notify_event; 1305 } 1306 1307 /* invalid state */ 1308 if (current == OMX_StateInvalid) { 1309 ret = OMX_ErrorInvalidState; 1310 goto notify_event; 1311 } 1312 1313 if (transition == OMX_StateLoaded) 1314 ret = TransStateToLoaded(current); 1315 else if (transition == OMX_StateIdle) 1316 ret = TransStateToIdle(current); 1317 else if (transition == OMX_StateExecuting) 1318 ret = TransStateToExecuting(current); 1319 else if (transition == OMX_StatePause) 1320 ret = TransStateToPause(current); 1321 else if (transition == OMX_StateInvalid) 1322 ret = TransStateToInvalid(current); 1323 else if (transition == OMX_StateWaitForResources) 1324 ret = TransStateToWaitForResources(current); 1325 else 1326 ret = OMX_ErrorIncorrectStateTransition; 1327 1328notify_event: 1329 if (ret == OMX_ErrorNone) { 1330 event = OMX_EventCmdComplete; 1331 data1 = OMX_CommandStateSet; 1332 data2 = transition; 1333 1334 state = transition; 1335 LOGD("transition from %s to %s completed\n", 1336 GetStateName(current), GetStateName(transition)); 1337 } 1338 else { 1339 event = OMX_EventError; 1340 data1 = ret; 1341 data2 = 0; 1342 1343 if (transition == OMX_StateInvalid) { 1344 state = transition; 1345 LOGD("transition from %s to %s completed\n", 1346 GetStateName(current), GetStateName(transition)); 1347 } 1348 } 1349 1350 callbacks->EventHandler(handle, appdata, event, data1, data2, NULL); 1351 1352 /* WaitForResources workaround */ 1353 if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources) 1354 callbacks->EventHandler(handle, appdata, 1355 OMX_EventResourcesAcquired, 0, 0, NULL); 1356} 1357 1358inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current) 1359{ 1360 OMX_ERRORTYPE ret; 1361 1362 if (current == OMX_StateIdle) { 1363 /* 1364 * Todo 1365 * 1. waits for completion of deallocation on each port 1366 * wokeup by FreeBuffer() 1367 * 2. deinitialize buffer process work 1368 * 3. deinitialize component's internal processor 1369 * (ex. deinitialize sw/hw codec) 1370 */ 1371 OMX_U32 i; 1372 1373 for (i = 0; i < nr_ports; i++) 1374 ports[i]->WaitPortBufferCompletion(); 1375 1376 ret = OMX_ErrorNone; 1377 } 1378 else if (current == OMX_StateWaitForResources) { 1379 LOGE("state transition's requested from WaitForResources to " 1380 "Loaded\n"); 1381 1382 /* 1383 * from WaitForResources to Loaded considered from Loaded to Loaded. 1384 * do nothing 1385 */ 1386 1387 ret = OMX_ErrorNone; 1388 } 1389 else 1390 ret = OMX_ErrorIncorrectStateOperation; 1391 1392 return ret; 1393} 1394 1395inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current) 1396{ 1397 OMX_ERRORTYPE ret; 1398 1399 if (current == OMX_StateLoaded) { 1400 /* 1401 * Todo 1402 * 1. waits for completion of allocation on each port. 1403 * wokeup by Allocate/UseBuffer() 1404 * 2. initialize buffer process work. 1405 * 3. initialize component's internal processor. 1406 * (ex. initialize sw/hw codec) 1407 */ 1408 OMX_U32 i; 1409 1410 for (i = 0; i < nr_ports; i++) 1411 ports[i]->WaitPortBufferCompletion(); 1412 1413 ret = OMX_ErrorNone; 1414 } 1415 else if (current == OMX_StateExecuting) { 1416 /* 1417 * Todo 1418 * 1. returns all buffers to thier suppliers. ! 1419 * call Fill/EmptyBufferDone() for all ports 1420 * 2. stop buffer process work ! 1421 * 3. stop component's internal processor 1422 */ 1423 OMX_U32 i; 1424 1425 pthread_mutex_lock(&ports_block); 1426 for (i = 0; i < nr_ports; i++) { 1427 ports[i]->FlushPort(); 1428 } 1429 pthread_mutex_unlock(&ports_block); 1430 1431 bufferwork->StopWork(); 1432 1433 ret = OMX_ErrorNone; 1434 } 1435 else if (current == OMX_StatePause) { 1436 /* 1437 * Todo 1438 * 1. returns all buffers to thier suppliers. ! 1439 * call Fill/EmptyBufferDone() for all ports 1440 * 2. discard queued work, stop buffer process work ! 1441 * 3. stop component's internal processor 1442 */ 1443 OMX_U32 i; 1444 1445 pthread_mutex_lock(&ports_block); 1446 for (i = 0; i < nr_ports; i++) { 1447 ports[i]->FlushPort(); 1448 } 1449 pthread_mutex_unlock(&ports_block); 1450 1451 bufferwork->CancelScheduledWork(this); 1452 bufferwork->StopWork(); 1453 1454 ret = OMX_ErrorNone; 1455 } 1456 else if (current == OMX_StateWaitForResources) { 1457 LOGE("state transition's requested from WaitForResources to Idle\n"); 1458 1459 /* same as Loaded to Idle BUT DO NOTHING for now */ 1460 1461 ret = OMX_ErrorNone; 1462 } 1463 else 1464 ret = OMX_ErrorIncorrectStateOperation; 1465 1466 return ret; 1467} 1468 1469inline OMX_ERRORTYPE 1470ComponentBase::TransStateToExecuting(OMX_STATETYPE current) 1471{ 1472 OMX_ERRORTYPE ret; 1473 1474 if (current == OMX_StateIdle) { 1475 /* 1476 * Todo 1477 * 1. start component's internal processor 1478 * 2. start processing buffers on each port ! 1479 */ 1480 1481 pthread_mutex_lock(&executing_lock); 1482 executing = true; 1483 pthread_mutex_unlock(&executing_lock); 1484 1485 bufferwork->StartWork(); 1486 ret = OMX_ErrorNone; 1487 } 1488 else if (current == OMX_StatePause) { 1489 /* 1490 * Todo 1491 * 1. resume component's internal processor 1492 * 2. resume buffer process work ! 1493 */ 1494 1495 pthread_mutex_lock(&executing_lock); 1496 executing = true; 1497 pthread_cond_signal(&executing_wait); 1498 pthread_mutex_unlock(&executing_lock); 1499 1500 ret = OMX_ErrorNone; 1501 } 1502 else 1503 ret = OMX_ErrorIncorrectStateOperation; 1504 1505 return ret; 1506} 1507 1508inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current) 1509{ 1510 OMX_ERRORTYPE ret; 1511 1512 if (current == OMX_StateIdle) { 1513 /* 1514 * Todo 1515 * 1. start(paused) component's internal processor 1516 * 2. start(paused) processing buffers on each port ! 1517 */ 1518 1519 /* turn off executing flag */ 1520 pthread_mutex_lock(&executing_lock); 1521 executing = false; 1522 pthread_mutex_unlock(&executing_lock); 1523 1524 bufferwork->StartWork(); 1525 1526 ret = OMX_ErrorNone; 1527 } 1528 else if (current == OMX_StateExecuting) { 1529 /* 1530 * Todo 1531 * 1. pause buffer process work ! 1532 * 2. pause component's internal processor 1533 */ 1534 1535 pthread_mutex_lock(&executing_lock); 1536 executing = false; 1537 pthread_mutex_unlock(&executing_lock); 1538 1539 ret = OMX_ErrorNone; 1540 } 1541 else 1542 ret = OMX_ErrorIncorrectStateOperation; 1543 1544 return ret; 1545} 1546 1547inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current) 1548{ 1549 OMX_ERRORTYPE ret = OMX_ErrorInvalidState; 1550 1551 /* 1552 * Todo 1553 * graceful escape 1554 */ 1555 1556 return ret; 1557} 1558 1559inline OMX_ERRORTYPE 1560ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current) 1561{ 1562 OMX_ERRORTYPE ret; 1563 1564 if (current == OMX_StateLoaded) { 1565 LOGE("state transition's requested from Loaded to WaitForResources\n"); 1566 ret = OMX_ErrorNone; 1567 } 1568 else 1569 ret = OMX_ErrorIncorrectStateOperation; 1570 1571 return ret; 1572} 1573 1574/* mark buffer */ 1575void ComponentBase::PushThisMark(OMX_U32 port_index, OMX_MARKTYPE *mark) 1576{ 1577 PortBase *port = NULL; 1578 OMX_EVENTTYPE event; 1579 OMX_U32 data1, data2; 1580 OMX_ERRORTYPE ret; 1581 1582 if (ports) 1583 if (port_index < nr_ports) 1584 port = ports[port_index]; 1585 1586 if (!port) { 1587 ret = OMX_ErrorBadPortIndex; 1588 goto notify_event; 1589 } 1590 1591 ret = port->PushMark(mark); 1592 if (ret != OMX_ErrorNone) { 1593 /* don't report OMX_ErrorInsufficientResources */ 1594 ret = OMX_ErrorUndefined; 1595 goto notify_event; 1596 } 1597 1598notify_event: 1599 if (ret == OMX_ErrorNone) { 1600 event = OMX_EventCmdComplete; 1601 data1 = OMX_CommandMarkBuffer; 1602 data2 = port_index; 1603 } 1604 else { 1605 event = OMX_EventError; 1606 data1 = ret; 1607 data2 = 0; 1608 } 1609 1610 callbacks->EventHandler(handle, appdata, event, data1, data2, NULL); 1611} 1612 1613/* set working role */ 1614OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role) 1615{ 1616 OMX_U32 i; 1617 1618 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1619 return OMX_ErrorIncorrectStateOperation; 1620 1621 if (!role) { 1622 working_role = NULL; 1623 return OMX_ErrorNone; 1624 } 1625 1626 for (i = 0; i < nr_roles; i++) { 1627 if (!strcmp((char *)&roles[i][0], role)) { 1628 working_role = (OMX_STRING)&roles[i][0]; 1629 return OMX_ErrorNone; 1630 } 1631 } 1632 1633 LOGE("cannot find %s role in %s\n", role, name); 1634 return OMX_ErrorBadParameter; 1635} 1636 1637/* apply a working role for a component having multiple roles */ 1638OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void) 1639{ 1640 OMX_U32 i; 1641 OMX_ERRORTYPE ret; 1642 1643 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1644 return OMX_ErrorIncorrectStateOperation; 1645 1646 if (!working_role) 1647 return OMX_ErrorBadParameter; 1648 1649 if (!callbacks || !appdata) 1650 return OMX_ErrorBadParameter; 1651 1652 ret = AllocatePorts(); 1653 if (ret != OMX_ErrorNone) { 1654 LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret); 1655 return ret; 1656 } 1657 1658 /* now we can access ports */ 1659 for (i = 0; i < nr_ports; i++) { 1660 ports[i]->SetOwner(handle); 1661 ports[i]->SetCallbacks(handle, callbacks, appdata); 1662 } 1663 1664 return OMX_ErrorNone; 1665} 1666 1667OMX_ERRORTYPE ComponentBase::AllocatePorts(void) 1668{ 1669 OMX_ERRORTYPE ret; 1670 1671 if (ports) 1672 return OMX_ErrorBadParameter; 1673 1674 ret = ComponentAllocatePorts(); 1675 if (ret != OMX_ErrorNone) { 1676 LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n", 1677 name, ret); 1678 return ret; 1679 } 1680 1681 return OMX_ErrorNone; 1682} 1683 1684/* called int FreeHandle() */ 1685OMX_ERRORTYPE ComponentBase::FreePorts(void) 1686{ 1687 if (ports) { 1688 OMX_U32 i, this_nr_ports = this->nr_ports; 1689 1690 for (i = 0; i < this_nr_ports; i++) { 1691 if (ports[i]) { 1692 delete ports[i]; 1693 ports[i] = NULL; 1694 } 1695 } 1696 delete []ports; 1697 ports = NULL; 1698 } 1699 1700 return OMX_ErrorNone; 1701} 1702 1703/* buffer processing */ 1704/* implement WorkableInterface */ 1705void ComponentBase::Work(void) 1706{ 1707 OMX_BUFFERHEADERTYPE *buffers[nr_ports]; 1708 OMX_U32 i; 1709 bool avail = false; 1710 1711 pthread_mutex_lock(&executing_lock); 1712 if (!executing) 1713 pthread_cond_wait(&executing_wait, &executing_lock); 1714 pthread_mutex_unlock(&executing_lock); 1715 1716 pthread_mutex_lock(&ports_block); 1717 1718 avail = IsAllBufferAvailable(); 1719 if (avail) { 1720 for (i = 0; i < nr_ports; i++) 1721 buffers[i] = ports[i]->PopBuffer(); 1722 1723 ComponentProcessBuffers(buffers, nr_ports); 1724 1725 for (i = 0; i < nr_ports; i++) { 1726 if (ports[i]->GetPortDirection() == OMX_DirInput) { 1727 bool is_sink_component = true; 1728 OMX_U32 j; 1729 1730 for (j = 0; j < nr_ports; j++) { 1731 if (j == i) 1732 continue; 1733 1734 if (ports[j]->GetPortDirection() == OMX_DirOutput) { 1735 if (buffers[i]->nFlags == OMX_BUFFERFLAG_EOS) 1736 buffers[j]->nFlags = buffers[i]->nFlags; 1737 is_sink_component = false; 1738 } 1739 } 1740 1741 if (is_sink_component) { 1742 if (buffers[i]->nFlags == OMX_BUFFERFLAG_EOS) { 1743 callbacks->EventHandler(handle, appdata, 1744 OMX_EventBufferFlag, 1745 i, buffers[i]->nFlags, NULL); 1746 } 1747 } 1748 } 1749 else if (ports[i]->GetPortDirection() == OMX_DirOutput) { 1750 if (buffers[i]->nFlags == OMX_BUFFERFLAG_EOS) { 1751 callbacks->EventHandler(handle, appdata, 1752 OMX_EventBufferFlag, 1753 i, buffers[i]->nFlags, NULL); 1754 } 1755 } 1756 else { 1757 LOGE("%s(): fatal error unknown port direction (0x%08x)\n", 1758 __func__, ports[i]->GetPortDirection()); 1759 } 1760 } 1761 1762 for (i = 0; i < nr_ports; i++) 1763 ports[i]->ReturnThisBuffer(buffers[i]); 1764 } 1765 ScheduleIfAllBufferAvailable(); 1766 1767 pthread_mutex_unlock(&ports_block); 1768} 1769 1770bool ComponentBase::IsAllBufferAvailable(void) 1771{ 1772 OMX_U32 i; 1773 OMX_U32 nr_avail = 0; 1774 1775 for (i = 0; i < nr_ports; i++) { 1776 OMX_U32 length; 1777 1778 length = ports[i]->BufferQueueLength(); 1779 if (length) 1780 nr_avail++; 1781 } 1782 1783 if (nr_avail == nr_ports) 1784 return true; 1785 else 1786 return false; 1787} 1788 1789void ComponentBase::ScheduleIfAllBufferAvailable(void) 1790{ 1791 bool avail; 1792 1793 avail = IsAllBufferAvailable(); 1794 if (avail) 1795 bufferwork->ScheduleWork(this); 1796} 1797 1798/* end of component methods & helpers */ 1799 1800/* 1801 * omx header manipuation 1802 */ 1803void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size) 1804{ 1805 OMX_U32 *nsize; 1806 OMX_VERSIONTYPE *nversion; 1807 1808 if (!type) 1809 return; 1810 1811 nsize = (OMX_U32 *)type; 1812 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 1813 1814 *nsize = size; 1815 nversion->nVersion = OMX_SPEC_VERSION; 1816} 1817 1818OMX_ERRORTYPE ComponentBase::CheckTypeHeader(OMX_PTR type, OMX_U32 size) 1819{ 1820 OMX_U32 *nsize; 1821 OMX_VERSIONTYPE *nversion; 1822 1823 if (!type) 1824 return OMX_ErrorBadParameter; 1825 1826 nsize = (OMX_U32 *)type; 1827 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 1828 1829 if (*nsize != size) 1830 return OMX_ErrorBadParameter; 1831 1832 if (nversion->nVersion != OMX_SPEC_VERSION) 1833 return OMX_ErrorVersionMismatch; 1834 1835 return OMX_ErrorNone; 1836} 1837 1838/* 1839 * query_roles helper 1840 */ 1841OMX_ERRORTYPE ComponentBase::QueryRolesHelper( 1842 OMX_U32 nr_comp_roles, 1843 const OMX_U8 **comp_roles, 1844 OMX_U32 *nr_roles, OMX_U8 **roles) 1845{ 1846 OMX_U32 i; 1847 1848 if (!roles) { 1849 *nr_roles = nr_comp_roles; 1850 return OMX_ErrorNone; 1851 } 1852 1853 if (!nr_roles || (*nr_roles != nr_comp_roles) || !roles) 1854 return OMX_ErrorBadParameter; 1855 1856 for (i = 0; i < nr_comp_roles; i++) { 1857 if (!roles[i]) 1858 break; 1859 1860 strncpy((OMX_STRING)&roles[i][0], 1861 (const OMX_STRING)&comp_roles[i][0], OMX_MAX_STRINGNAME_SIZE); 1862 } 1863 1864 if (i != nr_comp_roles) 1865 return OMX_ErrorBadParameter; 1866 1867 *nr_roles = nr_comp_roles; 1868 return OMX_ErrorNone; 1869} 1870 1871/* end of ComponentBase */ 1872