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