componentbase.cpp revision 02c027ae33fc00f917c21c1dccf058a0b25e723c
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->GetPortDefinition(), 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->SetPortDefinition(p, false); 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 if (ret == OMX_ErrorNone) 674 ProcessorSetParameter(nIndex); 675 676 return ret; 677} 678 679OMX_ERRORTYPE ComponentBase::GetConfig( 680 OMX_IN OMX_HANDLETYPE hComponent, 681 OMX_IN OMX_INDEXTYPE nIndex, 682 OMX_INOUT OMX_PTR pComponentConfigStructure) 683{ 684 ComponentBase *cbase; 685 686 if (!hComponent) 687 return OMX_ErrorBadParameter; 688 689 cbase = static_cast<ComponentBase *> 690 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 691 if (!cbase) 692 return OMX_ErrorBadParameter; 693 694 return cbase->CBaseGetConfig(hComponent, nIndex, 695 pComponentConfigStructure); 696} 697 698OMX_ERRORTYPE ComponentBase::CBaseGetConfig( 699 OMX_IN OMX_HANDLETYPE hComponent, 700 OMX_IN OMX_INDEXTYPE nIndex, 701 OMX_INOUT OMX_PTR pComponentConfigStructure) 702{ 703 OMX_ERRORTYPE ret; 704 705 if (hComponent != handle) 706 return OMX_ErrorBadParameter; 707 708 switch (nIndex) { 709 default: 710 ret = ComponentGetConfig(nIndex, pComponentConfigStructure); 711 } 712 713 return ret; 714} 715 716OMX_ERRORTYPE ComponentBase::SetConfig( 717 OMX_IN OMX_HANDLETYPE hComponent, 718 OMX_IN OMX_INDEXTYPE nIndex, 719 OMX_IN OMX_PTR pComponentConfigStructure) 720{ 721 ComponentBase *cbase; 722 723 if (!hComponent) 724 return OMX_ErrorBadParameter; 725 726 cbase = static_cast<ComponentBase *> 727 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 728 if (!cbase) 729 return OMX_ErrorBadParameter; 730 731 return cbase->CBaseSetConfig(hComponent, nIndex, 732 pComponentConfigStructure); 733} 734 735OMX_ERRORTYPE ComponentBase::CBaseSetConfig( 736 OMX_IN OMX_HANDLETYPE hComponent, 737 OMX_IN OMX_INDEXTYPE nIndex, 738 OMX_IN OMX_PTR pComponentConfigStructure) 739{ 740 OMX_ERRORTYPE ret; 741 742 if (hComponent != handle) 743 return OMX_ErrorBadParameter; 744 745 switch (nIndex) { 746 default: 747 ret = ComponentSetConfig(nIndex, pComponentConfigStructure); 748 } 749 750 if (ret == OMX_ErrorNone) 751 ProcessorSetConfig(nIndex); 752 753 return ret; 754} 755 756OMX_ERRORTYPE ComponentBase::GetExtensionIndex( 757 OMX_IN OMX_HANDLETYPE hComponent, 758 OMX_IN OMX_STRING cParameterName, 759 OMX_OUT OMX_INDEXTYPE* pIndexType) 760{ 761 ComponentBase *cbase; 762 763 if (!hComponent) 764 return OMX_ErrorBadParameter; 765 766 cbase = static_cast<ComponentBase *> 767 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 768 if (!cbase) 769 return OMX_ErrorBadParameter; 770 771 return cbase->CBaseGetExtensionIndex(hComponent, cParameterName, 772 pIndexType); 773} 774 775OMX_ERRORTYPE ComponentBase::CBaseGetExtensionIndex( 776 OMX_IN OMX_HANDLETYPE hComponent, 777 OMX_IN OMX_STRING cParameterName, 778 OMX_OUT OMX_INDEXTYPE* pIndexType) 779{ 780 /* 781 * Todo 782 */ 783 784 return OMX_ErrorNotImplemented; 785} 786 787OMX_ERRORTYPE ComponentBase::GetState( 788 OMX_IN OMX_HANDLETYPE hComponent, 789 OMX_OUT OMX_STATETYPE* pState) 790{ 791 ComponentBase *cbase; 792 793 if (!hComponent) 794 return OMX_ErrorBadParameter; 795 796 cbase = static_cast<ComponentBase *> 797 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 798 if (!cbase) 799 return OMX_ErrorBadParameter; 800 801 return cbase->CBaseGetState(hComponent, pState); 802} 803 804OMX_ERRORTYPE ComponentBase::CBaseGetState( 805 OMX_IN OMX_HANDLETYPE hComponent, 806 OMX_OUT OMX_STATETYPE* pState) 807{ 808 if (hComponent != handle) 809 return OMX_ErrorBadParameter; 810 811 *pState = state; 812 return OMX_ErrorNone; 813} 814 815OMX_ERRORTYPE ComponentBase::ComponentTunnelRequest( 816 OMX_IN OMX_HANDLETYPE hComponent, 817 OMX_IN OMX_U32 nPort, 818 OMX_IN OMX_HANDLETYPE hTunneledComponent, 819 OMX_IN OMX_U32 nTunneledPort, 820 OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup) 821{ 822 ComponentBase *cbase; 823 824 if (!hComponent) 825 return OMX_ErrorBadParameter; 826 827 cbase = static_cast<ComponentBase *> 828 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 829 if (!cbase) 830 return OMX_ErrorBadParameter; 831 832 return cbase->CBaseComponentTunnelRequest(hComponent, nPort, 833 hTunneledComponent, 834 nTunneledPort, pTunnelSetup); 835} 836 837OMX_ERRORTYPE ComponentBase::CBaseComponentTunnelRequest( 838 OMX_IN OMX_HANDLETYPE hComp, 839 OMX_IN OMX_U32 nPort, 840 OMX_IN OMX_HANDLETYPE hTunneledComp, 841 OMX_IN OMX_U32 nTunneledPort, 842 OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup) 843{ 844 /* 845 * Todo 846 */ 847 848 return OMX_ErrorNotImplemented; 849} 850 851OMX_ERRORTYPE ComponentBase::UseBuffer( 852 OMX_IN OMX_HANDLETYPE hComponent, 853 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 854 OMX_IN OMX_U32 nPortIndex, 855 OMX_IN OMX_PTR pAppPrivate, 856 OMX_IN OMX_U32 nSizeBytes, 857 OMX_IN OMX_U8 *pBuffer) 858{ 859 ComponentBase *cbase; 860 861 if (!hComponent) 862 return OMX_ErrorBadParameter; 863 864 cbase = static_cast<ComponentBase *> 865 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 866 if (!cbase) 867 return OMX_ErrorBadParameter; 868 869 return cbase->CBaseUseBuffer(hComponent, ppBufferHdr, nPortIndex, 870 pAppPrivate, nSizeBytes, pBuffer); 871} 872 873OMX_ERRORTYPE ComponentBase::CBaseUseBuffer( 874 OMX_IN OMX_HANDLETYPE hComponent, 875 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 876 OMX_IN OMX_U32 nPortIndex, 877 OMX_IN OMX_PTR pAppPrivate, 878 OMX_IN OMX_U32 nSizeBytes, 879 OMX_IN OMX_U8 *pBuffer) 880{ 881 PortBase *port = NULL; 882 OMX_ERRORTYPE ret; 883 884 if (hComponent != handle) 885 return OMX_ErrorBadParameter; 886 887 if (!ppBufferHdr) 888 return OMX_ErrorBadParameter; 889 *ppBufferHdr = NULL; 890 891 if (!pBuffer) 892 return OMX_ErrorBadParameter; 893 894 if (ports) 895 if (nPortIndex < nr_ports) 896 port = ports[nPortIndex]; 897 898 if (!port) 899 return OMX_ErrorBadParameter; 900 901 if (port->IsEnabled()) { 902 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 903 return OMX_ErrorIncorrectStateOperation; 904 } 905 906 return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, 907 pBuffer); 908} 909 910OMX_ERRORTYPE ComponentBase::AllocateBuffer( 911 OMX_IN OMX_HANDLETYPE hComponent, 912 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 913 OMX_IN OMX_U32 nPortIndex, 914 OMX_IN OMX_PTR pAppPrivate, 915 OMX_IN OMX_U32 nSizeBytes) 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->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex, 928 pAppPrivate, nSizeBytes); 929} 930 931OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer( 932 OMX_IN OMX_HANDLETYPE hComponent, 933 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 934 OMX_IN OMX_U32 nPortIndex, 935 OMX_IN OMX_PTR pAppPrivate, 936 OMX_IN OMX_U32 nSizeBytes) 937{ 938 PortBase *port = NULL; 939 OMX_ERRORTYPE ret; 940 941 if (hComponent != handle) 942 return OMX_ErrorBadParameter; 943 944 if (!ppBuffer) 945 return OMX_ErrorBadParameter; 946 *ppBuffer = NULL; 947 948 if (ports) 949 if (nPortIndex < nr_ports) 950 port = ports[nPortIndex]; 951 952 if (!port) 953 return OMX_ErrorBadParameter; 954 955 if (port->IsEnabled()) { 956 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 957 return OMX_ErrorIncorrectStateOperation; 958 } 959 960 return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes); 961} 962 963OMX_ERRORTYPE ComponentBase::FreeBuffer( 964 OMX_IN OMX_HANDLETYPE hComponent, 965 OMX_IN OMX_U32 nPortIndex, 966 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 967{ 968 ComponentBase *cbase; 969 970 if (!hComponent) 971 return OMX_ErrorBadParameter; 972 973 cbase = static_cast<ComponentBase *> 974 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 975 if (!cbase) 976 return OMX_ErrorBadParameter; 977 978 return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer); 979} 980 981OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer( 982 OMX_IN OMX_HANDLETYPE hComponent, 983 OMX_IN OMX_U32 nPortIndex, 984 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 985{ 986 PortBase *port = NULL; 987 OMX_ERRORTYPE ret; 988 989 if (hComponent != handle) 990 return OMX_ErrorBadParameter; 991 992 if (!pBuffer) 993 return OMX_ErrorBadParameter; 994 995 if (ports) 996 if (nPortIndex < nr_ports) 997 port = ports[nPortIndex]; 998 999 if (!port) 1000 return OMX_ErrorBadParameter; 1001 1002 return port->FreeBuffer(nPortIndex, pBuffer); 1003} 1004 1005OMX_ERRORTYPE ComponentBase::EmptyThisBuffer( 1006 OMX_IN OMX_HANDLETYPE hComponent, 1007 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 1008{ 1009 ComponentBase *cbase; 1010 1011 if (!hComponent) 1012 return OMX_ErrorBadParameter; 1013 1014 cbase = static_cast<ComponentBase *> 1015 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1016 if (!cbase) 1017 return OMX_ErrorBadParameter; 1018 1019 return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer); 1020} 1021 1022OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer( 1023 OMX_IN OMX_HANDLETYPE hComponent, 1024 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 1025{ 1026 PortBase *port = NULL; 1027 OMX_U32 port_index; 1028 OMX_ERRORTYPE ret; 1029 1030 if ((hComponent != handle) || !pBuffer) 1031 return OMX_ErrorBadParameter; 1032 1033 ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); 1034 if (ret != OMX_ErrorNone) 1035 return ret; 1036 1037 port_index = pBuffer->nInputPortIndex; 1038 if (port_index == (OMX_U32)-1) 1039 return OMX_ErrorBadParameter; 1040 1041 if (ports) 1042 if (port_index < nr_ports) 1043 port = ports[port_index]; 1044 1045 if (!port) 1046 return OMX_ErrorBadParameter; 1047 1048 if (pBuffer->pInputPortPrivate != port) 1049 return OMX_ErrorBadParameter; 1050 1051 if (port->IsEnabled()) { 1052 if (state != OMX_StateIdle && state != OMX_StateExecuting && 1053 state != OMX_StatePause) 1054 return OMX_ErrorIncorrectStateOperation; 1055 } 1056 1057 if (!pBuffer->hMarkTargetComponent) { 1058 OMX_MARKTYPE *mark; 1059 1060 mark = port->PopMark(); 1061 if (mark) { 1062 pBuffer->hMarkTargetComponent = mark->hMarkTargetComponent; 1063 pBuffer->pMarkData = mark->pMarkData; 1064 free(mark); 1065 } 1066 } 1067 1068 ret = port->PushThisBuffer(pBuffer); 1069 if (ret == OMX_ErrorNone) 1070 bufferwork->ScheduleWork(this); 1071 1072 return ret; 1073} 1074 1075OMX_ERRORTYPE ComponentBase::FillThisBuffer( 1076 OMX_IN OMX_HANDLETYPE hComponent, 1077 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 1078{ 1079 ComponentBase *cbase; 1080 1081 if (!hComponent) 1082 return OMX_ErrorBadParameter; 1083 1084 cbase = static_cast<ComponentBase *> 1085 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1086 if (!cbase) 1087 return OMX_ErrorBadParameter; 1088 1089 return cbase->CBaseFillThisBuffer(hComponent, pBuffer); 1090} 1091 1092OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer( 1093 OMX_IN OMX_HANDLETYPE hComponent, 1094 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 1095{ 1096 PortBase *port = NULL; 1097 OMX_U32 port_index; 1098 OMX_ERRORTYPE ret; 1099 1100 if ((hComponent != handle) || !pBuffer) 1101 return OMX_ErrorBadParameter; 1102 1103 ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); 1104 if (ret != OMX_ErrorNone) 1105 return ret; 1106 1107 port_index = pBuffer->nOutputPortIndex; 1108 if (port_index == (OMX_U32)-1) 1109 return OMX_ErrorBadParameter; 1110 1111 if (ports) 1112 if (port_index < nr_ports) 1113 port = ports[port_index]; 1114 1115 if (!port) 1116 return OMX_ErrorBadParameter; 1117 1118 if (pBuffer->pOutputPortPrivate != port) 1119 return OMX_ErrorBadParameter; 1120 1121 if (port->IsEnabled()) { 1122 if (state != OMX_StateIdle && state != OMX_StateExecuting && 1123 state != OMX_StatePause) 1124 return OMX_ErrorIncorrectStateOperation; 1125 } 1126 1127 ret = port->PushThisBuffer(pBuffer); 1128 if (ret == OMX_ErrorNone) 1129 bufferwork->ScheduleWork(this); 1130 1131 return ret; 1132} 1133 1134OMX_ERRORTYPE ComponentBase::SetCallbacks( 1135 OMX_IN OMX_HANDLETYPE hComponent, 1136 OMX_IN OMX_CALLBACKTYPE* pCallbacks, 1137 OMX_IN OMX_PTR pAppData) 1138{ 1139 ComponentBase *cbase; 1140 1141 if (!hComponent) 1142 return OMX_ErrorBadParameter; 1143 1144 cbase = static_cast<ComponentBase *> 1145 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1146 if (!cbase) 1147 return OMX_ErrorBadParameter; 1148 1149 return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData); 1150} 1151 1152OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks( 1153 OMX_IN OMX_HANDLETYPE hComponent, 1154 OMX_IN OMX_CALLBACKTYPE *pCallbacks, 1155 OMX_IN OMX_PTR pAppData) 1156{ 1157 if (hComponent != handle) 1158 return OMX_ErrorBadParameter; 1159 1160 appdata = pAppData; 1161 callbacks = pCallbacks; 1162 1163 return OMX_ErrorNone; 1164} 1165 1166OMX_ERRORTYPE ComponentBase::ComponentDeInit( 1167 OMX_IN OMX_HANDLETYPE hComponent) 1168{ 1169 ComponentBase *cbase; 1170 1171 if (!hComponent) 1172 return OMX_ErrorBadParameter; 1173 1174 cbase = static_cast<ComponentBase *> 1175 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1176 if (!cbase) 1177 return OMX_ErrorBadParameter; 1178 1179 return cbase->CBaseComponentDeInit(hComponent); 1180} 1181 1182OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit( 1183 OMX_IN OMX_HANDLETYPE hComponent) 1184{ 1185 /* 1186 * Todo 1187 */ 1188 1189 return OMX_ErrorNotImplemented; 1190} 1191 1192OMX_ERRORTYPE ComponentBase::UseEGLImage( 1193 OMX_IN OMX_HANDLETYPE hComponent, 1194 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1195 OMX_IN OMX_U32 nPortIndex, 1196 OMX_IN OMX_PTR pAppPrivate, 1197 OMX_IN void* eglImage) 1198{ 1199 ComponentBase *cbase; 1200 1201 if (!hComponent) 1202 return OMX_ErrorBadParameter; 1203 1204 cbase = static_cast<ComponentBase *> 1205 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1206 if (!cbase) 1207 return OMX_ErrorBadParameter; 1208 1209 return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex, 1210 pAppPrivate, eglImage); 1211} 1212 1213OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage( 1214 OMX_IN OMX_HANDLETYPE hComponent, 1215 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1216 OMX_IN OMX_U32 nPortIndex, 1217 OMX_IN OMX_PTR pAppPrivate, 1218 OMX_IN void* eglImage) 1219{ 1220 /* 1221 * Todo 1222 */ 1223 1224 return OMX_ErrorNotImplemented; 1225} 1226 1227OMX_ERRORTYPE ComponentBase::ComponentRoleEnum( 1228 OMX_IN OMX_HANDLETYPE hComponent, 1229 OMX_OUT OMX_U8 *cRole, 1230 OMX_IN OMX_U32 nIndex) 1231{ 1232 ComponentBase *cbase; 1233 1234 if (!hComponent) 1235 return OMX_ErrorBadParameter; 1236 1237 cbase = static_cast<ComponentBase *> 1238 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1239 if (!cbase) 1240 return OMX_ErrorBadParameter; 1241 1242 return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex); 1243} 1244 1245OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum( 1246 OMX_IN OMX_HANDLETYPE hComponent, 1247 OMX_OUT OMX_U8 *cRole, 1248 OMX_IN OMX_U32 nIndex) 1249{ 1250 if (hComponent != (OMX_HANDLETYPE *)this->handle) 1251 return OMX_ErrorBadParameter; 1252 1253 if (nIndex > nr_roles) 1254 return OMX_ErrorBadParameter; 1255 1256 strncpy((char *)cRole, (const char *)roles[nIndex], 1257 OMX_MAX_STRINGNAME_SIZE); 1258 return OMX_ErrorNone; 1259} 1260 1261/* implement CmdHandlerInterface */ 1262void ComponentBase::CmdHandler(struct cmd_s *cmd) 1263{ 1264 switch (cmd->cmd) { 1265 case OMX_CommandStateSet: { 1266 OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1; 1267 1268 TransState(transition); 1269 break; 1270 } 1271 case OMX_CommandFlush: { 1272 OMX_U32 port_index = cmd->param1; 1273 1274 FlushPort(port_index, 1); 1275 break; 1276 } 1277 case OMX_CommandPortDisable: { 1278 OMX_U32 port_index = cmd->param1; 1279 1280 TransStatePort(port_index, PortBase::OMX_PortDisabled); 1281 break; 1282 } 1283 case OMX_CommandPortEnable: { 1284 OMX_U32 port_index = cmd->param1; 1285 1286 TransStatePort(port_index, PortBase::OMX_PortEnabled); 1287 break; 1288 } 1289 case OMX_CommandMarkBuffer: 1290 OMX_U32 port_index = (OMX_U32)cmd->param1; 1291 OMX_MARKTYPE *mark = (OMX_MARKTYPE *)cmd->cmddata; 1292 1293 PushThisMark(port_index, mark); 1294 break; 1295 } /* switch */ 1296} 1297 1298/* 1299 * SendCommand:OMX_CommandStateSet 1300 * called in CmdHandler or called in other parts of component for reporting 1301 * internal error (OMX_StateInvalid). 1302 */ 1303/* 1304 * Todo 1305 * Resource Management (OMX_StateWaitForResources) 1306 * for now, we never notify OMX_ErrorInsufficientResources, 1307 * so IL client doesn't try to set component' state OMX_StateWaitForResources 1308 */ 1309static const char *state_name[OMX_StateWaitForResources + 1] = { 1310 "OMX_StateInvalid", 1311 "OMX_StateLoaded", 1312 "OMX_StateIdle", 1313 "OMX_StateExecuting", 1314 "OMX_StatePause", 1315 "OMX_StateWaitForResources", 1316}; 1317 1318static inline const char *GetStateName(OMX_STATETYPE state) 1319{ 1320 if (state > OMX_StateWaitForResources) 1321 return "UnKnown"; 1322 1323 return state_name[state]; 1324} 1325 1326void ComponentBase::TransState(OMX_STATETYPE transition) 1327{ 1328 OMX_STATETYPE current = this->state; 1329 OMX_EVENTTYPE event; 1330 OMX_U32 data1, data2; 1331 OMX_ERRORTYPE ret; 1332 1333 LOGD("current state = %s, transition state = %s\n", 1334 GetStateName(current), GetStateName(transition)); 1335 1336 /* same state */ 1337 if (current == transition) { 1338 ret = OMX_ErrorSameState; 1339 goto notify_event; 1340 } 1341 1342 /* invalid state */ 1343 if (current == OMX_StateInvalid) { 1344 ret = OMX_ErrorInvalidState; 1345 goto notify_event; 1346 } 1347 1348 if (transition == OMX_StateLoaded) 1349 ret = TransStateToLoaded(current); 1350 else if (transition == OMX_StateIdle) 1351 ret = TransStateToIdle(current); 1352 else if (transition == OMX_StateExecuting) 1353 ret = TransStateToExecuting(current); 1354 else if (transition == OMX_StatePause) 1355 ret = TransStateToPause(current); 1356 else if (transition == OMX_StateInvalid) 1357 ret = TransStateToInvalid(current); 1358 else if (transition == OMX_StateWaitForResources) 1359 ret = TransStateToWaitForResources(current); 1360 else 1361 ret = OMX_ErrorIncorrectStateTransition; 1362 1363notify_event: 1364 if (ret == OMX_ErrorNone) { 1365 event = OMX_EventCmdComplete; 1366 data1 = OMX_CommandStateSet; 1367 data2 = transition; 1368 1369 state = transition; 1370 LOGD("transition from %s to %s completed\n", 1371 GetStateName(current), GetStateName(transition)); 1372 } 1373 else { 1374 event = OMX_EventError; 1375 data1 = ret; 1376 data2 = 0; 1377 1378 if (transition == OMX_StateInvalid || ret == OMX_ErrorInvalidState) { 1379 state = OMX_StateInvalid; 1380 LOGD("failed transition from %s to %s, current state is %s\n", 1381 GetStateName(current), GetStateName(transition), 1382 GetStateName(state)); 1383 } 1384 } 1385 1386 callbacks->EventHandler(handle, appdata, event, data1, data2, NULL); 1387 1388 /* WaitForResources workaround */ 1389 if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources) 1390 callbacks->EventHandler(handle, appdata, 1391 OMX_EventResourcesAcquired, 0, 0, NULL); 1392} 1393 1394inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current) 1395{ 1396 OMX_ERRORTYPE ret; 1397 1398 if (current == OMX_StateIdle) { 1399 OMX_U32 i; 1400 1401 for (i = 0; i < nr_ports; i++) 1402 ports[i]->WaitPortBufferCompletion(); 1403 1404 ret = ProcessorDeinit(); 1405 if (ret != OMX_ErrorNone) { 1406 LOGE("failed to ProcessorDeinit() (ret = 0x%08x)\n", ret); 1407 ret = OMX_ErrorInvalidState; 1408 goto out; 1409 } 1410 } 1411 else if (current == OMX_StateWaitForResources) { 1412 LOGE("state transition's requested from WaitForResources to " 1413 "Loaded\n"); 1414 1415 /* 1416 * from WaitForResources to Loaded considered from Loaded to Loaded. 1417 * do nothing 1418 */ 1419 1420 ret = OMX_ErrorNone; 1421 } 1422 else 1423 ret = OMX_ErrorIncorrectStateTransition; 1424 1425out: 1426 return ret; 1427} 1428 1429inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current) 1430{ 1431 OMX_ERRORTYPE ret; 1432 1433 if (current == OMX_StateLoaded) { 1434 OMX_U32 i; 1435 1436 ret = ProcessorInit(); 1437 if (ret != OMX_ErrorNone) { 1438 LOGE("failed to ProcessorInit() (ret = 0x%08x)\n", ret); 1439 ret = OMX_ErrorInvalidState; 1440 goto out; 1441 } 1442 1443 for (i = 0; i < nr_ports; i++) { 1444 if (ports[i]->IsEnabled()) 1445 ports[i]->WaitPortBufferCompletion(); 1446 } 1447 } 1448 else if (current == OMX_StateExecuting) { 1449 FlushPort(OMX_ALL, 0); 1450 1451 bufferwork->StopWork(); 1452 1453 ret = ProcessorStop(); 1454 if (ret != OMX_ErrorNone) { 1455 LOGE("failed to ProcessorStop() (ret = 0x%08x)\n", ret); 1456 ret = OMX_ErrorInvalidState; 1457 goto out; 1458 } 1459 } 1460 else if (current == OMX_StatePause) { 1461 FlushPort(OMX_ALL, 0); 1462 1463 bufferwork->CancelScheduledWork(this); 1464 bufferwork->StopWork(); 1465 1466 ret = ProcessorStop(); 1467 if (ret != OMX_ErrorNone) { 1468 LOGE("failed to ProcessorStop() (ret = 0x%08x)\n", ret); 1469 ret = OMX_ErrorInvalidState; 1470 goto out; 1471 } 1472 } 1473 else if (current == OMX_StateWaitForResources) { 1474 LOGE("state transition's requested from WaitForResources to Idle\n"); 1475 1476 /* same as Loaded to Idle BUT DO NOTHING for now */ 1477 1478 ret = OMX_ErrorNone; 1479 } 1480 else 1481 ret = OMX_ErrorIncorrectStateTransition; 1482 1483out: 1484 return ret; 1485} 1486 1487inline OMX_ERRORTYPE 1488ComponentBase::TransStateToExecuting(OMX_STATETYPE current) 1489{ 1490 OMX_ERRORTYPE ret; 1491 1492 if (current == OMX_StateIdle) { 1493 pthread_mutex_lock(&executing_lock); 1494 executing = true; 1495 pthread_mutex_unlock(&executing_lock); 1496 1497 bufferwork->StartWork(); 1498 1499 ret = ProcessorStart(); 1500 if (ret != OMX_ErrorNone) { 1501 LOGE("failed to ProcessorStart() (ret = 0x%08x)\n", ret); 1502 ret = OMX_ErrorInvalidState; 1503 goto out; 1504 } 1505 } 1506 else if (current == OMX_StatePause) { 1507 pthread_mutex_lock(&executing_lock); 1508 executing = true; 1509 pthread_cond_signal(&executing_wait); 1510 pthread_mutex_unlock(&executing_lock); 1511 1512 ret = ProcessorResume(); 1513 if (ret != OMX_ErrorNone) { 1514 LOGE("failed to ProcessorStart() (ret = 0x%08x)\n", ret); 1515 ret = OMX_ErrorInvalidState; 1516 goto out; 1517 } 1518 } 1519 else 1520 ret = OMX_ErrorIncorrectStateTransition; 1521 1522out: 1523 return ret; 1524} 1525 1526inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current) 1527{ 1528 OMX_ERRORTYPE ret; 1529 1530 if (current == OMX_StateIdle) { 1531 /* turn off executing flag */ 1532 pthread_mutex_lock(&executing_lock); 1533 executing = false; 1534 pthread_mutex_unlock(&executing_lock); 1535 1536 bufferwork->StartWork(); 1537 1538 ret = ProcessorStart(); 1539 if (ret != OMX_ErrorNone) { 1540 LOGE("failed to ProcessorPause() (ret = 0x%08x)\n", ret); 1541 ret = OMX_ErrorInvalidState; 1542 goto out; 1543 } 1544 } 1545 else if (current == OMX_StateExecuting) { 1546 pthread_mutex_lock(&executing_lock); 1547 executing = false; 1548 pthread_mutex_unlock(&executing_lock); 1549 1550 ret = ProcessorPause(); 1551 if (ret != OMX_ErrorNone) { 1552 LOGE("failed to ProcessorPause() (ret = 0x%08x)\n", ret); 1553 ret = OMX_ErrorInvalidState; 1554 goto out; 1555 } 1556 } 1557 else 1558 ret = OMX_ErrorIncorrectStateTransition; 1559 1560out: 1561 return ret; 1562} 1563 1564inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current) 1565{ 1566 OMX_ERRORTYPE ret = OMX_ErrorInvalidState; 1567 1568 /* 1569 * Todo 1570 * graceful escape 1571 */ 1572 1573 return ret; 1574} 1575 1576inline OMX_ERRORTYPE 1577ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current) 1578{ 1579 OMX_ERRORTYPE ret; 1580 1581 if (current == OMX_StateLoaded) { 1582 LOGE("state transition's requested from Loaded to WaitForResources\n"); 1583 ret = OMX_ErrorNone; 1584 } 1585 else 1586 ret = OMX_ErrorIncorrectStateTransition; 1587 1588 return ret; 1589} 1590 1591/* mark buffer */ 1592void ComponentBase::PushThisMark(OMX_U32 port_index, OMX_MARKTYPE *mark) 1593{ 1594 PortBase *port = NULL; 1595 OMX_EVENTTYPE event; 1596 OMX_U32 data1, data2; 1597 OMX_ERRORTYPE ret; 1598 1599 if (ports) 1600 if (port_index < nr_ports) 1601 port = ports[port_index]; 1602 1603 if (!port) { 1604 ret = OMX_ErrorBadPortIndex; 1605 goto notify_event; 1606 } 1607 1608 ret = port->PushMark(mark); 1609 if (ret != OMX_ErrorNone) { 1610 /* don't report OMX_ErrorInsufficientResources */ 1611 ret = OMX_ErrorUndefined; 1612 goto notify_event; 1613 } 1614 1615notify_event: 1616 if (ret == OMX_ErrorNone) { 1617 event = OMX_EventCmdComplete; 1618 data1 = OMX_CommandMarkBuffer; 1619 data2 = port_index; 1620 } 1621 else { 1622 event = OMX_EventError; 1623 data1 = ret; 1624 data2 = 0; 1625 } 1626 1627 callbacks->EventHandler(handle, appdata, event, data1, data2, NULL); 1628} 1629 1630void ComponentBase::FlushPort(OMX_U32 port_index, bool notify) 1631{ 1632 OMX_U32 i, from_index, to_index; 1633 1634 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 1635 return; 1636 1637 if (port_index == OMX_ALL) { 1638 from_index = 0; 1639 to_index = nr_ports - 1; 1640 } 1641 else { 1642 from_index = port_index; 1643 to_index = port_index; 1644 } 1645 1646 pthread_mutex_lock(&ports_block); 1647 for (i = from_index; i <= to_index; i++) { 1648 ports[i]->FlushPort(); 1649 if (notify) 1650 callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete, 1651 OMX_CommandFlush, i, NULL); 1652 } 1653 pthread_mutex_unlock(&ports_block); 1654} 1655 1656void ComponentBase::TransStatePort(OMX_U32 port_index, OMX_U8 state) 1657{ 1658 OMX_EVENTTYPE event; 1659 OMX_U32 data1, data2; 1660 OMX_U32 i, from_index, to_index; 1661 OMX_ERRORTYPE ret; 1662 1663 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 1664 return; 1665 1666 if (port_index == OMX_ALL) { 1667 from_index = 0; 1668 to_index = nr_ports - 1; 1669 } 1670 else { 1671 from_index = port_index; 1672 to_index = port_index; 1673 } 1674 1675 pthread_mutex_lock(&ports_block); 1676 for (i = from_index; i <= to_index; i++) { 1677 ret = ports[i]->TransState(state); 1678 if (ret == OMX_ErrorNone) { 1679 event = OMX_EventCmdComplete; 1680 if (state == PortBase::OMX_PortEnabled) 1681 data1 = OMX_CommandPortEnable; 1682 else 1683 data1 = OMX_CommandPortDisable; 1684 data2 = i; 1685 } 1686 else { 1687 event = OMX_EventError; 1688 data1 = ret; 1689 data2 = 0; 1690 } 1691 callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete, 1692 OMX_CommandPortDisable, data2, NULL); 1693 } 1694 pthread_mutex_unlock(&ports_block); 1695} 1696 1697/* set working role */ 1698OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role) 1699{ 1700 OMX_U32 i; 1701 1702 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1703 return OMX_ErrorIncorrectStateOperation; 1704 1705 if (!role) { 1706 working_role = NULL; 1707 return OMX_ErrorNone; 1708 } 1709 1710 for (i = 0; i < nr_roles; i++) { 1711 if (!strcmp((char *)&roles[i][0], role)) { 1712 working_role = (OMX_STRING)&roles[i][0]; 1713 return OMX_ErrorNone; 1714 } 1715 } 1716 1717 LOGE("cannot find %s role in %s\n", role, name); 1718 return OMX_ErrorBadParameter; 1719} 1720 1721/* apply a working role for a component having multiple roles */ 1722OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void) 1723{ 1724 OMX_U32 i; 1725 OMX_ERRORTYPE ret; 1726 1727 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1728 return OMX_ErrorIncorrectStateOperation; 1729 1730 if (!working_role) 1731 return OMX_ErrorBadParameter; 1732 1733 if (!callbacks || !appdata) 1734 return OMX_ErrorBadParameter; 1735 1736 ret = AllocatePorts(); 1737 if (ret != OMX_ErrorNone) { 1738 LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret); 1739 return ret; 1740 } 1741 1742 /* now we can access ports */ 1743 for (i = 0; i < nr_ports; i++) { 1744 ports[i]->SetOwner(handle); 1745 ports[i]->SetCallbacks(handle, callbacks, appdata); 1746 } 1747 1748 return OMX_ErrorNone; 1749} 1750 1751OMX_ERRORTYPE ComponentBase::AllocatePorts(void) 1752{ 1753 OMX_ERRORTYPE ret; 1754 1755 if (ports) 1756 return OMX_ErrorBadParameter; 1757 1758 ret = ComponentAllocatePorts(); 1759 if (ret != OMX_ErrorNone) { 1760 LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n", 1761 name, ret); 1762 return ret; 1763 } 1764 1765 return OMX_ErrorNone; 1766} 1767 1768/* called int FreeHandle() */ 1769OMX_ERRORTYPE ComponentBase::FreePorts(void) 1770{ 1771 if (ports) { 1772 OMX_U32 i, this_nr_ports = this->nr_ports; 1773 1774 for (i = 0; i < this_nr_ports; i++) { 1775 if (ports[i]) { 1776 OMX_MARKTYPE *mark; 1777 /* it should be empty before this */ 1778 while ((mark = ports[i]->PopMark())) 1779 free(mark); 1780 1781 delete ports[i]; 1782 ports[i] = NULL; 1783 } 1784 } 1785 delete []ports; 1786 ports = NULL; 1787 } 1788 1789 return OMX_ErrorNone; 1790} 1791 1792/* buffer processing */ 1793/* implement WorkableInterface */ 1794void ComponentBase::Work(void) 1795{ 1796 OMX_BUFFERHEADERTYPE *buffers[nr_ports]; 1797 bool retain[nr_ports]; 1798 OMX_U32 i; 1799 bool avail = false; 1800 1801 pthread_mutex_lock(&executing_lock); 1802 if (!executing) 1803 pthread_cond_wait(&executing_wait, &executing_lock); 1804 pthread_mutex_unlock(&executing_lock); 1805 1806 pthread_mutex_lock(&ports_block); 1807 1808 avail = IsAllBufferAvailable(); 1809 if (avail) { 1810 for (i = 0; i < nr_ports; i++) { 1811 buffers[i] = ports[i]->PopBuffer(); 1812 retain[i] = false; 1813 } 1814 1815 ProcessorProcess(buffers, &retain[0], nr_ports); 1816 PostProcessBuffer(buffers, &retain[0], nr_ports); 1817 1818 for (i = 0; i < nr_ports; i++) { 1819 if (retain[i]) 1820 ports[i]->RetainThisBuffer(buffers[i]); 1821 else 1822 ports[i]->ReturnThisBuffer(buffers[i]); 1823 } 1824 } 1825 ScheduleIfAllBufferAvailable(); 1826 1827 pthread_mutex_unlock(&ports_block); 1828} 1829 1830bool ComponentBase::IsAllBufferAvailable(void) 1831{ 1832 OMX_U32 i; 1833 OMX_U32 nr_avail = 0; 1834 1835 for (i = 0; i < nr_ports; i++) { 1836 OMX_U32 length = 0; 1837 1838 if (ports[i]->IsEnabled()) 1839 length = ports[i]->BufferQueueLength(); 1840 1841 if (length) 1842 nr_avail++; 1843 } 1844 1845 if (nr_avail == nr_ports) 1846 return true; 1847 else 1848 return false; 1849} 1850 1851void ComponentBase::ScheduleIfAllBufferAvailable(void) 1852{ 1853 bool avail; 1854 1855 avail = IsAllBufferAvailable(); 1856 if (avail) 1857 bufferwork->ScheduleWork(this); 1858} 1859 1860void ComponentBase::PostProcessBuffer(OMX_BUFFERHEADERTYPE **buffers, 1861 bool *retain, 1862 OMX_U32 nr_buffers) 1863{ 1864 OMX_U32 i; 1865 1866 for (i = 0; i < nr_ports; i++) { 1867 OMX_MARKTYPE *mark; 1868 1869 if (ports[i]->GetPortDirection() == OMX_DirInput) { 1870 bool is_sink_component = true; 1871 OMX_U32 j; 1872 1873 if (buffers[i]->hMarkTargetComponent) { 1874 if (buffers[i]->hMarkTargetComponent == handle) { 1875 callbacks->EventHandler(handle, appdata, OMX_EventMark, 1876 0, 0, buffers[i]->pMarkData); 1877 buffers[i]->hMarkTargetComponent = NULL; 1878 buffers[i]->pMarkData = NULL; 1879 } 1880 } 1881 1882 for (j = 0; j < nr_ports; j++) { 1883 if (j == i) 1884 continue; 1885 1886 if (ports[j]->GetPortDirection() == OMX_DirOutput) { 1887 if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS) { 1888 buffers[j]->nFlags |= OMX_BUFFERFLAG_EOS; 1889 buffers[i]->nFlags &= ~OMX_BUFFERFLAG_EOS; 1890 retain[i] = false; 1891 retain[j] = false; 1892 } 1893 1894 if (!buffers[j]->hMarkTargetComponent) { 1895 mark = ports[j]->PopMark(); 1896 if (mark) { 1897 buffers[j]->hMarkTargetComponent = 1898 mark->hMarkTargetComponent; 1899 buffers[j]->pMarkData = mark->pMarkData; 1900 free(mark); 1901 mark = NULL; 1902 } 1903 1904 if (buffers[i]->hMarkTargetComponent) { 1905 if (buffers[j]->hMarkTargetComponent) { 1906 mark = (OMX_MARKTYPE *) 1907 malloc(sizeof(*mark)); 1908 if (mark) { 1909 mark->hMarkTargetComponent = 1910 buffers[i]->hMarkTargetComponent; 1911 mark->pMarkData = buffers[i]->pMarkData; 1912 ports[j]->PushMark(mark); 1913 mark = NULL; 1914 buffers[i]->hMarkTargetComponent = NULL; 1915 buffers[i]->pMarkData = NULL; 1916 } 1917 } 1918 else { 1919 buffers[j]->hMarkTargetComponent = 1920 buffers[i]->hMarkTargetComponent; 1921 buffers[j]->pMarkData = buffers[i]->pMarkData; 1922 buffers[i]->hMarkTargetComponent = NULL; 1923 buffers[i]->pMarkData = NULL; 1924 } 1925 } 1926 } 1927 else { 1928 if (buffers[i]->hMarkTargetComponent) { 1929 mark = (OMX_MARKTYPE *)malloc(sizeof(*mark)); 1930 if (mark) { 1931 mark->hMarkTargetComponent = 1932 buffers[i]->hMarkTargetComponent; 1933 mark->pMarkData = buffers[i]->pMarkData; 1934 ports[j]->PushMark(mark); 1935 mark = NULL; 1936 buffers[i]->hMarkTargetComponent = NULL; 1937 buffers[i]->pMarkData = NULL; 1938 } 1939 } 1940 } 1941 is_sink_component = false; 1942 } 1943 } 1944 1945 if (is_sink_component) { 1946 if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS) { 1947 callbacks->EventHandler(handle, appdata, 1948 OMX_EventBufferFlag, 1949 i, buffers[i]->nFlags, NULL); 1950 retain[i] = false; 1951 } 1952 } 1953 } 1954 else if (ports[i]->GetPortDirection() == OMX_DirOutput) { 1955 bool is_source_component = true; 1956 OMX_U32 j; 1957 1958 if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS) { 1959 callbacks->EventHandler(handle, appdata, 1960 OMX_EventBufferFlag, 1961 i, buffers[i]->nFlags, NULL); 1962 retain[i] = false; 1963 } 1964 1965 for (j = 0; j < nr_ports; j++) { 1966 if (j == i) 1967 continue; 1968 1969 if (ports[j]->GetPortDirection() == OMX_DirInput) 1970 is_source_component = false; 1971 } 1972 1973 if (is_source_component) { 1974 if (!retain[i]) { 1975 mark = ports[i]->PopMark(); 1976 if (mark) { 1977 buffers[i]->hMarkTargetComponent = 1978 mark->hMarkTargetComponent; 1979 buffers[i]->pMarkData = mark->pMarkData; 1980 free(mark); 1981 mark = NULL; 1982 1983 if (buffers[i]->hMarkTargetComponent == handle) { 1984 callbacks->EventHandler(handle, appdata, 1985 OMX_EventMark, 0, 0, 1986 buffers[i]->pMarkData); 1987 buffers[i]->hMarkTargetComponent = NULL; 1988 buffers[i]->pMarkData = NULL; 1989 } 1990 } 1991 } 1992 } 1993 } 1994 else { 1995 LOGE("%s(): fatal error unknown port direction (0x%08x)\n", 1996 __func__, ports[i]->GetPortDirection()); 1997 } 1998 } 1999} 2000 2001/* processor default callbacks */ 2002OMX_ERRORTYPE ComponentBase::ProcessorInit(void) 2003{ 2004 return OMX_ErrorNone; 2005} 2006OMX_ERRORTYPE ComponentBase::ProcessorDeinit(void) 2007{ 2008 return OMX_ErrorNone; 2009} 2010 2011OMX_ERRORTYPE ComponentBase::ProcessorStart(void) 2012{ 2013 return OMX_ErrorNone; 2014} 2015 2016OMX_ERRORTYPE ComponentBase::ProcessorStop(void) 2017{ 2018 return OMX_ErrorNone; 2019} 2020 2021OMX_ERRORTYPE ComponentBase::ProcessorPause(void) 2022{ 2023 return OMX_ErrorNone; 2024} 2025 2026OMX_ERRORTYPE ComponentBase::ProcessorResume(void) 2027{ 2028 return OMX_ErrorNone; 2029} 2030 2031OMX_ERRORTYPE ComponentBase::ProcessorSetConfig(OMX_INDEXTYPE nParamIndex) 2032{ 2033 return OMX_ErrorNone; 2034} 2035 2036OMX_ERRORTYPE ComponentBase::ProcessorSetParameter(OMX_INDEXTYPE nParamIndex) 2037{ 2038 return OMX_ErrorNone; 2039} 2040 2041/* end of processor callbacks */ 2042 2043/* end of component methods & helpers */ 2044 2045/* 2046 * omx header manipuation 2047 */ 2048void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size) 2049{ 2050 OMX_U32 *nsize; 2051 OMX_VERSIONTYPE *nversion; 2052 2053 if (!type) 2054 return; 2055 2056 nsize = (OMX_U32 *)type; 2057 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 2058 2059 *nsize = size; 2060 nversion->nVersion = OMX_SPEC_VERSION; 2061} 2062 2063OMX_ERRORTYPE ComponentBase::CheckTypeHeader(const OMX_PTR type, OMX_U32 size) 2064{ 2065 OMX_U32 *nsize; 2066 OMX_VERSIONTYPE *nversion; 2067 2068 if (!type) 2069 return OMX_ErrorBadParameter; 2070 2071 nsize = (OMX_U32 *)type; 2072 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 2073 2074 if (*nsize != size) 2075 return OMX_ErrorBadParameter; 2076 2077 if (nversion->nVersion != OMX_SPEC_VERSION) 2078 return OMX_ErrorVersionMismatch; 2079 2080 return OMX_ErrorNone; 2081} 2082 2083/* 2084 * query_roles helper 2085 */ 2086OMX_ERRORTYPE ComponentBase::QueryRolesHelper( 2087 OMX_U32 nr_comp_roles, 2088 const OMX_U8 **comp_roles, 2089 OMX_U32 *nr_roles, OMX_U8 **roles) 2090{ 2091 OMX_U32 i; 2092 2093 if (!roles) { 2094 *nr_roles = nr_comp_roles; 2095 return OMX_ErrorNone; 2096 } 2097 2098 if (!nr_roles || (*nr_roles != nr_comp_roles) || !roles) 2099 return OMX_ErrorBadParameter; 2100 2101 for (i = 0; i < nr_comp_roles; i++) { 2102 if (!roles[i]) 2103 break; 2104 2105 strncpy((OMX_STRING)&roles[i][0], 2106 (const OMX_STRING)&comp_roles[i][0], OMX_MAX_STRINGNAME_SIZE); 2107 } 2108 2109 if (i != nr_comp_roles) 2110 return OMX_ErrorBadParameter; 2111 2112 *nr_roles = nr_comp_roles; 2113 return OMX_ErrorNone; 2114} 2115 2116/* end of ComponentBase */ 2117