componentbase.cpp revision 64239dd40f5c997a4c5b66e0d9da49b6b110802a
1/* 2 * Copyright (C) 2009 Wind River Systems 3 * Author: Ho-Eun Ryu <ho-eun.ryu@windriver.com> 4 */ 5 6#include <stdlib.h> 7#include <string.h> 8 9#include <pthread.h> 10 11#include <OMX_Core.h> 12#include <OMX_Component.h> 13 14#include <componentbase.h> 15 16#include <queue.h> 17#include <workqueue.h> 18 19#define LOG_TAG "componentbase" 20#include <log.h> 21 22/* 23 * CmdProcessWork 24 */ 25CmdProcessWork::CmdProcessWork(CmdHandlerInterface *ci) 26{ 27 this->ci = ci; 28 29 workq = new WorkQueue; 30 31 __queue_init(&q); 32 pthread_mutex_init(&lock, NULL); 33 34 workq->StartWork(); 35} 36 37CmdProcessWork::~CmdProcessWork() 38{ 39 workq->StopWork(); 40 delete workq; 41 42 pthread_mutex_lock(&lock); 43 queue_free_all(&q); 44 pthread_mutex_unlock(&lock); 45 46 pthread_mutex_destroy(&lock); 47} 48 49OMX_ERRORTYPE CmdProcessWork::PushCmdQueue(struct cmd_s *cmd) 50{ 51 int ret; 52 53 pthread_mutex_lock(&lock); 54 ret = queue_push_tail(&q, cmd); 55 if (ret) { 56 pthread_mutex_unlock(&lock); 57 return OMX_ErrorInsufficientResources; 58 } 59 60 workq->ScheduleWork(this); 61 pthread_mutex_unlock(&lock); 62 63 return OMX_ErrorNone; 64} 65 66struct cmd_s *CmdProcessWork::PopCmdQueue(void) 67{ 68 struct cmd_s *cmd; 69 70 pthread_mutex_lock(&lock); 71 cmd = (struct cmd_s *)queue_pop_head(&q); 72 pthread_mutex_unlock(&lock); 73 74 return cmd; 75} 76 77void CmdProcessWork::ScheduleIfAvailable(void) 78{ 79 bool avail; 80 81 pthread_mutex_lock(&lock); 82 avail = queue_length(&q) ? true : false; 83 pthread_mutex_unlock(&lock); 84 85 if (avail) 86 workq->ScheduleWork(this); 87} 88 89void CmdProcessWork::Work(void) 90{ 91 struct cmd_s *cmd; 92 93 cmd = PopCmdQueue(); 94 if (cmd) { 95 ci->CmdHandler(cmd); 96 free(cmd); 97 } 98 ScheduleIfAvailable(); 99} 100 101/* end of CmdProcessWork */ 102 103/* 104 * ComponentBase 105 */ 106/* 107 * constructor & destructor 108 */ 109void ComponentBase::__ComponentBase(void) 110{ 111 memset(name, 0, OMX_MAX_STRINGNAME_SIZE); 112 cmodule = NULL; 113 handle = NULL; 114 115 roles = NULL; 116 nr_roles = 0; 117 118 working_role = NULL; 119 120 ports = NULL; 121 nr_ports = 0; 122 memset(&portparam, 0, sizeof(portparam)); 123 124 state = OMX_StateUnloaded; 125 126 cmdwork = new CmdProcessWork(this); 127 128 executing = false; 129 pthread_mutex_init(&executing_lock, NULL); 130 pthread_cond_init(&executing_wait, NULL); 131 132 bufferwork = new WorkQueue(); 133 134 pthread_mutex_init(&ports_block, NULL); 135} 136 137ComponentBase::ComponentBase() 138{ 139 __ComponentBase(); 140} 141 142ComponentBase::ComponentBase(const OMX_STRING name) 143{ 144 __ComponentBase(); 145 SetName(name); 146} 147 148ComponentBase::~ComponentBase() 149{ 150 delete cmdwork; 151 152 delete bufferwork; 153 pthread_mutex_destroy(&executing_lock); 154 pthread_cond_destroy(&executing_wait); 155 156 pthread_mutex_destroy(&ports_block); 157 158 if (roles) { 159 if (roles[0]) 160 free(roles[0]); 161 free(roles); 162 } 163} 164 165/* end of constructor & destructor */ 166 167/* 168 * accessor 169 */ 170/* name */ 171void ComponentBase::SetName(const OMX_STRING name) 172{ 173 strncpy(this->name, name, OMX_MAX_STRINGNAME_SIZE); 174 this->name[OMX_MAX_STRINGNAME_SIZE-1] = '\0'; 175} 176 177const OMX_STRING ComponentBase::GetName(void) 178{ 179 return name; 180} 181 182/* component module */ 183void ComponentBase::SetCModule(CModule *cmodule) 184{ 185 this->cmodule = cmodule; 186} 187 188CModule *ComponentBase::GetCModule(void) 189{ 190 return cmodule; 191} 192 193/* end of accessor */ 194 195/* 196 * core methods & helpers 197 */ 198/* roles */ 199OMX_ERRORTYPE ComponentBase::SetRolesOfComponent(OMX_U32 nr_roles, 200 const OMX_U8 **roles) 201{ 202 OMX_U32 i; 203 204 if (!roles || !nr_roles) 205 return OMX_ErrorBadParameter; 206 207 if (this->roles) { 208 free(this->roles[0]); 209 free(this->roles); 210 this->roles = NULL; 211 } 212 213 this->roles = (OMX_U8 **)malloc(sizeof(OMX_STRING) * nr_roles); 214 if (!this->roles) 215 return OMX_ErrorInsufficientResources; 216 217 this->roles[0] = (OMX_U8 *)malloc(OMX_MAX_STRINGNAME_SIZE * nr_roles); 218 if (!this->roles[0]) { 219 free(this->roles); 220 this->roles = NULL; 221 return OMX_ErrorInsufficientResources; 222 } 223 224 for (i = 0; i < nr_roles; i++) { 225 if (i < nr_roles-1) 226 this->roles[i+1] = this->roles[i] + OMX_MAX_STRINGNAME_SIZE; 227 228 strncpy((OMX_STRING)&this->roles[i][0], 229 (const OMX_STRING)&roles[i][0], OMX_MAX_STRINGNAME_SIZE); 230 } 231 232 this->nr_roles = nr_roles; 233 return OMX_ErrorNone; 234} 235 236/* GetHandle & FreeHandle */ 237OMX_ERRORTYPE ComponentBase::GetHandle(OMX_HANDLETYPE *pHandle, 238 OMX_PTR pAppData, 239 OMX_CALLBACKTYPE *pCallBacks) 240{ 241 OMX_U32 i; 242 OMX_ERRORTYPE ret; 243 244 if (handle) 245 return OMX_ErrorUndefined; 246 247 handle = (OMX_COMPONENTTYPE *)calloc(1, sizeof(*handle)); 248 if (!handle) 249 return OMX_ErrorInsufficientResources; 250 251 /* handle initialization */ 252 SetTypeHeader(handle, sizeof(*handle)); 253 handle->pComponentPrivate = static_cast<OMX_PTR>(this); 254 handle->pApplicationPrivate = pAppData; 255 256 /* connect handle's functions */ 257 handle->GetComponentVersion = GetComponentVersion; 258 handle->SendCommand = SendCommand; 259 handle->GetParameter = GetParameter; 260 handle->SetParameter = SetParameter; 261 handle->GetConfig = GetConfig; 262 handle->SetConfig = SetConfig; 263 handle->GetExtensionIndex = GetExtensionIndex; 264 handle->GetState = GetState; 265 handle->ComponentTunnelRequest = ComponentTunnelRequest; 266 handle->UseBuffer = UseBuffer; 267 handle->AllocateBuffer = AllocateBuffer; 268 handle->FreeBuffer = FreeBuffer; 269 handle->EmptyThisBuffer = EmptyThisBuffer; 270 handle->FillThisBuffer = FillThisBuffer; 271 handle->SetCallbacks = SetCallbacks; 272 handle->ComponentDeInit = ComponentDeInit; 273 handle->UseEGLImage = UseEGLImage; 274 handle->ComponentRoleEnum = ComponentRoleEnum; 275 276 appdata = pAppData; 277 callbacks = pCallBacks; 278 279 if (nr_roles == 1) { 280 SetWorkingRole((OMX_STRING)&roles[0][0]); 281 ret = ApplyWorkingRole(); 282 if (ret != OMX_ErrorNone) { 283 SetWorkingRole(NULL); 284 goto free_handle; 285 } 286 } 287 288 *pHandle = (OMX_HANDLETYPE *)handle; 289 state = OMX_StateLoaded; 290 return OMX_ErrorNone; 291 292free_handle: 293 free(handle); 294 295 appdata = NULL; 296 callbacks = NULL; 297 *pHandle = NULL; 298 299 return ret; 300} 301 302OMX_ERRORTYPE ComponentBase::FreeHandle(OMX_HANDLETYPE hComponent) 303{ 304 OMX_ERRORTYPE ret; 305 306 if (hComponent != handle) 307 return OMX_ErrorBadParameter; 308 309 if (state != OMX_StateLoaded) 310 return OMX_ErrorIncorrectStateOperation; 311 312 FreePorts(); 313 314 free(handle); 315 316 appdata = NULL; 317 callbacks = NULL; 318 319 state = OMX_StateUnloaded; 320 return OMX_ErrorNone; 321} 322 323/* end of core methods & helpers */ 324 325/* 326 * component methods & helpers 327 */ 328OMX_ERRORTYPE ComponentBase::GetComponentVersion( 329 OMX_IN OMX_HANDLETYPE hComponent, 330 OMX_OUT OMX_STRING pComponentName, 331 OMX_OUT OMX_VERSIONTYPE* pComponentVersion, 332 OMX_OUT OMX_VERSIONTYPE* pSpecVersion, 333 OMX_OUT OMX_UUIDTYPE* pComponentUUID) 334{ 335 ComponentBase *cbase; 336 337 if (!hComponent) 338 return OMX_ErrorBadParameter; 339 340 cbase = static_cast<ComponentBase *> 341 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 342 if (!cbase) 343 return OMX_ErrorBadParameter; 344 345 return cbase->CBaseGetComponentVersion(hComponent, 346 pComponentName, 347 pComponentVersion, 348 pSpecVersion, 349 pComponentUUID); 350} 351 352OMX_ERRORTYPE ComponentBase::CBaseGetComponentVersion( 353 OMX_IN OMX_HANDLETYPE hComponent, 354 OMX_OUT OMX_STRING pComponentName, 355 OMX_OUT OMX_VERSIONTYPE* pComponentVersion, 356 OMX_OUT OMX_VERSIONTYPE* pSpecVersion, 357 OMX_OUT OMX_UUIDTYPE* pComponentUUID) 358{ 359 /* 360 * Todo 361 */ 362 363 return OMX_ErrorNotImplemented; 364} 365 366OMX_ERRORTYPE ComponentBase::SendCommand( 367 OMX_IN OMX_HANDLETYPE hComponent, 368 OMX_IN OMX_COMMANDTYPE Cmd, 369 OMX_IN OMX_U32 nParam1, 370 OMX_IN OMX_PTR pCmdData) 371{ 372 ComponentBase *cbase; 373 374 if (!hComponent) 375 return OMX_ErrorBadParameter; 376 377 cbase = static_cast<ComponentBase *> 378 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 379 if (!cbase) 380 return OMX_ErrorBadParameter; 381 382 return cbase->CBaseSendCommand(hComponent, Cmd, nParam1, pCmdData); 383} 384 385OMX_ERRORTYPE ComponentBase::CBaseSendCommand( 386 OMX_IN OMX_HANDLETYPE hComponent, 387 OMX_IN OMX_COMMANDTYPE Cmd, 388 OMX_IN OMX_U32 nParam1, 389 OMX_IN OMX_PTR pCmdData) 390{ 391 struct cmd_s *cmd; 392 393 if (hComponent != handle) 394 return OMX_ErrorInvalidComponent; 395 396 /* basic error check */ 397 switch (Cmd) { 398 case OMX_CommandStateSet: 399 /* 400 * Todo 401 */ 402 break; 403 case OMX_CommandFlush: { 404 OMX_U32 port_index = nParam1; 405 406 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 407 return OMX_ErrorBadPortIndex; 408 break; 409 } 410 case OMX_CommandPortDisable: 411 case OMX_CommandPortEnable: { 412 OMX_U32 port_index = nParam1; 413 414 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 415 return OMX_ErrorBadPortIndex; 416 break; 417 } 418 case OMX_CommandMarkBuffer: { 419 OMX_MARKTYPE *mark = (OMX_MARKTYPE *)pCmdData; 420 OMX_MARKTYPE *copiedmark; 421 OMX_U32 port_index = nParam1; 422 423 if (port_index > nr_ports-1) 424 return OMX_ErrorBadPortIndex; 425 426 if (!mark || !mark->hMarkTargetComponent) 427 return OMX_ErrorBadParameter; 428 429 copiedmark = (OMX_MARKTYPE *)malloc(sizeof(*copiedmark)); 430 if (!copiedmark) 431 return OMX_ErrorInsufficientResources; 432 433 copiedmark->hMarkTargetComponent = mark->hMarkTargetComponent; 434 copiedmark->pMarkData = mark->pMarkData; 435 pCmdData = (OMX_PTR)copiedmark; 436 break; 437 } 438 default: 439 LOGE("command %d not supported\n", Cmd); 440 return OMX_ErrorUnsupportedIndex; 441 } 442 443 cmd = (struct cmd_s *)malloc(sizeof(*cmd)); 444 if (!cmd) 445 return OMX_ErrorInsufficientResources; 446 447 cmd->cmd = Cmd; 448 cmd->param1 = nParam1; 449 cmd->cmddata = pCmdData; 450 451 return cmdwork->PushCmdQueue(cmd); 452} 453 454OMX_ERRORTYPE ComponentBase::GetParameter( 455 OMX_IN OMX_HANDLETYPE hComponent, 456 OMX_IN OMX_INDEXTYPE nParamIndex, 457 OMX_INOUT OMX_PTR pComponentParameterStructure) 458{ 459 ComponentBase *cbase; 460 461 if (!hComponent) 462 return OMX_ErrorBadParameter; 463 464 cbase = static_cast<ComponentBase *> 465 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 466 if (!cbase) 467 return OMX_ErrorBadParameter; 468 469 return cbase->CBaseGetParameter(hComponent, nParamIndex, 470 pComponentParameterStructure); 471} 472 473OMX_ERRORTYPE ComponentBase::CBaseGetParameter( 474 OMX_IN OMX_HANDLETYPE hComponent, 475 OMX_IN OMX_INDEXTYPE nParamIndex, 476 OMX_INOUT OMX_PTR pComponentParameterStructure) 477{ 478 OMX_ERRORTYPE ret = OMX_ErrorNone; 479 480 if (hComponent != handle) 481 return OMX_ErrorBadParameter; 482 483 switch (nParamIndex) { 484 case OMX_IndexParamAudioInit: 485 case OMX_IndexParamVideoInit: 486 case OMX_IndexParamImageInit: 487 case OMX_IndexParamOtherInit: { 488 OMX_PORT_PARAM_TYPE *p = 489 (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure; 490 491 ret = CheckTypeHeader(p, sizeof(*p)); 492 if (ret != OMX_ErrorNone) 493 return ret; 494 495 memcpy(p, &portparam, sizeof(*p)); 496 break; 497 } 498 case OMX_IndexParamPortDefinition: { 499 OMX_PARAM_PORTDEFINITIONTYPE *p = 500 (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; 501 OMX_U32 index = p->nPortIndex; 502 PortBase *port = NULL; 503 504 ret = CheckTypeHeader(p, sizeof(*p)); 505 if (ret != OMX_ErrorNone) 506 return ret; 507 508 if (index < nr_ports) 509 port = ports[index]; 510 511 if (!port) 512 return OMX_ErrorBadPortIndex; 513 514 memcpy(p, port->GetPortDefinition(), sizeof(*p)); 515 break; 516 } 517 case OMX_IndexParamCompBufferSupplier: 518 /* 519 * Todo 520 */ 521 522 ret = OMX_ErrorUnsupportedIndex; 523 break; 524 default: 525 ret = ComponentGetParameter(nParamIndex, pComponentParameterStructure); 526 } /* switch */ 527 528 return ret; 529} 530 531OMX_ERRORTYPE ComponentBase::SetParameter( 532 OMX_IN OMX_HANDLETYPE hComponent, 533 OMX_IN OMX_INDEXTYPE nIndex, 534 OMX_IN OMX_PTR pComponentParameterStructure) 535{ 536 ComponentBase *cbase; 537 538 if (!hComponent) 539 return OMX_ErrorBadParameter; 540 541 cbase = static_cast<ComponentBase *> 542 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 543 if (!cbase) 544 return OMX_ErrorBadParameter; 545 546 return cbase->CBaseSetParameter(hComponent, nIndex, 547 pComponentParameterStructure); 548} 549 550OMX_ERRORTYPE ComponentBase::CBaseSetParameter( 551 OMX_IN OMX_HANDLETYPE hComponent, 552 OMX_IN OMX_INDEXTYPE nIndex, 553 OMX_IN OMX_PTR pComponentParameterStructure) 554{ 555 OMX_ERRORTYPE ret = OMX_ErrorNone; 556 557 if (hComponent != handle) 558 return OMX_ErrorBadParameter; 559 560 switch (nIndex) { 561 case OMX_IndexParamAudioInit: 562 case OMX_IndexParamVideoInit: 563 case OMX_IndexParamImageInit: 564 case OMX_IndexParamOtherInit: 565 /* preventing clients from setting OMX_PORT_PARAM_TYPE */ 566 ret = OMX_ErrorUnsupportedIndex; 567 break; 568 case OMX_IndexParamPortDefinition: { 569 OMX_PARAM_PORTDEFINITIONTYPE *p = 570 (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; 571 OMX_U32 index = p->nPortIndex; 572 PortBase *port = NULL; 573 574 ret = CheckTypeHeader(p, sizeof(*p)); 575 if (ret != OMX_ErrorNone) 576 return ret; 577 578 if (index < nr_ports) 579 port = ports[index]; 580 581 if (!port) 582 return OMX_ErrorBadPortIndex; 583 584 if (port->IsEnabled()) { 585 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 586 return OMX_ErrorIncorrectStateOperation; 587 } 588 589 port->SetPortDefinition(p, false); 590 break; 591 } 592 case OMX_IndexParamCompBufferSupplier: 593 /* 594 * Todo 595 */ 596 597 ret = OMX_ErrorUnsupportedIndex; 598 break; 599 case OMX_IndexParamStandardComponentRole: { 600 OMX_PARAM_COMPONENTROLETYPE *p = 601 (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; 602 603 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 604 return OMX_ErrorIncorrectStateOperation; 605 606 ret = CheckTypeHeader(p, sizeof(*p)); 607 if (ret != OMX_ErrorNone) 608 return ret; 609 610 ret = SetWorkingRole((OMX_STRING)p->cRole); 611 if (ret != OMX_ErrorNone) 612 return ret; 613 614 if (ports) 615 FreePorts(); 616 617 ret = ApplyWorkingRole(); 618 if (ret != OMX_ErrorNone) { 619 SetWorkingRole(NULL); 620 return ret; 621 } 622 break; 623 } 624 default: 625 ret = ComponentSetParameter(nIndex, pComponentParameterStructure); 626 } /* switch */ 627 628 return ret; 629} 630 631OMX_ERRORTYPE ComponentBase::GetConfig( 632 OMX_IN OMX_HANDLETYPE hComponent, 633 OMX_IN OMX_INDEXTYPE nIndex, 634 OMX_INOUT OMX_PTR pComponentConfigStructure) 635{ 636 ComponentBase *cbase; 637 638 if (!hComponent) 639 return OMX_ErrorBadParameter; 640 641 cbase = static_cast<ComponentBase *> 642 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 643 if (!cbase) 644 return OMX_ErrorBadParameter; 645 646 return cbase->CBaseGetConfig(hComponent, nIndex, 647 pComponentConfigStructure); 648} 649 650OMX_ERRORTYPE ComponentBase::CBaseGetConfig( 651 OMX_IN OMX_HANDLETYPE hComponent, 652 OMX_IN OMX_INDEXTYPE nIndex, 653 OMX_INOUT OMX_PTR pComponentConfigStructure) 654{ 655 OMX_ERRORTYPE ret; 656 657 if (hComponent != handle) 658 return OMX_ErrorBadParameter; 659 660 switch (nIndex) { 661 default: 662 ret = ComponentGetConfig(nIndex, pComponentConfigStructure); 663 } 664 665 return ret; 666} 667 668OMX_ERRORTYPE ComponentBase::SetConfig( 669 OMX_IN OMX_HANDLETYPE hComponent, 670 OMX_IN OMX_INDEXTYPE nIndex, 671 OMX_IN OMX_PTR pComponentConfigStructure) 672{ 673 ComponentBase *cbase; 674 675 if (!hComponent) 676 return OMX_ErrorBadParameter; 677 678 cbase = static_cast<ComponentBase *> 679 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 680 if (!cbase) 681 return OMX_ErrorBadParameter; 682 683 return cbase->CBaseSetConfig(hComponent, nIndex, 684 pComponentConfigStructure); 685} 686 687OMX_ERRORTYPE ComponentBase::CBaseSetConfig( 688 OMX_IN OMX_HANDLETYPE hComponent, 689 OMX_IN OMX_INDEXTYPE nIndex, 690 OMX_IN OMX_PTR pComponentConfigStructure) 691{ 692 OMX_ERRORTYPE ret; 693 694 if (hComponent != handle) 695 return OMX_ErrorBadParameter; 696 697 switch (nIndex) { 698 default: 699 ret = ComponentSetConfig(nIndex, pComponentConfigStructure); 700 } 701 702 return ret; 703} 704 705OMX_ERRORTYPE ComponentBase::GetExtensionIndex( 706 OMX_IN OMX_HANDLETYPE hComponent, 707 OMX_IN OMX_STRING cParameterName, 708 OMX_OUT OMX_INDEXTYPE* pIndexType) 709{ 710 ComponentBase *cbase; 711 712 if (!hComponent) 713 return OMX_ErrorBadParameter; 714 715 cbase = static_cast<ComponentBase *> 716 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 717 if (!cbase) 718 return OMX_ErrorBadParameter; 719 720 return cbase->CBaseGetExtensionIndex(hComponent, cParameterName, 721 pIndexType); 722} 723 724OMX_ERRORTYPE ComponentBase::CBaseGetExtensionIndex( 725 OMX_IN OMX_HANDLETYPE hComponent, 726 OMX_IN OMX_STRING cParameterName, 727 OMX_OUT OMX_INDEXTYPE* pIndexType) 728{ 729 /* 730 * Todo 731 */ 732 733 return OMX_ErrorNotImplemented; 734} 735 736OMX_ERRORTYPE ComponentBase::GetState( 737 OMX_IN OMX_HANDLETYPE hComponent, 738 OMX_OUT OMX_STATETYPE* pState) 739{ 740 ComponentBase *cbase; 741 742 if (!hComponent) 743 return OMX_ErrorBadParameter; 744 745 cbase = static_cast<ComponentBase *> 746 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 747 if (!cbase) 748 return OMX_ErrorBadParameter; 749 750 return cbase->CBaseGetState(hComponent, pState); 751} 752 753OMX_ERRORTYPE ComponentBase::CBaseGetState( 754 OMX_IN OMX_HANDLETYPE hComponent, 755 OMX_OUT OMX_STATETYPE* pState) 756{ 757 if (hComponent != handle) 758 return OMX_ErrorBadParameter; 759 760 *pState = state; 761 return OMX_ErrorNone; 762} 763 764OMX_ERRORTYPE ComponentBase::ComponentTunnelRequest( 765 OMX_IN OMX_HANDLETYPE hComponent, 766 OMX_IN OMX_U32 nPort, 767 OMX_IN OMX_HANDLETYPE hTunneledComponent, 768 OMX_IN OMX_U32 nTunneledPort, 769 OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup) 770{ 771 ComponentBase *cbase; 772 773 if (!hComponent) 774 return OMX_ErrorBadParameter; 775 776 cbase = static_cast<ComponentBase *> 777 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 778 if (!cbase) 779 return OMX_ErrorBadParameter; 780 781 return cbase->CBaseComponentTunnelRequest(hComponent, nPort, 782 hTunneledComponent, 783 nTunneledPort, pTunnelSetup); 784} 785 786OMX_ERRORTYPE ComponentBase::CBaseComponentTunnelRequest( 787 OMX_IN OMX_HANDLETYPE hComp, 788 OMX_IN OMX_U32 nPort, 789 OMX_IN OMX_HANDLETYPE hTunneledComp, 790 OMX_IN OMX_U32 nTunneledPort, 791 OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup) 792{ 793 /* 794 * Todo 795 */ 796 797 return OMX_ErrorNotImplemented; 798} 799 800OMX_ERRORTYPE ComponentBase::UseBuffer( 801 OMX_IN OMX_HANDLETYPE hComponent, 802 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 803 OMX_IN OMX_U32 nPortIndex, 804 OMX_IN OMX_PTR pAppPrivate, 805 OMX_IN OMX_U32 nSizeBytes, 806 OMX_IN OMX_U8 *pBuffer) 807{ 808 ComponentBase *cbase; 809 810 if (!hComponent) 811 return OMX_ErrorBadParameter; 812 813 cbase = static_cast<ComponentBase *> 814 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 815 if (!cbase) 816 return OMX_ErrorBadParameter; 817 818 return cbase->CBaseUseBuffer(hComponent, ppBufferHdr, nPortIndex, 819 pAppPrivate, nSizeBytes, pBuffer); 820} 821 822OMX_ERRORTYPE ComponentBase::CBaseUseBuffer( 823 OMX_IN OMX_HANDLETYPE hComponent, 824 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 825 OMX_IN OMX_U32 nPortIndex, 826 OMX_IN OMX_PTR pAppPrivate, 827 OMX_IN OMX_U32 nSizeBytes, 828 OMX_IN OMX_U8 *pBuffer) 829{ 830 PortBase *port = NULL; 831 OMX_ERRORTYPE ret; 832 833 if (hComponent != handle) 834 return OMX_ErrorBadParameter; 835 836 if (!ppBufferHdr) 837 return OMX_ErrorBadParameter; 838 *ppBufferHdr = NULL; 839 840 if (!pBuffer) 841 return OMX_ErrorBadParameter; 842 843 if (ports) 844 if (nPortIndex < nr_ports) 845 port = ports[nPortIndex]; 846 847 if (!port) 848 return OMX_ErrorBadParameter; 849 850 if (port->IsEnabled()) { 851 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 852 return OMX_ErrorIncorrectStateOperation; 853 } 854 855 return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, 856 pBuffer); 857} 858 859OMX_ERRORTYPE ComponentBase::AllocateBuffer( 860 OMX_IN OMX_HANDLETYPE hComponent, 861 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 862 OMX_IN OMX_U32 nPortIndex, 863 OMX_IN OMX_PTR pAppPrivate, 864 OMX_IN OMX_U32 nSizeBytes) 865{ 866 ComponentBase *cbase; 867 868 if (!hComponent) 869 return OMX_ErrorBadParameter; 870 871 cbase = static_cast<ComponentBase *> 872 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 873 if (!cbase) 874 return OMX_ErrorBadParameter; 875 876 return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex, 877 pAppPrivate, nSizeBytes); 878} 879 880OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer( 881 OMX_IN OMX_HANDLETYPE hComponent, 882 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 883 OMX_IN OMX_U32 nPortIndex, 884 OMX_IN OMX_PTR pAppPrivate, 885 OMX_IN OMX_U32 nSizeBytes) 886{ 887 PortBase *port = NULL; 888 OMX_ERRORTYPE ret; 889 890 if (hComponent != handle) 891 return OMX_ErrorBadParameter; 892 893 if (!ppBuffer) 894 return OMX_ErrorBadParameter; 895 *ppBuffer = NULL; 896 897 if (ports) 898 if (nPortIndex < nr_ports) 899 port = ports[nPortIndex]; 900 901 if (!port) 902 return OMX_ErrorBadParameter; 903 904 if (port->IsEnabled()) { 905 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 906 return OMX_ErrorIncorrectStateOperation; 907 } 908 909 return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes); 910} 911 912OMX_ERRORTYPE ComponentBase::FreeBuffer( 913 OMX_IN OMX_HANDLETYPE hComponent, 914 OMX_IN OMX_U32 nPortIndex, 915 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 916{ 917 ComponentBase *cbase; 918 919 if (!hComponent) 920 return OMX_ErrorBadParameter; 921 922 cbase = static_cast<ComponentBase *> 923 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 924 if (!cbase) 925 return OMX_ErrorBadParameter; 926 927 return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer); 928} 929 930OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer( 931 OMX_IN OMX_HANDLETYPE hComponent, 932 OMX_IN OMX_U32 nPortIndex, 933 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 934{ 935 PortBase *port = NULL; 936 OMX_ERRORTYPE ret; 937 938 if (hComponent != handle) 939 return OMX_ErrorBadParameter; 940 941 if (!pBuffer) 942 return OMX_ErrorBadParameter; 943 944 if (ports) 945 if (nPortIndex < nr_ports) 946 port = ports[nPortIndex]; 947 948 if (!port) 949 return OMX_ErrorBadParameter; 950 951 return port->FreeBuffer(nPortIndex, pBuffer); 952} 953 954OMX_ERRORTYPE ComponentBase::EmptyThisBuffer( 955 OMX_IN OMX_HANDLETYPE hComponent, 956 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 957{ 958 ComponentBase *cbase; 959 960 if (!hComponent) 961 return OMX_ErrorBadParameter; 962 963 cbase = static_cast<ComponentBase *> 964 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 965 if (!cbase) 966 return OMX_ErrorBadParameter; 967 968 return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer); 969} 970 971OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer( 972 OMX_IN OMX_HANDLETYPE hComponent, 973 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 974{ 975 PortBase *port = NULL; 976 OMX_U32 port_index; 977 OMX_ERRORTYPE ret; 978 979 if ((hComponent != handle) || !pBuffer) 980 return OMX_ErrorBadParameter; 981 982 ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); 983 if (ret != OMX_ErrorNone) 984 return ret; 985 986 port_index = pBuffer->nInputPortIndex; 987 if (port_index == (OMX_U32)-1) 988 return OMX_ErrorBadParameter; 989 990 if (ports) 991 if (port_index < nr_ports) 992 port = ports[port_index]; 993 994 if (!port) 995 return OMX_ErrorBadParameter; 996 997 if (pBuffer->pInputPortPrivate != port) 998 return OMX_ErrorBadParameter; 999 1000 if (port->IsEnabled()) { 1001 if (state != OMX_StateIdle && state != OMX_StateExecuting && 1002 state != OMX_StatePause) 1003 return OMX_ErrorIncorrectStateOperation; 1004 } 1005 1006 if (!pBuffer->hMarkTargetComponent) { 1007 OMX_MARKTYPE *mark; 1008 1009 mark = port->PopMark(); 1010 if (mark) { 1011 pBuffer->hMarkTargetComponent = mark->hMarkTargetComponent; 1012 pBuffer->pMarkData = mark->pMarkData; 1013 free(mark); 1014 } 1015 } 1016 1017 ret = port->PushThisBuffer(pBuffer); 1018 if (ret == OMX_ErrorNone) 1019 bufferwork->ScheduleWork(this); 1020 1021 return ret; 1022} 1023 1024OMX_ERRORTYPE ComponentBase::FillThisBuffer( 1025 OMX_IN OMX_HANDLETYPE hComponent, 1026 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 1027{ 1028 ComponentBase *cbase; 1029 1030 if (!hComponent) 1031 return OMX_ErrorBadParameter; 1032 1033 cbase = static_cast<ComponentBase *> 1034 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1035 if (!cbase) 1036 return OMX_ErrorBadParameter; 1037 1038 return cbase->CBaseFillThisBuffer(hComponent, pBuffer); 1039} 1040 1041OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer( 1042 OMX_IN OMX_HANDLETYPE hComponent, 1043 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 1044{ 1045 PortBase *port = NULL; 1046 OMX_U32 port_index; 1047 OMX_ERRORTYPE ret; 1048 1049 if ((hComponent != handle) || !pBuffer) 1050 return OMX_ErrorBadParameter; 1051 1052 ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); 1053 if (ret != OMX_ErrorNone) 1054 return ret; 1055 1056 port_index = pBuffer->nOutputPortIndex; 1057 if (port_index == (OMX_U32)-1) 1058 return OMX_ErrorBadParameter; 1059 1060 if (ports) 1061 if (port_index < nr_ports) 1062 port = ports[port_index]; 1063 1064 if (!port) 1065 return OMX_ErrorBadParameter; 1066 1067 if (pBuffer->pOutputPortPrivate != port) 1068 return OMX_ErrorBadParameter; 1069 1070 if (port->IsEnabled()) { 1071 if (state != OMX_StateIdle && state != OMX_StateExecuting && 1072 state != OMX_StatePause) 1073 return OMX_ErrorIncorrectStateOperation; 1074 } 1075 1076 ret = port->PushThisBuffer(pBuffer); 1077 if (ret == OMX_ErrorNone) 1078 bufferwork->ScheduleWork(this); 1079 1080 return ret; 1081} 1082 1083OMX_ERRORTYPE ComponentBase::SetCallbacks( 1084 OMX_IN OMX_HANDLETYPE hComponent, 1085 OMX_IN OMX_CALLBACKTYPE* pCallbacks, 1086 OMX_IN OMX_PTR pAppData) 1087{ 1088 ComponentBase *cbase; 1089 1090 if (!hComponent) 1091 return OMX_ErrorBadParameter; 1092 1093 cbase = static_cast<ComponentBase *> 1094 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1095 if (!cbase) 1096 return OMX_ErrorBadParameter; 1097 1098 return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData); 1099} 1100 1101OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks( 1102 OMX_IN OMX_HANDLETYPE hComponent, 1103 OMX_IN OMX_CALLBACKTYPE *pCallbacks, 1104 OMX_IN OMX_PTR pAppData) 1105{ 1106 if (hComponent != handle) 1107 return OMX_ErrorBadParameter; 1108 1109 appdata = pAppData; 1110 callbacks = pCallbacks; 1111 1112 return OMX_ErrorNone; 1113} 1114 1115OMX_ERRORTYPE ComponentBase::ComponentDeInit( 1116 OMX_IN OMX_HANDLETYPE hComponent) 1117{ 1118 ComponentBase *cbase; 1119 1120 if (!hComponent) 1121 return OMX_ErrorBadParameter; 1122 1123 cbase = static_cast<ComponentBase *> 1124 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1125 if (!cbase) 1126 return OMX_ErrorBadParameter; 1127 1128 return cbase->CBaseComponentDeInit(hComponent); 1129} 1130 1131OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit( 1132 OMX_IN OMX_HANDLETYPE hComponent) 1133{ 1134 /* 1135 * Todo 1136 */ 1137 1138 return OMX_ErrorNotImplemented; 1139} 1140 1141OMX_ERRORTYPE ComponentBase::UseEGLImage( 1142 OMX_IN OMX_HANDLETYPE hComponent, 1143 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1144 OMX_IN OMX_U32 nPortIndex, 1145 OMX_IN OMX_PTR pAppPrivate, 1146 OMX_IN void* eglImage) 1147{ 1148 ComponentBase *cbase; 1149 1150 if (!hComponent) 1151 return OMX_ErrorBadParameter; 1152 1153 cbase = static_cast<ComponentBase *> 1154 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1155 if (!cbase) 1156 return OMX_ErrorBadParameter; 1157 1158 return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex, 1159 pAppPrivate, eglImage); 1160} 1161 1162OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage( 1163 OMX_IN OMX_HANDLETYPE hComponent, 1164 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1165 OMX_IN OMX_U32 nPortIndex, 1166 OMX_IN OMX_PTR pAppPrivate, 1167 OMX_IN void* eglImage) 1168{ 1169 /* 1170 * Todo 1171 */ 1172 1173 return OMX_ErrorNotImplemented; 1174} 1175 1176OMX_ERRORTYPE ComponentBase::ComponentRoleEnum( 1177 OMX_IN OMX_HANDLETYPE hComponent, 1178 OMX_OUT OMX_U8 *cRole, 1179 OMX_IN OMX_U32 nIndex) 1180{ 1181 ComponentBase *cbase; 1182 1183 if (!hComponent) 1184 return OMX_ErrorBadParameter; 1185 1186 cbase = static_cast<ComponentBase *> 1187 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1188 if (!cbase) 1189 return OMX_ErrorBadParameter; 1190 1191 return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex); 1192} 1193 1194OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum( 1195 OMX_IN OMX_HANDLETYPE hComponent, 1196 OMX_OUT OMX_U8 *cRole, 1197 OMX_IN OMX_U32 nIndex) 1198{ 1199 if (hComponent != (OMX_HANDLETYPE *)this->handle) 1200 return OMX_ErrorBadParameter; 1201 1202 if (nIndex > nr_roles) 1203 return OMX_ErrorBadParameter; 1204 1205 strncpy((char *)cRole, (const char *)roles[nIndex], 1206 OMX_MAX_STRINGNAME_SIZE); 1207 return OMX_ErrorNone; 1208} 1209 1210/* implement CmdHandlerInterface */ 1211void ComponentBase::CmdHandler(struct cmd_s *cmd) 1212{ 1213 switch (cmd->cmd) { 1214 case OMX_CommandStateSet: { 1215 OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1; 1216 1217 TransState(transition); 1218 break; 1219 } 1220 case OMX_CommandFlush: { 1221 OMX_U32 port_index = cmd->param1; 1222 1223 FlushPort(port_index, 1); 1224 break; 1225 } 1226 case OMX_CommandPortDisable: { 1227 OMX_U32 port_index = cmd->param1; 1228 1229 TransStatePort(port_index, PortBase::OMX_PortDisabled); 1230 break; 1231 } 1232 case OMX_CommandPortEnable: { 1233 OMX_U32 port_index = cmd->param1; 1234 1235 TransStatePort(port_index, PortBase::OMX_PortEnabled); 1236 break; 1237 } 1238 case OMX_CommandMarkBuffer: { 1239 OMX_U32 port_index = (OMX_U32)cmd->param1; 1240 OMX_MARKTYPE *mark = (OMX_MARKTYPE *)cmd->cmddata; 1241 1242 PushThisMark(port_index, mark); 1243 break; 1244 } 1245 default: 1246 LOGE("receive command 0x%08x that cannot be handled\n", cmd->cmd); 1247 break; 1248 } /* switch */ 1249} 1250 1251/* 1252 * SendCommand:OMX_CommandStateSet 1253 * called in CmdHandler or called in other parts of component for reporting 1254 * internal error (OMX_StateInvalid). 1255 */ 1256/* 1257 * Todo 1258 * Resource Management (OMX_StateWaitForResources) 1259 * for now, we never notify OMX_ErrorInsufficientResources, 1260 * so IL client doesn't try to set component' state OMX_StateWaitForResources 1261 */ 1262static const char *state_name[OMX_StateWaitForResources + 1] = { 1263 "OMX_StateInvalid", 1264 "OMX_StateLoaded", 1265 "OMX_StateIdle", 1266 "OMX_StateExecuting", 1267 "OMX_StatePause", 1268 "OMX_StateWaitForResources", 1269}; 1270 1271static inline const char *GetStateName(OMX_STATETYPE state) 1272{ 1273 if (state > OMX_StateWaitForResources) 1274 return "UnKnown"; 1275 1276 return state_name[state]; 1277} 1278 1279void ComponentBase::TransState(OMX_STATETYPE transition) 1280{ 1281 OMX_STATETYPE current = this->state; 1282 OMX_EVENTTYPE event; 1283 OMX_U32 data1, data2; 1284 OMX_ERRORTYPE ret; 1285 1286 LOGD("current state = %s, transition state = %s\n", 1287 GetStateName(current), GetStateName(transition)); 1288 1289 /* same state */ 1290 if (current == transition) { 1291 ret = OMX_ErrorSameState; 1292 goto notify_event; 1293 } 1294 1295 /* invalid state */ 1296 if (current == OMX_StateInvalid) { 1297 ret = OMX_ErrorInvalidState; 1298 goto notify_event; 1299 } 1300 1301 if (transition == OMX_StateLoaded) 1302 ret = TransStateToLoaded(current); 1303 else if (transition == OMX_StateIdle) 1304 ret = TransStateToIdle(current); 1305 else if (transition == OMX_StateExecuting) 1306 ret = TransStateToExecuting(current); 1307 else if (transition == OMX_StatePause) 1308 ret = TransStateToPause(current); 1309 else if (transition == OMX_StateInvalid) 1310 ret = TransStateToInvalid(current); 1311 else if (transition == OMX_StateWaitForResources) 1312 ret = TransStateToWaitForResources(current); 1313 else 1314 ret = OMX_ErrorIncorrectStateTransition; 1315 1316notify_event: 1317 if (ret == OMX_ErrorNone) { 1318 event = OMX_EventCmdComplete; 1319 data1 = OMX_CommandStateSet; 1320 data2 = transition; 1321 1322 state = transition; 1323 LOGD("transition from %s to %s completed\n", 1324 GetStateName(current), GetStateName(transition)); 1325 } 1326 else { 1327 event = OMX_EventError; 1328 data1 = ret; 1329 data2 = 0; 1330 1331 if (transition == OMX_StateInvalid || ret == OMX_ErrorInvalidState) { 1332 state = OMX_StateInvalid; 1333 LOGD("failed transition from %s to %s, current state is %s\n", 1334 GetStateName(current), GetStateName(transition), 1335 GetStateName(state)); 1336 } 1337 } 1338 1339 callbacks->EventHandler(handle, appdata, event, data1, data2, NULL); 1340 1341 /* WaitForResources workaround */ 1342 if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources) 1343 callbacks->EventHandler(handle, appdata, 1344 OMX_EventResourcesAcquired, 0, 0, NULL); 1345} 1346 1347inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current) 1348{ 1349 OMX_ERRORTYPE ret; 1350 1351 if (current == OMX_StateIdle) { 1352 OMX_U32 i; 1353 1354 for (i = 0; i < nr_ports; i++) 1355 ports[i]->WaitPortBufferCompletion(); 1356 1357 ret = ProcessorDeinit(); 1358 if (ret != OMX_ErrorNone) { 1359 LOGE("failed to ProcessorDeinit() (ret = 0x%08x)\n", ret); 1360 ret = OMX_ErrorInvalidState; 1361 goto out; 1362 } 1363 } 1364 else if (current == OMX_StateWaitForResources) { 1365 LOGE("state transition's requested from WaitForResources to " 1366 "Loaded\n"); 1367 1368 /* 1369 * from WaitForResources to Loaded considered from Loaded to Loaded. 1370 * do nothing 1371 */ 1372 1373 ret = OMX_ErrorNone; 1374 } 1375 else 1376 ret = OMX_ErrorIncorrectStateTransition; 1377 1378out: 1379 return ret; 1380} 1381 1382inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current) 1383{ 1384 OMX_ERRORTYPE ret; 1385 1386 if (current == OMX_StateLoaded) { 1387 OMX_U32 i; 1388 1389 ret = ProcessorInit(); 1390 if (ret != OMX_ErrorNone) { 1391 LOGE("failed to ProcessorInit() (ret = 0x%08x)\n", ret); 1392 ret = OMX_ErrorInvalidState; 1393 goto out; 1394 } 1395 1396 for (i = 0; i < nr_ports; i++) { 1397 if (ports[i]->IsEnabled()) 1398 ports[i]->WaitPortBufferCompletion(); 1399 } 1400 } 1401 else if ((current == OMX_StatePause) || (current == OMX_StateExecuting)) { 1402 FlushPort(OMX_ALL, 0); 1403 1404 bufferwork->CancelScheduledWork(this); 1405 bufferwork->StopWork(); 1406 1407 ret = ProcessorStop(); 1408 if (ret != OMX_ErrorNone) { 1409 LOGE("failed to ProcessorStop() (ret = 0x%08x)\n", ret); 1410 ret = OMX_ErrorInvalidState; 1411 goto out; 1412 } 1413 } 1414 else if (current == OMX_StateWaitForResources) { 1415 LOGE("state transition's requested from WaitForResources to Idle\n"); 1416 1417 /* same as Loaded to Idle BUT DO NOTHING for now */ 1418 1419 ret = OMX_ErrorNone; 1420 } 1421 else 1422 ret = OMX_ErrorIncorrectStateTransition; 1423 1424out: 1425 return ret; 1426} 1427 1428inline OMX_ERRORTYPE 1429ComponentBase::TransStateToExecuting(OMX_STATETYPE current) 1430{ 1431 OMX_ERRORTYPE ret; 1432 1433 if (current == OMX_StateIdle) { 1434 pthread_mutex_lock(&executing_lock); 1435 executing = true; 1436 pthread_mutex_unlock(&executing_lock); 1437 1438 bufferwork->StartWork(); 1439 1440 ret = ProcessorStart(); 1441 if (ret != OMX_ErrorNone) { 1442 LOGE("failed to ProcessorStart() (ret = 0x%08x)\n", ret); 1443 ret = OMX_ErrorInvalidState; 1444 goto out; 1445 } 1446 } 1447 else if (current == OMX_StatePause) { 1448 pthread_mutex_lock(&executing_lock); 1449 executing = true; 1450 pthread_cond_signal(&executing_wait); 1451 pthread_mutex_unlock(&executing_lock); 1452 1453 ret = ProcessorResume(); 1454 if (ret != OMX_ErrorNone) { 1455 LOGE("failed to ProcessorStart() (ret = 0x%08x)\n", ret); 1456 ret = OMX_ErrorInvalidState; 1457 goto out; 1458 } 1459 } 1460 else 1461 ret = OMX_ErrorIncorrectStateTransition; 1462 1463out: 1464 return ret; 1465} 1466 1467inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current) 1468{ 1469 OMX_ERRORTYPE ret; 1470 1471 if (current == OMX_StateIdle) { 1472 /* turn off executing flag */ 1473 pthread_mutex_lock(&executing_lock); 1474 executing = false; 1475 pthread_mutex_unlock(&executing_lock); 1476 1477 bufferwork->StartWork(); 1478 1479 ret = ProcessorStart(); 1480 if (ret != OMX_ErrorNone) { 1481 LOGE("failed to ProcessorPause() (ret = 0x%08x)\n", ret); 1482 ret = OMX_ErrorInvalidState; 1483 goto out; 1484 } 1485 } 1486 else if (current == OMX_StateExecuting) { 1487 pthread_mutex_lock(&executing_lock); 1488 executing = false; 1489 pthread_mutex_unlock(&executing_lock); 1490 1491 ret = ProcessorPause(); 1492 if (ret != OMX_ErrorNone) { 1493 LOGE("failed to ProcessorPause() (ret = 0x%08x)\n", ret); 1494 ret = OMX_ErrorInvalidState; 1495 goto out; 1496 } 1497 } 1498 else 1499 ret = OMX_ErrorIncorrectStateTransition; 1500 1501out: 1502 return ret; 1503} 1504 1505inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current) 1506{ 1507 OMX_ERRORTYPE ret = OMX_ErrorInvalidState; 1508 1509 /* 1510 * Todo 1511 * graceful escape 1512 */ 1513 1514 return ret; 1515} 1516 1517inline OMX_ERRORTYPE 1518ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current) 1519{ 1520 OMX_ERRORTYPE ret; 1521 1522 if (current == OMX_StateLoaded) { 1523 LOGE("state transition's requested from Loaded to WaitForResources\n"); 1524 ret = OMX_ErrorNone; 1525 } 1526 else 1527 ret = OMX_ErrorIncorrectStateTransition; 1528 1529 return ret; 1530} 1531 1532/* mark buffer */ 1533void ComponentBase::PushThisMark(OMX_U32 port_index, OMX_MARKTYPE *mark) 1534{ 1535 PortBase *port = NULL; 1536 OMX_EVENTTYPE event; 1537 OMX_U32 data1, data2; 1538 OMX_ERRORTYPE ret; 1539 1540 if (ports) 1541 if (port_index < nr_ports) 1542 port = ports[port_index]; 1543 1544 if (!port) { 1545 ret = OMX_ErrorBadPortIndex; 1546 goto notify_event; 1547 } 1548 1549 ret = port->PushMark(mark); 1550 if (ret != OMX_ErrorNone) { 1551 /* don't report OMX_ErrorInsufficientResources */ 1552 ret = OMX_ErrorUndefined; 1553 goto notify_event; 1554 } 1555 1556notify_event: 1557 if (ret == OMX_ErrorNone) { 1558 event = OMX_EventCmdComplete; 1559 data1 = OMX_CommandMarkBuffer; 1560 data2 = port_index; 1561 } 1562 else { 1563 event = OMX_EventError; 1564 data1 = ret; 1565 data2 = 0; 1566 } 1567 1568 callbacks->EventHandler(handle, appdata, event, data1, data2, NULL); 1569} 1570 1571void ComponentBase::FlushPort(OMX_U32 port_index, bool notify) 1572{ 1573 OMX_U32 i, from_index, to_index; 1574 1575 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 1576 return; 1577 1578 if (port_index == OMX_ALL) { 1579 from_index = 0; 1580 to_index = nr_ports - 1; 1581 } 1582 else { 1583 from_index = port_index; 1584 to_index = port_index; 1585 } 1586 1587 pthread_mutex_lock(&ports_block); 1588 for (i = from_index; i <= to_index; i++) { 1589 ports[i]->FlushPort(); 1590 if (notify) 1591 callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete, 1592 OMX_CommandFlush, i, NULL); 1593 } 1594 pthread_mutex_unlock(&ports_block); 1595} 1596 1597void ComponentBase::TransStatePort(OMX_U32 port_index, OMX_U8 state) 1598{ 1599 OMX_EVENTTYPE event; 1600 OMX_U32 data1, data2; 1601 OMX_U32 i, from_index, to_index; 1602 OMX_ERRORTYPE ret; 1603 1604 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 1605 return; 1606 1607 if (port_index == OMX_ALL) { 1608 from_index = 0; 1609 to_index = nr_ports - 1; 1610 } 1611 else { 1612 from_index = port_index; 1613 to_index = port_index; 1614 } 1615 1616 pthread_mutex_lock(&ports_block); 1617 for (i = from_index; i <= to_index; i++) { 1618 ret = ports[i]->TransState(state); 1619 if (ret == OMX_ErrorNone) { 1620 event = OMX_EventCmdComplete; 1621 if (state == PortBase::OMX_PortEnabled) 1622 data1 = OMX_CommandPortEnable; 1623 else 1624 data1 = OMX_CommandPortDisable; 1625 data2 = i; 1626 } 1627 else { 1628 event = OMX_EventError; 1629 data1 = ret; 1630 data2 = 0; 1631 } 1632 callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete, 1633 OMX_CommandPortDisable, data2, NULL); 1634 } 1635 pthread_mutex_unlock(&ports_block); 1636} 1637 1638/* set working role */ 1639OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role) 1640{ 1641 OMX_U32 i; 1642 1643 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1644 return OMX_ErrorIncorrectStateOperation; 1645 1646 if (!role) { 1647 working_role = NULL; 1648 return OMX_ErrorNone; 1649 } 1650 1651 for (i = 0; i < nr_roles; i++) { 1652 if (!strcmp((char *)&roles[i][0], role)) { 1653 working_role = (OMX_STRING)&roles[i][0]; 1654 return OMX_ErrorNone; 1655 } 1656 } 1657 1658 LOGE("cannot find %s role in %s\n", role, name); 1659 return OMX_ErrorBadParameter; 1660} 1661 1662/* apply a working role for a component having multiple roles */ 1663OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void) 1664{ 1665 OMX_U32 i; 1666 OMX_ERRORTYPE ret; 1667 1668 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1669 return OMX_ErrorIncorrectStateOperation; 1670 1671 if (!working_role) 1672 return OMX_ErrorBadParameter; 1673 1674 if (!callbacks || !appdata) 1675 return OMX_ErrorBadParameter; 1676 1677 ret = AllocatePorts(); 1678 if (ret != OMX_ErrorNone) { 1679 LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret); 1680 return ret; 1681 } 1682 1683 /* now we can access ports */ 1684 for (i = 0; i < nr_ports; i++) { 1685 ports[i]->SetOwner(handle); 1686 ports[i]->SetCallbacks(handle, callbacks, appdata); 1687 } 1688 1689 return OMX_ErrorNone; 1690} 1691 1692OMX_ERRORTYPE ComponentBase::AllocatePorts(void) 1693{ 1694 OMX_ERRORTYPE ret; 1695 1696 if (ports) 1697 return OMX_ErrorBadParameter; 1698 1699 ret = ComponentAllocatePorts(); 1700 if (ret != OMX_ErrorNone) { 1701 LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n", 1702 name, ret); 1703 return ret; 1704 } 1705 1706 return OMX_ErrorNone; 1707} 1708 1709/* called int FreeHandle() */ 1710OMX_ERRORTYPE ComponentBase::FreePorts(void) 1711{ 1712 if (ports) { 1713 OMX_U32 i, this_nr_ports = this->nr_ports; 1714 1715 for (i = 0; i < this_nr_ports; i++) { 1716 if (ports[i]) { 1717 OMX_MARKTYPE *mark; 1718 /* it should be empty before this */ 1719 while ((mark = ports[i]->PopMark())) 1720 free(mark); 1721 1722 delete ports[i]; 1723 ports[i] = NULL; 1724 } 1725 } 1726 delete []ports; 1727 ports = NULL; 1728 } 1729 1730 return OMX_ErrorNone; 1731} 1732 1733/* buffer processing */ 1734/* implement WorkableInterface */ 1735void ComponentBase::Work(void) 1736{ 1737 OMX_BUFFERHEADERTYPE *buffers[nr_ports]; 1738 bool retain[nr_ports]; 1739 OMX_U32 i; 1740 bool avail = false; 1741 1742 pthread_mutex_lock(&executing_lock); 1743 if (!executing) 1744 pthread_cond_wait(&executing_wait, &executing_lock); 1745 pthread_mutex_unlock(&executing_lock); 1746 1747 pthread_mutex_lock(&ports_block); 1748 1749 avail = IsAllBufferAvailable(); 1750 if (avail) { 1751 for (i = 0; i < nr_ports; i++) { 1752 buffers[i] = ports[i]->PopBuffer(); 1753 retain[i] = false; 1754 } 1755 1756 ProcessorProcess(buffers, &retain[0], nr_ports); 1757 PostProcessBuffer(buffers, &retain[0], nr_ports); 1758 1759 for (i = 0; i < nr_ports; i++) { 1760 if (retain[i]) 1761 ports[i]->RetainThisBuffer(buffers[i]); 1762 else 1763 ports[i]->ReturnThisBuffer(buffers[i]); 1764 } 1765 } 1766 ScheduleIfAllBufferAvailable(); 1767 1768 pthread_mutex_unlock(&ports_block); 1769} 1770 1771bool ComponentBase::IsAllBufferAvailable(void) 1772{ 1773 OMX_U32 i; 1774 OMX_U32 nr_avail = 0; 1775 1776 for (i = 0; i < nr_ports; i++) { 1777 OMX_U32 length = 0; 1778 1779 if (ports[i]->IsEnabled()) 1780 length = ports[i]->BufferQueueLength(); 1781 1782 if (length) 1783 nr_avail++; 1784 } 1785 1786 if (nr_avail == nr_ports) 1787 return true; 1788 else 1789 return false; 1790} 1791 1792void ComponentBase::ScheduleIfAllBufferAvailable(void) 1793{ 1794 bool avail; 1795 1796 avail = IsAllBufferAvailable(); 1797 if (avail) 1798 bufferwork->ScheduleWork(this); 1799} 1800 1801void ComponentBase::PostProcessBuffer(OMX_BUFFERHEADERTYPE **buffers, 1802 bool *retain, 1803 OMX_U32 nr_buffers) 1804{ 1805 OMX_U32 i; 1806 1807 for (i = 0; i < nr_ports; i++) { 1808 OMX_MARKTYPE *mark; 1809 1810 if (ports[i]->GetPortDirection() == OMX_DirInput) { 1811 bool is_sink_component = true; 1812 OMX_U32 j; 1813 1814 if (buffers[i]->hMarkTargetComponent) { 1815 if (buffers[i]->hMarkTargetComponent == handle) { 1816 callbacks->EventHandler(handle, appdata, OMX_EventMark, 1817 0, 0, buffers[i]->pMarkData); 1818 buffers[i]->hMarkTargetComponent = NULL; 1819 buffers[i]->pMarkData = NULL; 1820 } 1821 } 1822 1823 for (j = 0; j < nr_ports; j++) { 1824 if (j == i) 1825 continue; 1826 1827 if (ports[j]->GetPortDirection() == OMX_DirOutput) { 1828 if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS) { 1829 buffers[j]->nFlags |= OMX_BUFFERFLAG_EOS; 1830 buffers[i]->nFlags &= ~OMX_BUFFERFLAG_EOS; 1831 retain[i] = false; 1832 retain[j] = false; 1833 } 1834 1835 if (!buffers[j]->hMarkTargetComponent) { 1836 mark = ports[j]->PopMark(); 1837 if (mark) { 1838 buffers[j]->hMarkTargetComponent = 1839 mark->hMarkTargetComponent; 1840 buffers[j]->pMarkData = mark->pMarkData; 1841 free(mark); 1842 mark = NULL; 1843 } 1844 1845 if (buffers[i]->hMarkTargetComponent) { 1846 if (buffers[j]->hMarkTargetComponent) { 1847 mark = (OMX_MARKTYPE *) 1848 malloc(sizeof(*mark)); 1849 if (mark) { 1850 mark->hMarkTargetComponent = 1851 buffers[i]->hMarkTargetComponent; 1852 mark->pMarkData = buffers[i]->pMarkData; 1853 ports[j]->PushMark(mark); 1854 mark = NULL; 1855 buffers[i]->hMarkTargetComponent = NULL; 1856 buffers[i]->pMarkData = NULL; 1857 } 1858 } 1859 else { 1860 buffers[j]->hMarkTargetComponent = 1861 buffers[i]->hMarkTargetComponent; 1862 buffers[j]->pMarkData = buffers[i]->pMarkData; 1863 buffers[i]->hMarkTargetComponent = NULL; 1864 buffers[i]->pMarkData = NULL; 1865 } 1866 } 1867 } 1868 else { 1869 if (buffers[i]->hMarkTargetComponent) { 1870 mark = (OMX_MARKTYPE *)malloc(sizeof(*mark)); 1871 if (mark) { 1872 mark->hMarkTargetComponent = 1873 buffers[i]->hMarkTargetComponent; 1874 mark->pMarkData = buffers[i]->pMarkData; 1875 ports[j]->PushMark(mark); 1876 mark = NULL; 1877 buffers[i]->hMarkTargetComponent = NULL; 1878 buffers[i]->pMarkData = NULL; 1879 } 1880 } 1881 } 1882 is_sink_component = false; 1883 } 1884 } 1885 1886 if (is_sink_component) { 1887 if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS) { 1888 callbacks->EventHandler(handle, appdata, 1889 OMX_EventBufferFlag, 1890 i, buffers[i]->nFlags, NULL); 1891 retain[i] = false; 1892 } 1893 } 1894 } 1895 else if (ports[i]->GetPortDirection() == OMX_DirOutput) { 1896 bool is_source_component = true; 1897 OMX_U32 j; 1898 1899 if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS) { 1900 callbacks->EventHandler(handle, appdata, 1901 OMX_EventBufferFlag, 1902 i, buffers[i]->nFlags, NULL); 1903 retain[i] = false; 1904 } 1905 1906 for (j = 0; j < nr_ports; j++) { 1907 if (j == i) 1908 continue; 1909 1910 if (ports[j]->GetPortDirection() == OMX_DirInput) 1911 is_source_component = false; 1912 } 1913 1914 if (is_source_component) { 1915 if (!retain[i]) { 1916 mark = ports[i]->PopMark(); 1917 if (mark) { 1918 buffers[i]->hMarkTargetComponent = 1919 mark->hMarkTargetComponent; 1920 buffers[i]->pMarkData = mark->pMarkData; 1921 free(mark); 1922 mark = NULL; 1923 1924 if (buffers[i]->hMarkTargetComponent == handle) { 1925 callbacks->EventHandler(handle, appdata, 1926 OMX_EventMark, 0, 0, 1927 buffers[i]->pMarkData); 1928 buffers[i]->hMarkTargetComponent = NULL; 1929 buffers[i]->pMarkData = NULL; 1930 } 1931 } 1932 } 1933 } 1934 } 1935 else { 1936 LOGE("%s(): fatal error unknown port direction (0x%08x)\n", 1937 __func__, ports[i]->GetPortDirection()); 1938 } 1939 } 1940} 1941 1942/* processor default callbacks */ 1943OMX_ERRORTYPE ComponentBase::ProcessorInit(void) 1944{ 1945 return OMX_ErrorNone; 1946} 1947OMX_ERRORTYPE ComponentBase::ProcessorDeinit(void) 1948{ 1949 return OMX_ErrorNone; 1950} 1951 1952OMX_ERRORTYPE ComponentBase::ProcessorStart(void) 1953{ 1954 return OMX_ErrorNone; 1955} 1956 1957OMX_ERRORTYPE ComponentBase::ProcessorStop(void) 1958{ 1959 return OMX_ErrorNone; 1960} 1961 1962OMX_ERRORTYPE ComponentBase::ProcessorPause(void) 1963{ 1964 return OMX_ErrorNone; 1965} 1966 1967OMX_ERRORTYPE ComponentBase::ProcessorResume(void) 1968{ 1969 return OMX_ErrorNone; 1970} 1971 1972/* end of processor callbacks */ 1973 1974/* helper for derived class */ 1975const OMX_STRING ComponentBase::GetWorkingRole(void) 1976{ 1977 return &working_role[0]; 1978} 1979 1980const OMX_COMPONENTTYPE *ComponentBase::GetComponentHandle(void) 1981{ 1982 return handle; 1983} 1984 1985/* end of component methods & helpers */ 1986 1987/* 1988 * omx header manipuation 1989 */ 1990void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size) 1991{ 1992 OMX_U32 *nsize; 1993 OMX_VERSIONTYPE *nversion; 1994 1995 if (!type) 1996 return; 1997 1998 nsize = (OMX_U32 *)type; 1999 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 2000 2001 *nsize = size; 2002 nversion->nVersion = OMX_SPEC_VERSION; 2003} 2004 2005OMX_ERRORTYPE ComponentBase::CheckTypeHeader(const OMX_PTR type, OMX_U32 size) 2006{ 2007 OMX_U32 *nsize; 2008 OMX_VERSIONTYPE *nversion; 2009 2010 if (!type) 2011 return OMX_ErrorBadParameter; 2012 2013 nsize = (OMX_U32 *)type; 2014 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 2015 2016 if (*nsize != size) 2017 return OMX_ErrorBadParameter; 2018 2019 if (nversion->nVersion != OMX_SPEC_VERSION) 2020 return OMX_ErrorVersionMismatch; 2021 2022 return OMX_ErrorNone; 2023} 2024 2025/* 2026 * query_roles helper 2027 */ 2028OMX_ERRORTYPE ComponentBase::QueryRolesHelper( 2029 OMX_U32 nr_comp_roles, 2030 const OMX_U8 **comp_roles, 2031 OMX_U32 *nr_roles, OMX_U8 **roles) 2032{ 2033 OMX_U32 i; 2034 2035 if (!roles) { 2036 *nr_roles = nr_comp_roles; 2037 return OMX_ErrorNone; 2038 } 2039 2040 if (!nr_roles || (*nr_roles != nr_comp_roles) || !roles) 2041 return OMX_ErrorBadParameter; 2042 2043 for (i = 0; i < nr_comp_roles; i++) { 2044 if (!roles[i]) 2045 break; 2046 2047 strncpy((OMX_STRING)&roles[i][0], 2048 (const OMX_STRING)&comp_roles[i][0], OMX_MAX_STRINGNAME_SIZE); 2049 } 2050 2051 if (i != nr_comp_roles) 2052 return OMX_ErrorBadParameter; 2053 2054 *nr_roles = nr_comp_roles; 2055 return OMX_ErrorNone; 2056} 2057 2058/* end of ComponentBase */ 2059