componentbase.cpp revision fb74fc90d40dadb1a607b3e81a2f271845fcd659
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 1406 if (current == OMX_StatePause) { 1407 pthread_mutex_lock(&executing_lock); 1408 executing = true; 1409 pthread_cond_signal(&executing_wait); 1410 pthread_mutex_unlock(&executing_lock); 1411 } 1412 1413 bufferwork->StopWork(); 1414 1415 ret = ProcessorStop(); 1416 if (ret != OMX_ErrorNone) { 1417 LOGE("failed to ProcessorStop() (ret = 0x%08x)\n", ret); 1418 ret = OMX_ErrorInvalidState; 1419 goto out; 1420 } 1421 } 1422 else if (current == OMX_StateWaitForResources) { 1423 LOGE("state transition's requested from WaitForResources to Idle\n"); 1424 1425 /* same as Loaded to Idle BUT DO NOTHING for now */ 1426 1427 ret = OMX_ErrorNone; 1428 } 1429 else 1430 ret = OMX_ErrorIncorrectStateTransition; 1431 1432out: 1433 return ret; 1434} 1435 1436inline OMX_ERRORTYPE 1437ComponentBase::TransStateToExecuting(OMX_STATETYPE current) 1438{ 1439 OMX_ERRORTYPE ret; 1440 1441 if (current == OMX_StateIdle) { 1442 pthread_mutex_lock(&executing_lock); 1443 executing = true; 1444 pthread_mutex_unlock(&executing_lock); 1445 1446 bufferwork->StartWork(); 1447 1448 ret = ProcessorStart(); 1449 if (ret != OMX_ErrorNone) { 1450 LOGE("failed to ProcessorStart() (ret = 0x%08x)\n", ret); 1451 ret = OMX_ErrorInvalidState; 1452 goto out; 1453 } 1454 } 1455 else if (current == OMX_StatePause) { 1456 pthread_mutex_lock(&executing_lock); 1457 executing = true; 1458 pthread_cond_signal(&executing_wait); 1459 pthread_mutex_unlock(&executing_lock); 1460 1461 ret = ProcessorResume(); 1462 if (ret != OMX_ErrorNone) { 1463 LOGE("failed to ProcessorStart() (ret = 0x%08x)\n", ret); 1464 ret = OMX_ErrorInvalidState; 1465 goto out; 1466 } 1467 } 1468 else 1469 ret = OMX_ErrorIncorrectStateTransition; 1470 1471out: 1472 return ret; 1473} 1474 1475inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current) 1476{ 1477 OMX_ERRORTYPE ret; 1478 1479 if (current == OMX_StateIdle) { 1480 /* turn off executing flag */ 1481 pthread_mutex_lock(&executing_lock); 1482 executing = false; 1483 pthread_mutex_unlock(&executing_lock); 1484 1485 bufferwork->StartWork(); 1486 1487 ret = ProcessorStart(); 1488 if (ret != OMX_ErrorNone) { 1489 LOGE("failed to ProcessorPause() (ret = 0x%08x)\n", ret); 1490 ret = OMX_ErrorInvalidState; 1491 goto out; 1492 } 1493 } 1494 else if (current == OMX_StateExecuting) { 1495 pthread_mutex_lock(&executing_lock); 1496 executing = false; 1497 pthread_mutex_unlock(&executing_lock); 1498 1499 ret = ProcessorPause(); 1500 if (ret != OMX_ErrorNone) { 1501 LOGE("failed to ProcessorPause() (ret = 0x%08x)\n", ret); 1502 ret = OMX_ErrorInvalidState; 1503 goto out; 1504 } 1505 } 1506 else 1507 ret = OMX_ErrorIncorrectStateTransition; 1508 1509out: 1510 return ret; 1511} 1512 1513inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current) 1514{ 1515 OMX_ERRORTYPE ret = OMX_ErrorInvalidState; 1516 1517 /* 1518 * Todo 1519 * graceful escape 1520 */ 1521 1522 return ret; 1523} 1524 1525inline OMX_ERRORTYPE 1526ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current) 1527{ 1528 OMX_ERRORTYPE ret; 1529 1530 if (current == OMX_StateLoaded) { 1531 LOGE("state transition's requested from Loaded to WaitForResources\n"); 1532 ret = OMX_ErrorNone; 1533 } 1534 else 1535 ret = OMX_ErrorIncorrectStateTransition; 1536 1537 return ret; 1538} 1539 1540/* mark buffer */ 1541void ComponentBase::PushThisMark(OMX_U32 port_index, OMX_MARKTYPE *mark) 1542{ 1543 PortBase *port = NULL; 1544 OMX_EVENTTYPE event; 1545 OMX_U32 data1, data2; 1546 OMX_ERRORTYPE ret; 1547 1548 if (ports) 1549 if (port_index < nr_ports) 1550 port = ports[port_index]; 1551 1552 if (!port) { 1553 ret = OMX_ErrorBadPortIndex; 1554 goto notify_event; 1555 } 1556 1557 ret = port->PushMark(mark); 1558 if (ret != OMX_ErrorNone) { 1559 /* don't report OMX_ErrorInsufficientResources */ 1560 ret = OMX_ErrorUndefined; 1561 goto notify_event; 1562 } 1563 1564notify_event: 1565 if (ret == OMX_ErrorNone) { 1566 event = OMX_EventCmdComplete; 1567 data1 = OMX_CommandMarkBuffer; 1568 data2 = port_index; 1569 } 1570 else { 1571 event = OMX_EventError; 1572 data1 = ret; 1573 data2 = 0; 1574 } 1575 1576 callbacks->EventHandler(handle, appdata, event, data1, data2, NULL); 1577} 1578 1579void ComponentBase::FlushPort(OMX_U32 port_index, bool notify) 1580{ 1581 OMX_U32 i, from_index, to_index; 1582 1583 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 1584 return; 1585 1586 if (port_index == OMX_ALL) { 1587 from_index = 0; 1588 to_index = nr_ports - 1; 1589 } 1590 else { 1591 from_index = port_index; 1592 to_index = port_index; 1593 } 1594 1595 pthread_mutex_lock(&ports_block); 1596 for (i = from_index; i <= to_index; i++) { 1597 ports[i]->FlushPort(); 1598 if (notify) 1599 callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete, 1600 OMX_CommandFlush, i, NULL); 1601 } 1602 pthread_mutex_unlock(&ports_block); 1603} 1604 1605void ComponentBase::TransStatePort(OMX_U32 port_index, OMX_U8 state) 1606{ 1607 OMX_EVENTTYPE event; 1608 OMX_U32 data1, data2; 1609 OMX_U32 i, from_index, to_index; 1610 OMX_ERRORTYPE ret; 1611 1612 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 1613 return; 1614 1615 if (port_index == OMX_ALL) { 1616 from_index = 0; 1617 to_index = nr_ports - 1; 1618 } 1619 else { 1620 from_index = port_index; 1621 to_index = port_index; 1622 } 1623 1624 pthread_mutex_lock(&ports_block); 1625 for (i = from_index; i <= to_index; i++) { 1626 ret = ports[i]->TransState(state); 1627 if (ret == OMX_ErrorNone) { 1628 event = OMX_EventCmdComplete; 1629 if (state == PortBase::OMX_PortEnabled) 1630 data1 = OMX_CommandPortEnable; 1631 else 1632 data1 = OMX_CommandPortDisable; 1633 data2 = i; 1634 } 1635 else { 1636 event = OMX_EventError; 1637 data1 = ret; 1638 data2 = 0; 1639 } 1640 callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete, 1641 OMX_CommandPortDisable, data2, NULL); 1642 } 1643 pthread_mutex_unlock(&ports_block); 1644} 1645 1646/* set working role */ 1647OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role) 1648{ 1649 OMX_U32 i; 1650 1651 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1652 return OMX_ErrorIncorrectStateOperation; 1653 1654 if (!role) { 1655 working_role = NULL; 1656 return OMX_ErrorNone; 1657 } 1658 1659 for (i = 0; i < nr_roles; i++) { 1660 if (!strcmp((char *)&roles[i][0], role)) { 1661 working_role = (OMX_STRING)&roles[i][0]; 1662 return OMX_ErrorNone; 1663 } 1664 } 1665 1666 LOGE("cannot find %s role in %s\n", role, name); 1667 return OMX_ErrorBadParameter; 1668} 1669 1670/* apply a working role for a component having multiple roles */ 1671OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void) 1672{ 1673 OMX_U32 i; 1674 OMX_ERRORTYPE ret; 1675 1676 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1677 return OMX_ErrorIncorrectStateOperation; 1678 1679 if (!working_role) 1680 return OMX_ErrorBadParameter; 1681 1682 if (!callbacks || !appdata) 1683 return OMX_ErrorBadParameter; 1684 1685 ret = AllocatePorts(); 1686 if (ret != OMX_ErrorNone) { 1687 LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret); 1688 return ret; 1689 } 1690 1691 /* now we can access ports */ 1692 for (i = 0; i < nr_ports; i++) { 1693 ports[i]->SetOwner(handle); 1694 ports[i]->SetCallbacks(handle, callbacks, appdata); 1695 } 1696 1697 return OMX_ErrorNone; 1698} 1699 1700OMX_ERRORTYPE ComponentBase::AllocatePorts(void) 1701{ 1702 OMX_ERRORTYPE ret; 1703 1704 if (ports) 1705 return OMX_ErrorBadParameter; 1706 1707 ret = ComponentAllocatePorts(); 1708 if (ret != OMX_ErrorNone) { 1709 LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n", 1710 name, ret); 1711 return ret; 1712 } 1713 1714 return OMX_ErrorNone; 1715} 1716 1717/* called int FreeHandle() */ 1718OMX_ERRORTYPE ComponentBase::FreePorts(void) 1719{ 1720 if (ports) { 1721 OMX_U32 i, this_nr_ports = this->nr_ports; 1722 1723 for (i = 0; i < this_nr_ports; i++) { 1724 if (ports[i]) { 1725 OMX_MARKTYPE *mark; 1726 /* it should be empty before this */ 1727 while ((mark = ports[i]->PopMark())) 1728 free(mark); 1729 1730 delete ports[i]; 1731 ports[i] = NULL; 1732 } 1733 } 1734 delete []ports; 1735 ports = NULL; 1736 } 1737 1738 return OMX_ErrorNone; 1739} 1740 1741/* buffer processing */ 1742/* implement WorkableInterface */ 1743void ComponentBase::Work(void) 1744{ 1745 OMX_BUFFERHEADERTYPE *buffers[nr_ports]; 1746 bool retain[nr_ports]; 1747 OMX_U32 i; 1748 bool avail = false; 1749 1750 pthread_mutex_lock(&executing_lock); 1751 if (!executing) 1752 pthread_cond_wait(&executing_wait, &executing_lock); 1753 pthread_mutex_unlock(&executing_lock); 1754 1755 pthread_mutex_lock(&ports_block); 1756 1757 avail = IsAllBufferAvailable(); 1758 if (avail) { 1759 for (i = 0; i < nr_ports; i++) { 1760 buffers[i] = ports[i]->PopBuffer(); 1761 retain[i] = false; 1762 } 1763 1764 ProcessorProcess(buffers, &retain[0], nr_ports); 1765 PostProcessBuffer(buffers, &retain[0], nr_ports); 1766 1767 for (i = 0; i < nr_ports; i++) { 1768 if (retain[i]) 1769 ports[i]->RetainThisBuffer(buffers[i]); 1770 else 1771 ports[i]->ReturnThisBuffer(buffers[i]); 1772 } 1773 } 1774 ScheduleIfAllBufferAvailable(); 1775 pthread_mutex_unlock(&ports_block); 1776} 1777 1778bool ComponentBase::IsAllBufferAvailable(void) 1779{ 1780 OMX_U32 i; 1781 OMX_U32 nr_avail = 0; 1782 1783 for (i = 0; i < nr_ports; i++) { 1784 OMX_U32 length = 0; 1785 1786 if (ports[i]->IsEnabled()) 1787 length = ports[i]->BufferQueueLength(); 1788 1789 if (length) 1790 nr_avail++; 1791 } 1792 1793 if (nr_avail == nr_ports) 1794 return true; 1795 else 1796 return false; 1797} 1798 1799void ComponentBase::ScheduleIfAllBufferAvailable(void) 1800{ 1801 bool avail; 1802 1803 avail = IsAllBufferAvailable(); 1804 if (avail) 1805 bufferwork->ScheduleWork(this); 1806} 1807 1808void ComponentBase::PostProcessBuffer(OMX_BUFFERHEADERTYPE **buffers, 1809 bool *retain, 1810 OMX_U32 nr_buffers) 1811{ 1812 OMX_U32 i; 1813 1814 for (i = 0; i < nr_ports; i++) { 1815 OMX_MARKTYPE *mark; 1816 1817 if (ports[i]->GetPortDirection() == OMX_DirInput) { 1818 bool is_sink_component = true; 1819 OMX_U32 j; 1820 1821 if (buffers[i]->hMarkTargetComponent) { 1822 if (buffers[i]->hMarkTargetComponent == handle) { 1823 callbacks->EventHandler(handle, appdata, OMX_EventMark, 1824 0, 0, buffers[i]->pMarkData); 1825 buffers[i]->hMarkTargetComponent = NULL; 1826 buffers[i]->pMarkData = NULL; 1827 } 1828 } 1829 1830 for (j = 0; j < nr_ports; j++) { 1831 if (j == i) 1832 continue; 1833 1834 if (ports[j]->GetPortDirection() == OMX_DirOutput) { 1835 if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS) { 1836 buffers[j]->nFlags |= OMX_BUFFERFLAG_EOS; 1837 buffers[i]->nFlags &= ~OMX_BUFFERFLAG_EOS; 1838 retain[i] = false; 1839 retain[j] = false; 1840 } 1841 1842 if (!buffers[j]->hMarkTargetComponent) { 1843 mark = ports[j]->PopMark(); 1844 if (mark) { 1845 buffers[j]->hMarkTargetComponent = 1846 mark->hMarkTargetComponent; 1847 buffers[j]->pMarkData = mark->pMarkData; 1848 free(mark); 1849 mark = NULL; 1850 } 1851 1852 if (buffers[i]->hMarkTargetComponent) { 1853 if (buffers[j]->hMarkTargetComponent) { 1854 mark = (OMX_MARKTYPE *) 1855 malloc(sizeof(*mark)); 1856 if (mark) { 1857 mark->hMarkTargetComponent = 1858 buffers[i]->hMarkTargetComponent; 1859 mark->pMarkData = buffers[i]->pMarkData; 1860 ports[j]->PushMark(mark); 1861 mark = NULL; 1862 buffers[i]->hMarkTargetComponent = NULL; 1863 buffers[i]->pMarkData = NULL; 1864 } 1865 } 1866 else { 1867 buffers[j]->hMarkTargetComponent = 1868 buffers[i]->hMarkTargetComponent; 1869 buffers[j]->pMarkData = buffers[i]->pMarkData; 1870 buffers[i]->hMarkTargetComponent = NULL; 1871 buffers[i]->pMarkData = NULL; 1872 } 1873 } 1874 } 1875 else { 1876 if (buffers[i]->hMarkTargetComponent) { 1877 mark = (OMX_MARKTYPE *)malloc(sizeof(*mark)); 1878 if (mark) { 1879 mark->hMarkTargetComponent = 1880 buffers[i]->hMarkTargetComponent; 1881 mark->pMarkData = buffers[i]->pMarkData; 1882 ports[j]->PushMark(mark); 1883 mark = NULL; 1884 buffers[i]->hMarkTargetComponent = NULL; 1885 buffers[i]->pMarkData = NULL; 1886 } 1887 } 1888 } 1889 is_sink_component = false; 1890 } 1891 } 1892 1893 if (is_sink_component) { 1894 if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS) { 1895 callbacks->EventHandler(handle, appdata, 1896 OMX_EventBufferFlag, 1897 i, buffers[i]->nFlags, NULL); 1898 retain[i] = false; 1899 } 1900 } 1901 } 1902 else if (ports[i]->GetPortDirection() == OMX_DirOutput) { 1903 bool is_source_component = true; 1904 OMX_U32 j; 1905 1906 if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS) { 1907 callbacks->EventHandler(handle, appdata, 1908 OMX_EventBufferFlag, 1909 i, buffers[i]->nFlags, NULL); 1910 retain[i] = false; 1911 } 1912 1913 for (j = 0; j < nr_ports; j++) { 1914 if (j == i) 1915 continue; 1916 1917 if (ports[j]->GetPortDirection() == OMX_DirInput) 1918 is_source_component = false; 1919 } 1920 1921 if (is_source_component) { 1922 if (!retain[i]) { 1923 mark = ports[i]->PopMark(); 1924 if (mark) { 1925 buffers[i]->hMarkTargetComponent = 1926 mark->hMarkTargetComponent; 1927 buffers[i]->pMarkData = mark->pMarkData; 1928 free(mark); 1929 mark = NULL; 1930 1931 if (buffers[i]->hMarkTargetComponent == handle) { 1932 callbacks->EventHandler(handle, appdata, 1933 OMX_EventMark, 0, 0, 1934 buffers[i]->pMarkData); 1935 buffers[i]->hMarkTargetComponent = NULL; 1936 buffers[i]->pMarkData = NULL; 1937 } 1938 } 1939 } 1940 } 1941 } 1942 else { 1943 LOGE("%s(): fatal error unknown port direction (0x%08x)\n", 1944 __func__, ports[i]->GetPortDirection()); 1945 } 1946 } 1947} 1948 1949/* processor default callbacks */ 1950OMX_ERRORTYPE ComponentBase::ProcessorInit(void) 1951{ 1952 return OMX_ErrorNone; 1953} 1954OMX_ERRORTYPE ComponentBase::ProcessorDeinit(void) 1955{ 1956 return OMX_ErrorNone; 1957} 1958 1959OMX_ERRORTYPE ComponentBase::ProcessorStart(void) 1960{ 1961 return OMX_ErrorNone; 1962} 1963 1964OMX_ERRORTYPE ComponentBase::ProcessorStop(void) 1965{ 1966 return OMX_ErrorNone; 1967} 1968 1969OMX_ERRORTYPE ComponentBase::ProcessorPause(void) 1970{ 1971 return OMX_ErrorNone; 1972} 1973 1974OMX_ERRORTYPE ComponentBase::ProcessorResume(void) 1975{ 1976 return OMX_ErrorNone; 1977} 1978 1979/* end of processor callbacks */ 1980 1981/* helper for derived class */ 1982const OMX_STRING ComponentBase::GetWorkingRole(void) 1983{ 1984 return &working_role[0]; 1985} 1986 1987const OMX_COMPONENTTYPE *ComponentBase::GetComponentHandle(void) 1988{ 1989 return handle; 1990} 1991 1992void ComponentBase::DumpBuffer(const OMX_BUFFERHEADERTYPE *bufferheader) 1993{ 1994 OMX_U8 *pbuffer = bufferheader->pBuffer, *p; 1995 OMX_U32 offset = bufferheader->nOffset; 1996 OMX_U32 alloc_len = bufferheader->nAllocLen; 1997 OMX_U32 filled_len = bufferheader->nFilledLen; 1998 OMX_U32 left = filled_len, oneline; 1999 OMX_U32 index = 0, i; 2000 /* 0x%04lx: %02x %02x .. (n = 16)\n\0 */ 2001 char prbuffer[8 + 3 * 0x10 + 2], *pp; 2002 OMX_U32 prbuffer_len; 2003 2004 LOGD("Componant %s DumpBuffer\n", name); 2005 LOGD("%s port index = %lu", 2006 (bufferheader->nInputPortIndex != 0x7fffffff) ? "input" : "output", 2007 (bufferheader->nInputPortIndex != 0x7fffffff) ? 2008 bufferheader->nInputPortIndex : bufferheader->nOutputPortIndex); 2009 LOGD("nAllocLen = %lu, nOffset = %lu, nFilledLen = %lu\n", 2010 alloc_len, offset, filled_len); 2011 LOGD("nTimeStamp = %lld, nTickCount = %lu", 2012 bufferheader->nTimeStamp, 2013 bufferheader->nTickCount); 2014 LOGD("nFlags = 0x%08lx\n", bufferheader->nFlags); 2015 2016 if (!pbuffer || !alloc_len || !filled_len) 2017 return; 2018 2019 if (offset + filled_len > alloc_len) 2020 return; 2021 2022 p = pbuffer + offset; 2023 while (left) { 2024 oneline = left > 0x10 ? 0x10 : left; /* 16 items per 1 line */ 2025 pp += sprintf(pp, "0x%04lx: ", index); 2026 for (i = 0; i < oneline; i++) 2027 pp += sprintf(pp, " %02x", *(p + i)); 2028 pp += sprintf(pp, "\n"); 2029 *pp = '\0'; 2030 2031 index += 0x10; 2032 p += oneline; 2033 left -= oneline; 2034 2035 pp = &prbuffer[0]; 2036 LOGD("%s", pp); 2037 } 2038} 2039 2040/* end of component methods & helpers */ 2041 2042/* 2043 * omx header manipuation 2044 */ 2045void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size) 2046{ 2047 OMX_U32 *nsize; 2048 OMX_VERSIONTYPE *nversion; 2049 2050 if (!type) 2051 return; 2052 2053 nsize = (OMX_U32 *)type; 2054 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 2055 2056 *nsize = size; 2057 nversion->nVersion = OMX_SPEC_VERSION; 2058} 2059 2060OMX_ERRORTYPE ComponentBase::CheckTypeHeader(const OMX_PTR type, OMX_U32 size) 2061{ 2062 OMX_U32 *nsize; 2063 OMX_VERSIONTYPE *nversion; 2064 2065 if (!type) 2066 return OMX_ErrorBadParameter; 2067 2068 nsize = (OMX_U32 *)type; 2069 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 2070 2071 if (*nsize != size) 2072 return OMX_ErrorBadParameter; 2073 2074 if (nversion->nVersion != OMX_SPEC_VERSION) 2075 return OMX_ErrorVersionMismatch; 2076 2077 return OMX_ErrorNone; 2078} 2079 2080/* 2081 * query_roles helper 2082 */ 2083OMX_ERRORTYPE ComponentBase::QueryRolesHelper( 2084 OMX_U32 nr_comp_roles, 2085 const OMX_U8 **comp_roles, 2086 OMX_U32 *nr_roles, OMX_U8 **roles) 2087{ 2088 OMX_U32 i; 2089 2090 if (!roles) { 2091 *nr_roles = nr_comp_roles; 2092 return OMX_ErrorNone; 2093 } 2094 2095 if (!nr_roles || (*nr_roles != nr_comp_roles) || !roles) 2096 return OMX_ErrorBadParameter; 2097 2098 for (i = 0; i < nr_comp_roles; i++) { 2099 if (!roles[i]) 2100 break; 2101 2102 strncpy((OMX_STRING)&roles[i][0], 2103 (const OMX_STRING)&comp_roles[i][0], OMX_MAX_STRINGNAME_SIZE); 2104 } 2105 2106 if (i != nr_comp_roles) 2107 return OMX_ErrorBadParameter; 2108 2109 *nr_roles = nr_comp_roles; 2110 return OMX_ErrorNone; 2111} 2112 2113/* end of ComponentBase */ 2114