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