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