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