componentbase.cpp revision 69d34dfb7d76cbdd1bd0f0b4b7cb1f2267f5002a
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 OMX_U32 port_index = nParam1; 407 408 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 409 return OMX_ErrorBadPortIndex; 410 break; 411 } 412 case OMX_CommandPortDisable: 413 case OMX_CommandPortEnable: { 414 OMX_U32 port_index = nParam1; 415 416 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 417 return OMX_ErrorBadPortIndex; 418 break; 419 } 420 case OMX_CommandMarkBuffer: { 421 OMX_MARKTYPE *mark = (OMX_MARKTYPE *)pCmdData; 422 OMX_MARKTYPE *copiedmark; 423 OMX_U32 port_index = nParam1; 424 425 if (port_index > nr_ports-1) 426 return OMX_ErrorBadPortIndex; 427 428 if (!mark || !mark->hMarkTargetComponent) 429 return OMX_ErrorBadParameter; 430 431 copiedmark = (OMX_MARKTYPE *)malloc(sizeof(*copiedmark)); 432 if (!copiedmark) 433 return OMX_ErrorInsufficientResources; 434 435 copiedmark->hMarkTargetComponent = mark->hMarkTargetComponent; 436 copiedmark->pMarkData = mark->pMarkData; 437 pCmdData = (OMX_PTR)copiedmark; 438 break; 439 } 440 default: 441 LOGE("command %d not supported\n", Cmd); 442 return OMX_ErrorUnsupportedIndex; 443 } 444 445 cmd = (struct cmd_s *)malloc(sizeof(*cmd)); 446 if (!cmd) 447 return OMX_ErrorInsufficientResources; 448 449 cmd->cmd = Cmd; 450 cmd->param1 = nParam1; 451 cmd->cmddata = pCmdData; 452 453 return cmdwork->PushCmdQueue(cmd); 454} 455 456OMX_ERRORTYPE ComponentBase::GetParameter( 457 OMX_IN OMX_HANDLETYPE hComponent, 458 OMX_IN OMX_INDEXTYPE nParamIndex, 459 OMX_INOUT OMX_PTR pComponentParameterStructure) 460{ 461 ComponentBase *cbase; 462 463 if (!hComponent) 464 return OMX_ErrorBadParameter; 465 466 cbase = static_cast<ComponentBase *> 467 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 468 if (!cbase) 469 return OMX_ErrorBadParameter; 470 471 return cbase->CBaseGetParameter(hComponent, nParamIndex, 472 pComponentParameterStructure); 473} 474 475OMX_ERRORTYPE ComponentBase::CBaseGetParameter( 476 OMX_IN OMX_HANDLETYPE hComponent, 477 OMX_IN OMX_INDEXTYPE nParamIndex, 478 OMX_INOUT OMX_PTR pComponentParameterStructure) 479{ 480 OMX_ERRORTYPE ret = OMX_ErrorNone; 481 482 if (hComponent != handle) 483 return OMX_ErrorBadParameter; 484 485 switch (nParamIndex) { 486 case OMX_IndexParamAudioInit: 487 case OMX_IndexParamVideoInit: 488 case OMX_IndexParamImageInit: 489 case OMX_IndexParamOtherInit: { 490 OMX_PORT_PARAM_TYPE *p = 491 (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure; 492 493 ret = CheckTypeHeader(p, sizeof(*p)); 494 if (ret != OMX_ErrorNone) 495 return ret; 496 497 memcpy(p, &portparam, sizeof(*p)); 498 break; 499 } 500 case OMX_IndexParamPortDefinition: { 501 OMX_PARAM_PORTDEFINITIONTYPE *p = 502 (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; 503 OMX_U32 index = p->nPortIndex; 504 PortBase *port = NULL; 505 506 ret = CheckTypeHeader(p, sizeof(*p)); 507 if (ret != OMX_ErrorNone) 508 return ret; 509 510 if (index < nr_ports) 511 port = ports[index]; 512 513 if (!port) 514 return OMX_ErrorBadPortIndex; 515 516 memcpy(p, port->GetPortDefinition(), sizeof(*p)); 517 break; 518 } 519 case OMX_IndexParamCompBufferSupplier: 520 /* 521 * Todo 522 */ 523 524 ret = OMX_ErrorUnsupportedIndex; 525 break; 526 default: 527 ret = ComponentGetParameter(nParamIndex, pComponentParameterStructure); 528 } /* switch */ 529 530 return ret; 531} 532 533OMX_ERRORTYPE ComponentBase::SetParameter( 534 OMX_IN OMX_HANDLETYPE hComponent, 535 OMX_IN OMX_INDEXTYPE nIndex, 536 OMX_IN OMX_PTR pComponentParameterStructure) 537{ 538 ComponentBase *cbase; 539 540 if (!hComponent) 541 return OMX_ErrorBadParameter; 542 543 cbase = static_cast<ComponentBase *> 544 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 545 if (!cbase) 546 return OMX_ErrorBadParameter; 547 548 return cbase->CBaseSetParameter(hComponent, nIndex, 549 pComponentParameterStructure); 550} 551 552OMX_ERRORTYPE ComponentBase::CBaseSetParameter( 553 OMX_IN OMX_HANDLETYPE hComponent, 554 OMX_IN OMX_INDEXTYPE nIndex, 555 OMX_IN OMX_PTR pComponentParameterStructure) 556{ 557 OMX_ERRORTYPE ret = OMX_ErrorNone; 558 559 if (hComponent != handle) 560 return OMX_ErrorBadParameter; 561 562 switch (nIndex) { 563 case OMX_IndexParamAudioInit: 564 case OMX_IndexParamVideoInit: 565 case OMX_IndexParamImageInit: 566 case OMX_IndexParamOtherInit: 567 /* preventing clients from setting OMX_PORT_PARAM_TYPE */ 568 ret = OMX_ErrorUnsupportedIndex; 569 break; 570 case OMX_IndexParamPortDefinition: { 571 OMX_PARAM_PORTDEFINITIONTYPE *p = 572 (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; 573 OMX_U32 index = p->nPortIndex; 574 PortBase *port = NULL; 575 576 ret = CheckTypeHeader(p, sizeof(*p)); 577 if (ret != OMX_ErrorNone) 578 return ret; 579 580 if (index < nr_ports) 581 port = ports[index]; 582 583 if (!port) 584 return OMX_ErrorBadPortIndex; 585 586 if (port->IsEnabled()) { 587 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 588 return OMX_ErrorIncorrectStateOperation; 589 } 590 591 port->SetPortDefinition(p, false); 592 break; 593 } 594 case OMX_IndexParamCompBufferSupplier: 595 /* 596 * Todo 597 */ 598 599 ret = OMX_ErrorUnsupportedIndex; 600 break; 601 case OMX_IndexParamStandardComponentRole: { 602 OMX_PARAM_COMPONENTROLETYPE *p = 603 (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; 604 605 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 606 return OMX_ErrorIncorrectStateOperation; 607 608 ret = CheckTypeHeader(p, sizeof(*p)); 609 if (ret != OMX_ErrorNone) 610 return ret; 611 612 ret = SetWorkingRole((OMX_STRING)p->cRole); 613 if (ret != OMX_ErrorNone) 614 return ret; 615 616 if (ports) 617 FreePorts(); 618 619 ret = ApplyWorkingRole(); 620 if (ret != OMX_ErrorNone) { 621 SetWorkingRole(NULL); 622 return ret; 623 } 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 (!ppBufferHdr) 839 return OMX_ErrorBadParameter; 840 *ppBufferHdr = NULL; 841 842 if (!pBuffer) 843 return OMX_ErrorBadParameter; 844 845 if (ports) 846 if (nPortIndex < nr_ports) 847 port = ports[nPortIndex]; 848 849 if (!port) 850 return OMX_ErrorBadParameter; 851 852 if (port->IsEnabled()) { 853 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 854 return OMX_ErrorIncorrectStateOperation; 855 } 856 857 return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, 858 pBuffer); 859} 860 861OMX_ERRORTYPE ComponentBase::AllocateBuffer( 862 OMX_IN OMX_HANDLETYPE hComponent, 863 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 864 OMX_IN OMX_U32 nPortIndex, 865 OMX_IN OMX_PTR pAppPrivate, 866 OMX_IN OMX_U32 nSizeBytes) 867{ 868 ComponentBase *cbase; 869 870 if (!hComponent) 871 return OMX_ErrorBadParameter; 872 873 cbase = static_cast<ComponentBase *> 874 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 875 if (!cbase) 876 return OMX_ErrorBadParameter; 877 878 return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex, 879 pAppPrivate, nSizeBytes); 880} 881 882OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer( 883 OMX_IN OMX_HANDLETYPE hComponent, 884 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 885 OMX_IN OMX_U32 nPortIndex, 886 OMX_IN OMX_PTR pAppPrivate, 887 OMX_IN OMX_U32 nSizeBytes) 888{ 889 PortBase *port = NULL; 890 OMX_ERRORTYPE ret; 891 892 if (hComponent != handle) 893 return OMX_ErrorBadParameter; 894 895 if (!ppBuffer) 896 return OMX_ErrorBadParameter; 897 *ppBuffer = NULL; 898 899 if (ports) 900 if (nPortIndex < nr_ports) 901 port = ports[nPortIndex]; 902 903 if (!port) 904 return OMX_ErrorBadParameter; 905 906 if (port->IsEnabled()) { 907 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 908 return OMX_ErrorIncorrectStateOperation; 909 } 910 911 return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes); 912} 913 914OMX_ERRORTYPE ComponentBase::FreeBuffer( 915 OMX_IN OMX_HANDLETYPE hComponent, 916 OMX_IN OMX_U32 nPortIndex, 917 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 918{ 919 ComponentBase *cbase; 920 921 if (!hComponent) 922 return OMX_ErrorBadParameter; 923 924 cbase = static_cast<ComponentBase *> 925 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 926 if (!cbase) 927 return OMX_ErrorBadParameter; 928 929 return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer); 930} 931 932OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer( 933 OMX_IN OMX_HANDLETYPE hComponent, 934 OMX_IN OMX_U32 nPortIndex, 935 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 936{ 937 PortBase *port = NULL; 938 OMX_ERRORTYPE ret; 939 940 if (hComponent != handle) 941 return OMX_ErrorBadParameter; 942 943 if (!pBuffer) 944 return OMX_ErrorBadParameter; 945 946 if (ports) 947 if (nPortIndex < nr_ports) 948 port = ports[nPortIndex]; 949 950 if (!port) 951 return OMX_ErrorBadParameter; 952 953 return port->FreeBuffer(nPortIndex, pBuffer); 954} 955 956OMX_ERRORTYPE ComponentBase::EmptyThisBuffer( 957 OMX_IN OMX_HANDLETYPE hComponent, 958 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 959{ 960 ComponentBase *cbase; 961 962 if (!hComponent) 963 return OMX_ErrorBadParameter; 964 965 cbase = static_cast<ComponentBase *> 966 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 967 if (!cbase) 968 return OMX_ErrorBadParameter; 969 970 return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer); 971} 972 973OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer( 974 OMX_IN OMX_HANDLETYPE hComponent, 975 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 976{ 977 PortBase *port = NULL; 978 OMX_U32 port_index; 979 OMX_ERRORTYPE ret; 980 981 if ((hComponent != handle) || !pBuffer) 982 return OMX_ErrorBadParameter; 983 984 ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); 985 if (ret != OMX_ErrorNone) 986 return ret; 987 988 port_index = pBuffer->nInputPortIndex; 989 if (port_index == (OMX_U32)-1) 990 return OMX_ErrorBadParameter; 991 992 if (ports) 993 if (port_index < nr_ports) 994 port = ports[port_index]; 995 996 if (!port) 997 return OMX_ErrorBadParameter; 998 999 if (pBuffer->pInputPortPrivate != port) 1000 return OMX_ErrorBadParameter; 1001 1002 if (port->IsEnabled()) { 1003 if (state != OMX_StateIdle && state != OMX_StateExecuting && 1004 state != OMX_StatePause) 1005 return OMX_ErrorIncorrectStateOperation; 1006 } 1007 1008 if (!pBuffer->hMarkTargetComponent) { 1009 OMX_MARKTYPE *mark; 1010 1011 mark = port->PopMark(); 1012 if (mark) { 1013 pBuffer->hMarkTargetComponent = mark->hMarkTargetComponent; 1014 pBuffer->pMarkData = mark->pMarkData; 1015 free(mark); 1016 } 1017 } 1018 1019 ret = port->PushThisBuffer(pBuffer); 1020 if (ret == OMX_ErrorNone) 1021 bufferwork->ScheduleWork(this); 1022 1023 return ret; 1024} 1025 1026OMX_ERRORTYPE ComponentBase::FillThisBuffer( 1027 OMX_IN OMX_HANDLETYPE hComponent, 1028 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 1029{ 1030 ComponentBase *cbase; 1031 1032 if (!hComponent) 1033 return OMX_ErrorBadParameter; 1034 1035 cbase = static_cast<ComponentBase *> 1036 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1037 if (!cbase) 1038 return OMX_ErrorBadParameter; 1039 1040 return cbase->CBaseFillThisBuffer(hComponent, pBuffer); 1041} 1042 1043OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer( 1044 OMX_IN OMX_HANDLETYPE hComponent, 1045 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 1046{ 1047 PortBase *port = NULL; 1048 OMX_U32 port_index; 1049 OMX_ERRORTYPE ret; 1050 1051 if ((hComponent != handle) || !pBuffer) 1052 return OMX_ErrorBadParameter; 1053 1054 ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); 1055 if (ret != OMX_ErrorNone) 1056 return ret; 1057 1058 port_index = pBuffer->nOutputPortIndex; 1059 if (port_index == (OMX_U32)-1) 1060 return OMX_ErrorBadParameter; 1061 1062 if (ports) 1063 if (port_index < nr_ports) 1064 port = ports[port_index]; 1065 1066 if (!port) 1067 return OMX_ErrorBadParameter; 1068 1069 if (pBuffer->pOutputPortPrivate != port) 1070 return OMX_ErrorBadParameter; 1071 1072 if (port->IsEnabled()) { 1073 if (state != OMX_StateIdle && state != OMX_StateExecuting && 1074 state != OMX_StatePause) 1075 return OMX_ErrorIncorrectStateOperation; 1076 } 1077 1078 ret = port->PushThisBuffer(pBuffer); 1079 if (ret == OMX_ErrorNone) 1080 bufferwork->ScheduleWork(this); 1081 1082 return ret; 1083} 1084 1085OMX_ERRORTYPE ComponentBase::SetCallbacks( 1086 OMX_IN OMX_HANDLETYPE hComponent, 1087 OMX_IN OMX_CALLBACKTYPE* pCallbacks, 1088 OMX_IN OMX_PTR pAppData) 1089{ 1090 ComponentBase *cbase; 1091 1092 if (!hComponent) 1093 return OMX_ErrorBadParameter; 1094 1095 cbase = static_cast<ComponentBase *> 1096 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1097 if (!cbase) 1098 return OMX_ErrorBadParameter; 1099 1100 return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData); 1101} 1102 1103OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks( 1104 OMX_IN OMX_HANDLETYPE hComponent, 1105 OMX_IN OMX_CALLBACKTYPE *pCallbacks, 1106 OMX_IN OMX_PTR pAppData) 1107{ 1108 if (hComponent != handle) 1109 return OMX_ErrorBadParameter; 1110 1111 appdata = pAppData; 1112 callbacks = pCallbacks; 1113 1114 return OMX_ErrorNone; 1115} 1116 1117OMX_ERRORTYPE ComponentBase::ComponentDeInit( 1118 OMX_IN OMX_HANDLETYPE hComponent) 1119{ 1120 ComponentBase *cbase; 1121 1122 if (!hComponent) 1123 return OMX_ErrorBadParameter; 1124 1125 cbase = static_cast<ComponentBase *> 1126 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1127 if (!cbase) 1128 return OMX_ErrorBadParameter; 1129 1130 return cbase->CBaseComponentDeInit(hComponent); 1131} 1132 1133OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit( 1134 OMX_IN OMX_HANDLETYPE hComponent) 1135{ 1136 /* 1137 * Todo 1138 */ 1139 1140 return OMX_ErrorNotImplemented; 1141} 1142 1143OMX_ERRORTYPE ComponentBase::UseEGLImage( 1144 OMX_IN OMX_HANDLETYPE hComponent, 1145 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1146 OMX_IN OMX_U32 nPortIndex, 1147 OMX_IN OMX_PTR pAppPrivate, 1148 OMX_IN void* eglImage) 1149{ 1150 ComponentBase *cbase; 1151 1152 if (!hComponent) 1153 return OMX_ErrorBadParameter; 1154 1155 cbase = static_cast<ComponentBase *> 1156 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1157 if (!cbase) 1158 return OMX_ErrorBadParameter; 1159 1160 return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex, 1161 pAppPrivate, eglImage); 1162} 1163 1164OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage( 1165 OMX_IN OMX_HANDLETYPE hComponent, 1166 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1167 OMX_IN OMX_U32 nPortIndex, 1168 OMX_IN OMX_PTR pAppPrivate, 1169 OMX_IN void* eglImage) 1170{ 1171 /* 1172 * Todo 1173 */ 1174 1175 return OMX_ErrorNotImplemented; 1176} 1177 1178OMX_ERRORTYPE ComponentBase::ComponentRoleEnum( 1179 OMX_IN OMX_HANDLETYPE hComponent, 1180 OMX_OUT OMX_U8 *cRole, 1181 OMX_IN OMX_U32 nIndex) 1182{ 1183 ComponentBase *cbase; 1184 1185 if (!hComponent) 1186 return OMX_ErrorBadParameter; 1187 1188 cbase = static_cast<ComponentBase *> 1189 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1190 if (!cbase) 1191 return OMX_ErrorBadParameter; 1192 1193 return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex); 1194} 1195 1196OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum( 1197 OMX_IN OMX_HANDLETYPE hComponent, 1198 OMX_OUT OMX_U8 *cRole, 1199 OMX_IN OMX_U32 nIndex) 1200{ 1201 if (hComponent != (OMX_HANDLETYPE *)this->handle) 1202 return OMX_ErrorBadParameter; 1203 1204 if (nIndex > nr_roles) 1205 return OMX_ErrorBadParameter; 1206 1207 strncpy((char *)cRole, (const char *)roles[nIndex], 1208 OMX_MAX_STRINGNAME_SIZE); 1209 return OMX_ErrorNone; 1210} 1211 1212/* implement CmdHandlerInterface */ 1213void ComponentBase::CmdHandler(struct cmd_s *cmd) 1214{ 1215 switch (cmd->cmd) { 1216 case OMX_CommandStateSet: { 1217 OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1; 1218 1219 TransState(transition); 1220 break; 1221 } 1222 case OMX_CommandFlush: { 1223 OMX_U32 port_index = cmd->param1; 1224 1225 FlushPort(port_index, 1); 1226 break; 1227 } 1228 case OMX_CommandPortDisable: { 1229 OMX_U32 port_index = cmd->param1; 1230 1231 TransStatePort(port_index, PortBase::OMX_PortDisabled); 1232 break; 1233 } 1234 case OMX_CommandPortEnable: { 1235 OMX_U32 port_index = cmd->param1; 1236 1237 TransStatePort(port_index, PortBase::OMX_PortEnabled); 1238 break; 1239 } 1240 case OMX_CommandMarkBuffer: 1241 OMX_U32 port_index = (OMX_U32)cmd->param1; 1242 OMX_MARKTYPE *mark = (OMX_MARKTYPE *)cmd->cmddata; 1243 1244 PushThisMark(port_index, mark); 1245 break; 1246 } /* switch */ 1247} 1248 1249/* 1250 * SendCommand:OMX_CommandStateSet 1251 * called in CmdHandler or called in other parts of component for reporting 1252 * internal error (OMX_StateInvalid). 1253 */ 1254/* 1255 * Todo 1256 * Resource Management (OMX_StateWaitForResources) 1257 * for now, we never notify OMX_ErrorInsufficientResources, 1258 * so IL client doesn't try to set component' state OMX_StateWaitForResources 1259 */ 1260static const char *state_name[OMX_StateWaitForResources + 1] = { 1261 "OMX_StateInvalid", 1262 "OMX_StateLoaded", 1263 "OMX_StateIdle", 1264 "OMX_StateExecuting", 1265 "OMX_StatePause", 1266 "OMX_StateWaitForResources", 1267}; 1268 1269static inline const char *GetStateName(OMX_STATETYPE state) 1270{ 1271 if (state > OMX_StateWaitForResources) 1272 return "UnKnown"; 1273 1274 return state_name[state]; 1275} 1276 1277void ComponentBase::TransState(OMX_STATETYPE transition) 1278{ 1279 OMX_STATETYPE current = this->state; 1280 OMX_EVENTTYPE event; 1281 OMX_U32 data1, data2; 1282 OMX_ERRORTYPE ret; 1283 1284 LOGD("current state = %s, transition state = %s\n", 1285 GetStateName(current), GetStateName(transition)); 1286 1287 /* same state */ 1288 if (current == transition) { 1289 ret = OMX_ErrorSameState; 1290 goto notify_event; 1291 } 1292 1293 /* invalid state */ 1294 if (current == OMX_StateInvalid) { 1295 ret = OMX_ErrorInvalidState; 1296 goto notify_event; 1297 } 1298 1299 if (transition == OMX_StateLoaded) 1300 ret = TransStateToLoaded(current); 1301 else if (transition == OMX_StateIdle) 1302 ret = TransStateToIdle(current); 1303 else if (transition == OMX_StateExecuting) 1304 ret = TransStateToExecuting(current); 1305 else if (transition == OMX_StatePause) 1306 ret = TransStateToPause(current); 1307 else if (transition == OMX_StateInvalid) 1308 ret = TransStateToInvalid(current); 1309 else if (transition == OMX_StateWaitForResources) 1310 ret = TransStateToWaitForResources(current); 1311 else 1312 ret = OMX_ErrorIncorrectStateTransition; 1313 1314notify_event: 1315 if (ret == OMX_ErrorNone) { 1316 event = OMX_EventCmdComplete; 1317 data1 = OMX_CommandStateSet; 1318 data2 = transition; 1319 1320 state = transition; 1321 LOGD("transition from %s to %s completed\n", 1322 GetStateName(current), GetStateName(transition)); 1323 } 1324 else { 1325 event = OMX_EventError; 1326 data1 = ret; 1327 data2 = 0; 1328 1329 if (transition == OMX_StateInvalid || ret == OMX_ErrorInvalidState) { 1330 state = OMX_StateInvalid; 1331 LOGD("failed transition from %s to %s, current state is %s\n", 1332 GetStateName(current), GetStateName(transition), 1333 GetStateName(state)); 1334 } 1335 } 1336 1337 callbacks->EventHandler(handle, appdata, event, data1, data2, NULL); 1338 1339 /* WaitForResources workaround */ 1340 if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources) 1341 callbacks->EventHandler(handle, appdata, 1342 OMX_EventResourcesAcquired, 0, 0, NULL); 1343} 1344 1345inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current) 1346{ 1347 OMX_ERRORTYPE ret; 1348 1349 if (current == OMX_StateIdle) { 1350 OMX_U32 i; 1351 1352 for (i = 0; i < nr_ports; i++) 1353 ports[i]->WaitPortBufferCompletion(); 1354 1355 ret = ProcessorDeinit(); 1356 if (ret != OMX_ErrorNone) { 1357 LOGE("failed to ProcessorDeinit() (ret = 0x%08x)\n", ret); 1358 ret = OMX_ErrorInvalidState; 1359 goto out; 1360 } 1361 } 1362 else if (current == OMX_StateWaitForResources) { 1363 LOGE("state transition's requested from WaitForResources to " 1364 "Loaded\n"); 1365 1366 /* 1367 * from WaitForResources to Loaded considered from Loaded to Loaded. 1368 * do nothing 1369 */ 1370 1371 ret = OMX_ErrorNone; 1372 } 1373 else 1374 ret = OMX_ErrorIncorrectStateTransition; 1375 1376out: 1377 return ret; 1378} 1379 1380inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current) 1381{ 1382 OMX_ERRORTYPE ret; 1383 1384 if (current == OMX_StateLoaded) { 1385 OMX_U32 i; 1386 1387 ret = ProcessorInit(); 1388 if (ret != OMX_ErrorNone) { 1389 LOGE("failed to ProcessorInit() (ret = 0x%08x)\n", ret); 1390 ret = OMX_ErrorInvalidState; 1391 goto out; 1392 } 1393 1394 for (i = 0; i < nr_ports; i++) { 1395 if (ports[i]->IsEnabled()) 1396 ports[i]->WaitPortBufferCompletion(); 1397 } 1398 } 1399 else if (current == OMX_StateExecuting) { 1400 FlushPort(OMX_ALL, 0); 1401 1402 bufferwork->StopWork(); 1403 1404 ret = ProcessorStop(); 1405 if (ret != OMX_ErrorNone) { 1406 LOGE("failed to ProcessorStop() (ret = 0x%08x)\n", ret); 1407 ret = OMX_ErrorInvalidState; 1408 goto out; 1409 } 1410 } 1411 else if (current == OMX_StatePause) { 1412 FlushPort(OMX_ALL, 0); 1413 1414 bufferwork->CancelScheduledWork(this); 1415 bufferwork->StopWork(); 1416 1417 ret = ProcessorStop(); 1418 if (ret != OMX_ErrorNone) { 1419 LOGE("failed to ProcessorStop() (ret = 0x%08x)\n", ret); 1420 ret = OMX_ErrorInvalidState; 1421 goto out; 1422 } 1423 } 1424 else if (current == OMX_StateWaitForResources) { 1425 LOGE("state transition's requested from WaitForResources to Idle\n"); 1426 1427 /* same as Loaded to Idle BUT DO NOTHING for now */ 1428 1429 ret = OMX_ErrorNone; 1430 } 1431 else 1432 ret = OMX_ErrorIncorrectStateTransition; 1433 1434out: 1435 return ret; 1436} 1437 1438inline OMX_ERRORTYPE 1439ComponentBase::TransStateToExecuting(OMX_STATETYPE current) 1440{ 1441 OMX_ERRORTYPE ret; 1442 1443 if (current == OMX_StateIdle) { 1444 pthread_mutex_lock(&executing_lock); 1445 executing = true; 1446 pthread_mutex_unlock(&executing_lock); 1447 1448 bufferwork->StartWork(); 1449 1450 ret = ProcessorStart(); 1451 if (ret != OMX_ErrorNone) { 1452 LOGE("failed to ProcessorStart() (ret = 0x%08x)\n", ret); 1453 ret = OMX_ErrorInvalidState; 1454 goto out; 1455 } 1456 } 1457 else if (current == OMX_StatePause) { 1458 pthread_mutex_lock(&executing_lock); 1459 executing = true; 1460 pthread_cond_signal(&executing_wait); 1461 pthread_mutex_unlock(&executing_lock); 1462 1463 ret = ProcessorResume(); 1464 if (ret != OMX_ErrorNone) { 1465 LOGE("failed to ProcessorStart() (ret = 0x%08x)\n", ret); 1466 ret = OMX_ErrorInvalidState; 1467 goto out; 1468 } 1469 } 1470 else 1471 ret = OMX_ErrorIncorrectStateTransition; 1472 1473out: 1474 return ret; 1475} 1476 1477inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current) 1478{ 1479 OMX_ERRORTYPE ret; 1480 1481 if (current == OMX_StateIdle) { 1482 /* turn off executing flag */ 1483 pthread_mutex_lock(&executing_lock); 1484 executing = false; 1485 pthread_mutex_unlock(&executing_lock); 1486 1487 bufferwork->StartWork(); 1488 1489 ret = ProcessorStart(); 1490 if (ret != OMX_ErrorNone) { 1491 LOGE("failed to ProcessorPause() (ret = 0x%08x)\n", ret); 1492 ret = OMX_ErrorInvalidState; 1493 goto out; 1494 } 1495 } 1496 else if (current == OMX_StateExecuting) { 1497 pthread_mutex_lock(&executing_lock); 1498 executing = false; 1499 pthread_mutex_unlock(&executing_lock); 1500 1501 ret = ProcessorPause(); 1502 if (ret != OMX_ErrorNone) { 1503 LOGE("failed to ProcessorPause() (ret = 0x%08x)\n", ret); 1504 ret = OMX_ErrorInvalidState; 1505 goto out; 1506 } 1507 } 1508 else 1509 ret = OMX_ErrorIncorrectStateTransition; 1510 1511out: 1512 return ret; 1513} 1514 1515inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current) 1516{ 1517 OMX_ERRORTYPE ret = OMX_ErrorInvalidState; 1518 1519 /* 1520 * Todo 1521 * graceful escape 1522 */ 1523 1524 return ret; 1525} 1526 1527inline OMX_ERRORTYPE 1528ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current) 1529{ 1530 OMX_ERRORTYPE ret; 1531 1532 if (current == OMX_StateLoaded) { 1533 LOGE("state transition's requested from Loaded to WaitForResources\n"); 1534 ret = OMX_ErrorNone; 1535 } 1536 else 1537 ret = OMX_ErrorIncorrectStateTransition; 1538 1539 return ret; 1540} 1541 1542/* mark buffer */ 1543void ComponentBase::PushThisMark(OMX_U32 port_index, OMX_MARKTYPE *mark) 1544{ 1545 PortBase *port = NULL; 1546 OMX_EVENTTYPE event; 1547 OMX_U32 data1, data2; 1548 OMX_ERRORTYPE ret; 1549 1550 if (ports) 1551 if (port_index < nr_ports) 1552 port = ports[port_index]; 1553 1554 if (!port) { 1555 ret = OMX_ErrorBadPortIndex; 1556 goto notify_event; 1557 } 1558 1559 ret = port->PushMark(mark); 1560 if (ret != OMX_ErrorNone) { 1561 /* don't report OMX_ErrorInsufficientResources */ 1562 ret = OMX_ErrorUndefined; 1563 goto notify_event; 1564 } 1565 1566notify_event: 1567 if (ret == OMX_ErrorNone) { 1568 event = OMX_EventCmdComplete; 1569 data1 = OMX_CommandMarkBuffer; 1570 data2 = port_index; 1571 } 1572 else { 1573 event = OMX_EventError; 1574 data1 = ret; 1575 data2 = 0; 1576 } 1577 1578 callbacks->EventHandler(handle, appdata, event, data1, data2, NULL); 1579} 1580 1581void ComponentBase::FlushPort(OMX_U32 port_index, bool notify) 1582{ 1583 OMX_U32 i, from_index, to_index; 1584 1585 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 1586 return; 1587 1588 if (port_index == OMX_ALL) { 1589 from_index = 0; 1590 to_index = nr_ports - 1; 1591 } 1592 else { 1593 from_index = port_index; 1594 to_index = port_index; 1595 } 1596 1597 pthread_mutex_lock(&ports_block); 1598 for (i = from_index; i <= to_index; i++) { 1599 ports[i]->FlushPort(); 1600 if (notify) 1601 callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete, 1602 OMX_CommandFlush, i, NULL); 1603 } 1604 pthread_mutex_unlock(&ports_block); 1605} 1606 1607void ComponentBase::TransStatePort(OMX_U32 port_index, OMX_U8 state) 1608{ 1609 OMX_EVENTTYPE event; 1610 OMX_U32 data1, data2; 1611 OMX_U32 i, from_index, to_index; 1612 OMX_ERRORTYPE ret; 1613 1614 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 1615 return; 1616 1617 if (port_index == OMX_ALL) { 1618 from_index = 0; 1619 to_index = nr_ports - 1; 1620 } 1621 else { 1622 from_index = port_index; 1623 to_index = port_index; 1624 } 1625 1626 pthread_mutex_lock(&ports_block); 1627 for (i = from_index; i <= to_index; i++) { 1628 ret = ports[i]->TransState(state); 1629 if (ret == OMX_ErrorNone) { 1630 event = OMX_EventCmdComplete; 1631 if (state == PortBase::OMX_PortEnabled) 1632 data1 = OMX_CommandPortEnable; 1633 else 1634 data1 = OMX_CommandPortDisable; 1635 data2 = i; 1636 } 1637 else { 1638 event = OMX_EventError; 1639 data1 = ret; 1640 data2 = 0; 1641 } 1642 callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete, 1643 OMX_CommandPortDisable, data2, NULL); 1644 } 1645 pthread_mutex_unlock(&ports_block); 1646} 1647 1648/* set working role */ 1649OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role) 1650{ 1651 OMX_U32 i; 1652 1653 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1654 return OMX_ErrorIncorrectStateOperation; 1655 1656 if (!role) { 1657 working_role = NULL; 1658 return OMX_ErrorNone; 1659 } 1660 1661 for (i = 0; i < nr_roles; i++) { 1662 if (!strcmp((char *)&roles[i][0], role)) { 1663 working_role = (OMX_STRING)&roles[i][0]; 1664 return OMX_ErrorNone; 1665 } 1666 } 1667 1668 LOGE("cannot find %s role in %s\n", role, name); 1669 return OMX_ErrorBadParameter; 1670} 1671 1672/* apply a working role for a component having multiple roles */ 1673OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void) 1674{ 1675 OMX_U32 i; 1676 OMX_ERRORTYPE ret; 1677 1678 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1679 return OMX_ErrorIncorrectStateOperation; 1680 1681 if (!working_role) 1682 return OMX_ErrorBadParameter; 1683 1684 if (!callbacks || !appdata) 1685 return OMX_ErrorBadParameter; 1686 1687 ret = AllocatePorts(); 1688 if (ret != OMX_ErrorNone) { 1689 LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret); 1690 return ret; 1691 } 1692 1693 /* now we can access ports */ 1694 for (i = 0; i < nr_ports; i++) { 1695 ports[i]->SetOwner(handle); 1696 ports[i]->SetCallbacks(handle, callbacks, appdata); 1697 } 1698 1699 return OMX_ErrorNone; 1700} 1701 1702OMX_ERRORTYPE ComponentBase::AllocatePorts(void) 1703{ 1704 OMX_ERRORTYPE ret; 1705 1706 if (ports) 1707 return OMX_ErrorBadParameter; 1708 1709 ret = ComponentAllocatePorts(); 1710 if (ret != OMX_ErrorNone) { 1711 LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n", 1712 name, ret); 1713 return ret; 1714 } 1715 1716 return OMX_ErrorNone; 1717} 1718 1719/* called int FreeHandle() */ 1720OMX_ERRORTYPE ComponentBase::FreePorts(void) 1721{ 1722 if (ports) { 1723 OMX_U32 i, this_nr_ports = this->nr_ports; 1724 1725 for (i = 0; i < this_nr_ports; i++) { 1726 if (ports[i]) { 1727 OMX_MARKTYPE *mark; 1728 /* it should be empty before this */ 1729 while ((mark = ports[i]->PopMark())) 1730 free(mark); 1731 1732 delete ports[i]; 1733 ports[i] = NULL; 1734 } 1735 } 1736 delete []ports; 1737 ports = NULL; 1738 } 1739 1740 return OMX_ErrorNone; 1741} 1742 1743/* buffer processing */ 1744/* implement WorkableInterface */ 1745void ComponentBase::Work(void) 1746{ 1747 OMX_BUFFERHEADERTYPE *buffers[nr_ports]; 1748 bool retain[nr_ports]; 1749 OMX_U32 i; 1750 bool avail = false; 1751 1752 pthread_mutex_lock(&executing_lock); 1753 if (!executing) 1754 pthread_cond_wait(&executing_wait, &executing_lock); 1755 pthread_mutex_unlock(&executing_lock); 1756 1757 pthread_mutex_lock(&ports_block); 1758 1759 avail = IsAllBufferAvailable(); 1760 if (avail) { 1761 for (i = 0; i < nr_ports; i++) { 1762 buffers[i] = ports[i]->PopBuffer(); 1763 retain[i] = false; 1764 } 1765 1766 ProcessorProcess(buffers, &retain[0], nr_ports); 1767 PostProcessBuffer(buffers, &retain[0], nr_ports); 1768 1769 for (i = 0; i < nr_ports; i++) { 1770 if (retain[i]) 1771 ports[i]->RetainThisBuffer(buffers[i]); 1772 else 1773 ports[i]->ReturnThisBuffer(buffers[i]); 1774 } 1775 } 1776 ScheduleIfAllBufferAvailable(); 1777 1778 pthread_mutex_unlock(&ports_block); 1779} 1780 1781bool ComponentBase::IsAllBufferAvailable(void) 1782{ 1783 OMX_U32 i; 1784 OMX_U32 nr_avail = 0; 1785 1786 for (i = 0; i < nr_ports; i++) { 1787 OMX_U32 length = 0; 1788 1789 if (ports[i]->IsEnabled()) 1790 length = ports[i]->BufferQueueLength(); 1791 1792 if (length) 1793 nr_avail++; 1794 } 1795 1796 if (nr_avail == nr_ports) 1797 return true; 1798 else 1799 return false; 1800} 1801 1802void ComponentBase::ScheduleIfAllBufferAvailable(void) 1803{ 1804 bool avail; 1805 1806 avail = IsAllBufferAvailable(); 1807 if (avail) 1808 bufferwork->ScheduleWork(this); 1809} 1810 1811void ComponentBase::PostProcessBuffer(OMX_BUFFERHEADERTYPE **buffers, 1812 bool *retain, 1813 OMX_U32 nr_buffers) 1814{ 1815 OMX_U32 i; 1816 1817 for (i = 0; i < nr_ports; i++) { 1818 OMX_MARKTYPE *mark; 1819 1820 if (ports[i]->GetPortDirection() == OMX_DirInput) { 1821 bool is_sink_component = true; 1822 OMX_U32 j; 1823 1824 if (buffers[i]->hMarkTargetComponent) { 1825 if (buffers[i]->hMarkTargetComponent == handle) { 1826 callbacks->EventHandler(handle, appdata, OMX_EventMark, 1827 0, 0, buffers[i]->pMarkData); 1828 buffers[i]->hMarkTargetComponent = NULL; 1829 buffers[i]->pMarkData = NULL; 1830 } 1831 } 1832 1833 for (j = 0; j < nr_ports; j++) { 1834 if (j == i) 1835 continue; 1836 1837 if (ports[j]->GetPortDirection() == OMX_DirOutput) { 1838 if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS) { 1839 buffers[j]->nFlags |= OMX_BUFFERFLAG_EOS; 1840 buffers[i]->nFlags &= ~OMX_BUFFERFLAG_EOS; 1841 retain[i] = false; 1842 retain[j] = false; 1843 } 1844 1845 if (!buffers[j]->hMarkTargetComponent) { 1846 mark = ports[j]->PopMark(); 1847 if (mark) { 1848 buffers[j]->hMarkTargetComponent = 1849 mark->hMarkTargetComponent; 1850 buffers[j]->pMarkData = mark->pMarkData; 1851 free(mark); 1852 mark = NULL; 1853 } 1854 1855 if (buffers[i]->hMarkTargetComponent) { 1856 if (buffers[j]->hMarkTargetComponent) { 1857 mark = (OMX_MARKTYPE *) 1858 malloc(sizeof(*mark)); 1859 if (mark) { 1860 mark->hMarkTargetComponent = 1861 buffers[i]->hMarkTargetComponent; 1862 mark->pMarkData = buffers[i]->pMarkData; 1863 ports[j]->PushMark(mark); 1864 mark = NULL; 1865 buffers[i]->hMarkTargetComponent = NULL; 1866 buffers[i]->pMarkData = NULL; 1867 } 1868 } 1869 else { 1870 buffers[j]->hMarkTargetComponent = 1871 buffers[i]->hMarkTargetComponent; 1872 buffers[j]->pMarkData = buffers[i]->pMarkData; 1873 buffers[i]->hMarkTargetComponent = NULL; 1874 buffers[i]->pMarkData = NULL; 1875 } 1876 } 1877 } 1878 else { 1879 if (buffers[i]->hMarkTargetComponent) { 1880 mark = (OMX_MARKTYPE *)malloc(sizeof(*mark)); 1881 if (mark) { 1882 mark->hMarkTargetComponent = 1883 buffers[i]->hMarkTargetComponent; 1884 mark->pMarkData = buffers[i]->pMarkData; 1885 ports[j]->PushMark(mark); 1886 mark = NULL; 1887 buffers[i]->hMarkTargetComponent = NULL; 1888 buffers[i]->pMarkData = NULL; 1889 } 1890 } 1891 } 1892 is_sink_component = false; 1893 } 1894 } 1895 1896 if (is_sink_component) { 1897 if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS) { 1898 callbacks->EventHandler(handle, appdata, 1899 OMX_EventBufferFlag, 1900 i, buffers[i]->nFlags, NULL); 1901 retain[i] = false; 1902 } 1903 } 1904 } 1905 else if (ports[i]->GetPortDirection() == OMX_DirOutput) { 1906 bool is_source_component = true; 1907 OMX_U32 j; 1908 1909 if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS) { 1910 callbacks->EventHandler(handle, appdata, 1911 OMX_EventBufferFlag, 1912 i, buffers[i]->nFlags, NULL); 1913 retain[i] = false; 1914 } 1915 1916 for (j = 0; j < nr_ports; j++) { 1917 if (j == i) 1918 continue; 1919 1920 if (ports[j]->GetPortDirection() == OMX_DirInput) 1921 is_source_component = false; 1922 } 1923 1924 if (is_source_component) { 1925 if (!retain[i]) { 1926 mark = ports[i]->PopMark(); 1927 if (mark) { 1928 buffers[i]->hMarkTargetComponent = 1929 mark->hMarkTargetComponent; 1930 buffers[i]->pMarkData = mark->pMarkData; 1931 free(mark); 1932 mark = NULL; 1933 1934 if (buffers[i]->hMarkTargetComponent == handle) { 1935 callbacks->EventHandler(handle, appdata, 1936 OMX_EventMark, 0, 0, 1937 buffers[i]->pMarkData); 1938 buffers[i]->hMarkTargetComponent = NULL; 1939 buffers[i]->pMarkData = NULL; 1940 } 1941 } 1942 } 1943 } 1944 } 1945 else { 1946 LOGE("%s(): fatal error unknown port direction (0x%08x)\n", 1947 __func__, ports[i]->GetPortDirection()); 1948 } 1949 } 1950} 1951 1952/* processor default callbacks */ 1953OMX_ERRORTYPE ComponentBase::ProcessorInit(void) 1954{ 1955 return OMX_ErrorNone; 1956} 1957OMX_ERRORTYPE ComponentBase::ProcessorDeinit(void) 1958{ 1959 return OMX_ErrorNone; 1960} 1961 1962OMX_ERRORTYPE ComponentBase::ProcessorStart(void) 1963{ 1964 return OMX_ErrorNone; 1965} 1966 1967OMX_ERRORTYPE ComponentBase::ProcessorStop(void) 1968{ 1969 return OMX_ErrorNone; 1970} 1971 1972OMX_ERRORTYPE ComponentBase::ProcessorPause(void) 1973{ 1974 return OMX_ErrorNone; 1975} 1976 1977OMX_ERRORTYPE ComponentBase::ProcessorResume(void) 1978{ 1979 return OMX_ErrorNone; 1980} 1981 1982/* end of processor callbacks */ 1983 1984/* helper for derived class */ 1985const OMX_STRING ComponentBase::GetWorkingRole(void) 1986{ 1987 return &working_role[0]; 1988} 1989 1990const OMX_COMPONENTTYPE *ComponentBase::GetComponentHandle(void) 1991{ 1992 return handle; 1993} 1994 1995/* end of component methods & helpers */ 1996 1997/* 1998 * omx header manipuation 1999 */ 2000void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size) 2001{ 2002 OMX_U32 *nsize; 2003 OMX_VERSIONTYPE *nversion; 2004 2005 if (!type) 2006 return; 2007 2008 nsize = (OMX_U32 *)type; 2009 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 2010 2011 *nsize = size; 2012 nversion->nVersion = OMX_SPEC_VERSION; 2013} 2014 2015OMX_ERRORTYPE ComponentBase::CheckTypeHeader(const OMX_PTR type, OMX_U32 size) 2016{ 2017 OMX_U32 *nsize; 2018 OMX_VERSIONTYPE *nversion; 2019 2020 if (!type) 2021 return OMX_ErrorBadParameter; 2022 2023 nsize = (OMX_U32 *)type; 2024 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 2025 2026 if (*nsize != size) 2027 return OMX_ErrorBadParameter; 2028 2029 if (nversion->nVersion != OMX_SPEC_VERSION) 2030 return OMX_ErrorVersionMismatch; 2031 2032 return OMX_ErrorNone; 2033} 2034 2035/* 2036 * query_roles helper 2037 */ 2038OMX_ERRORTYPE ComponentBase::QueryRolesHelper( 2039 OMX_U32 nr_comp_roles, 2040 const OMX_U8 **comp_roles, 2041 OMX_U32 *nr_roles, OMX_U8 **roles) 2042{ 2043 OMX_U32 i; 2044 2045 if (!roles) { 2046 *nr_roles = nr_comp_roles; 2047 return OMX_ErrorNone; 2048 } 2049 2050 if (!nr_roles || (*nr_roles != nr_comp_roles) || !roles) 2051 return OMX_ErrorBadParameter; 2052 2053 for (i = 0; i < nr_comp_roles; i++) { 2054 if (!roles[i]) 2055 break; 2056 2057 strncpy((OMX_STRING)&roles[i][0], 2058 (const OMX_STRING)&comp_roles[i][0], OMX_MAX_STRINGNAME_SIZE); 2059 } 2060 2061 if (i != nr_comp_roles) 2062 return OMX_ErrorBadParameter; 2063 2064 *nr_roles = nr_comp_roles; 2065 return OMX_ErrorNone; 2066} 2067 2068/* end of ComponentBase */ 2069