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