componentbase.cpp revision d63975db3595680a0c681285b9e49b52fdacdbca
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 roles[i+1] = 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 if (nr_roles == 1) 250 SetWorkingRole((OMX_STRING)&roles[0]); 251 252 handle = (OMX_COMPONENTTYPE *)calloc(1, sizeof(*handle)); 253 if (!handle) { 254 SetWorkingRole(NULL); 255 return OMX_ErrorInsufficientResources; 256 } 257 258 /* handle initialization */ 259 SetTypeHeader(handle, sizeof(*handle)); 260 handle->pComponentPrivate = static_cast<OMX_PTR>(this); 261 handle->pApplicationPrivate = pAppData; 262 263 /* connect handle's functions */ 264 handle->GetComponentVersion = GetComponentVersion; 265 handle->SendCommand = SendCommand; 266 handle->GetParameter = GetParameter; 267 handle->SetParameter = SetParameter; 268 handle->GetConfig = GetConfig; 269 handle->SetConfig = SetConfig; 270 handle->GetExtensionIndex = GetExtensionIndex; 271 handle->GetState = GetState; 272 handle->ComponentTunnelRequest = ComponentTunnelRequest; 273 handle->UseBuffer = UseBuffer; 274 handle->AllocateBuffer = AllocateBuffer; 275 handle->FreeBuffer = FreeBuffer; 276 handle->EmptyThisBuffer = EmptyThisBuffer; 277 handle->FillThisBuffer = FillThisBuffer; 278 handle->SetCallbacks = SetCallbacks; 279 handle->ComponentDeInit = ComponentDeInit; 280 handle->UseEGLImage = UseEGLImage; 281 handle->ComponentRoleEnum = ComponentRoleEnum; 282 283 appdata = pAppData; 284 callbacks = pCallBacks; 285 *pHandle = (OMX_HANDLETYPE *)handle; 286 287 state = OMX_StateLoaded; 288 return OMX_ErrorNone; 289} 290 291OMX_ERRORTYPE ComponentBase::FreeHandle(OMX_HANDLETYPE hComponent) 292{ 293 OMX_ERRORTYPE ret; 294 295 if (hComponent != handle) 296 return OMX_ErrorBadParameter; 297 298 FreePorts(); 299 300 free(handle); 301 302 appdata = NULL; 303 callbacks = NULL; 304 305 state = OMX_StateUnloaded; 306 return OMX_ErrorNone; 307} 308 309/* end of core methods & helpers */ 310 311/* 312 * component methods & helpers 313 */ 314OMX_ERRORTYPE ComponentBase::GetComponentVersion( 315 OMX_IN OMX_HANDLETYPE hComponent, 316 OMX_OUT OMX_STRING pComponentName, 317 OMX_OUT OMX_VERSIONTYPE* pComponentVersion, 318 OMX_OUT OMX_VERSIONTYPE* pSpecVersion, 319 OMX_OUT OMX_UUIDTYPE* pComponentUUID) 320{ 321 ComponentBase *cbase; 322 323 if (!hComponent) 324 return OMX_ErrorBadParameter; 325 326 cbase = static_cast<ComponentBase *> 327 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 328 if (!cbase) 329 return OMX_ErrorBadParameter; 330 331 return cbase->CBaseGetComponentVersion(hComponent, 332 pComponentName, 333 pComponentVersion, 334 pSpecVersion, 335 pComponentUUID); 336} 337 338OMX_ERRORTYPE ComponentBase::CBaseGetComponentVersion( 339 OMX_IN OMX_HANDLETYPE hComponent, 340 OMX_OUT OMX_STRING pComponentName, 341 OMX_OUT OMX_VERSIONTYPE* pComponentVersion, 342 OMX_OUT OMX_VERSIONTYPE* pSpecVersion, 343 OMX_OUT OMX_UUIDTYPE* pComponentUUID) 344{ 345 /* 346 * Todo 347 */ 348 349 return OMX_ErrorNotImplemented; 350} 351 352OMX_ERRORTYPE ComponentBase::SendCommand( 353 OMX_IN OMX_HANDLETYPE hComponent, 354 OMX_IN OMX_COMMANDTYPE Cmd, 355 OMX_IN OMX_U32 nParam1, 356 OMX_IN OMX_PTR pCmdData) 357{ 358 ComponentBase *cbase; 359 360 if (!hComponent) 361 return OMX_ErrorBadParameter; 362 363 cbase = static_cast<ComponentBase *> 364 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 365 if (!cbase) 366 return OMX_ErrorBadParameter; 367 368 return cbase->CBaseSendCommand(hComponent, Cmd, nParam1, pCmdData); 369} 370 371OMX_ERRORTYPE ComponentBase::CBaseSendCommand( 372 OMX_IN OMX_HANDLETYPE hComponent, 373 OMX_IN OMX_COMMANDTYPE Cmd, 374 OMX_IN OMX_U32 nParam1, 375 OMX_IN OMX_PTR pCmdData) 376{ 377 struct cmd_s *cmd; 378 379 if (hComponent != handle) 380 return OMX_ErrorInvalidComponent; 381 382 /* basic error check */ 383 switch (Cmd) { 384 case OMX_CommandStateSet: 385 /* 386 * Todo 387 */ 388 break; 389 case OMX_CommandFlush: 390 /* 391 * Todo 392 */ 393 //break; 394 case OMX_CommandPortDisable: 395 /* 396 * Todo 397 */ 398 //break; 399 case OMX_CommandPortEnable: 400 /* 401 * Todo 402 */ 403 //break; 404 case OMX_CommandMarkBuffer: 405 /* 406 * Todo 407 */ 408 //break; 409 default: 410 LOGE("command %d not supported\n", Cmd); 411 return OMX_ErrorUnsupportedIndex; 412 } 413 414 cmd = (struct cmd_s *)malloc(sizeof(*cmd)); 415 if (!cmd) 416 return OMX_ErrorInsufficientResources; 417 418 cmd->cmd = Cmd; 419 cmd->param1 = nParam1; 420 cmd->cmddata = pCmdData; 421 422 return cmdwork->PushCmdQueue(cmd); 423} 424 425OMX_ERRORTYPE ComponentBase::GetParameter( 426 OMX_IN OMX_HANDLETYPE hComponent, 427 OMX_IN OMX_INDEXTYPE nParamIndex, 428 OMX_INOUT OMX_PTR pComponentParameterStructure) 429{ 430 ComponentBase *cbase; 431 432 if (!hComponent) 433 return OMX_ErrorBadParameter; 434 435 cbase = static_cast<ComponentBase *> 436 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 437 if (!cbase) 438 return OMX_ErrorBadParameter; 439 440 return cbase->CBaseGetParameter(hComponent, nParamIndex, 441 pComponentParameterStructure); 442} 443 444OMX_ERRORTYPE ComponentBase::CBaseGetParameter( 445 OMX_IN OMX_HANDLETYPE hComponent, 446 OMX_IN OMX_INDEXTYPE nParamIndex, 447 OMX_INOUT OMX_PTR pComponentParameterStructure) 448{ 449 OMX_ERRORTYPE ret = OMX_ErrorNone; 450 451 if (hComponent != handle) 452 return OMX_ErrorBadParameter; 453 454 switch (nParamIndex) { 455 case OMX_IndexParamAudioInit: 456 case OMX_IndexParamVideoInit: 457 case OMX_IndexParamImageInit: 458 case OMX_IndexParamOtherInit: { 459 OMX_PORT_PARAM_TYPE *p = 460 (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure; 461 462 memcpy(p, &portparam, sizeof(*p)); 463 break; 464 } 465 case OMX_IndexParamPortDefinition: { 466 OMX_PARAM_PORTDEFINITIONTYPE *p = 467 (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; 468 OMX_U32 index = p->nPortIndex; 469 PortBase *port = ports[index]; 470 471 memcpy(p, port->GetPortParam(), sizeof(*p)); 472 break; 473 } 474 case OMX_IndexParamAudioPortFormat: { 475 OMX_AUDIO_PARAM_PORTFORMATTYPE *p = 476 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure; 477 OMX_U32 index = p->nPortIndex; 478 PortBase *port = ports[index]; 479 480 memcpy(p, port->GetAudioPortParam(), sizeof(*p)); 481 break; 482 } 483 case OMX_IndexParamCompBufferSupplier: 484 /* 485 * Todo 486 */ 487 488 ret = OMX_ErrorUnsupportedIndex; 489 break; 490 default: 491 ret = ComponentGetParameter(nParamIndex, pComponentParameterStructure); 492 } /* switch */ 493 494 return ret; 495} 496 497OMX_ERRORTYPE ComponentBase::SetParameter( 498 OMX_IN OMX_HANDLETYPE hComponent, 499 OMX_IN OMX_INDEXTYPE nIndex, 500 OMX_IN OMX_PTR pComponentParameterStructure) 501{ 502 ComponentBase *cbase; 503 504 if (!hComponent) 505 return OMX_ErrorBadParameter; 506 507 cbase = static_cast<ComponentBase *> 508 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 509 if (!cbase) 510 return OMX_ErrorBadParameter; 511 512 return cbase->CBaseSetParameter(hComponent, nIndex, 513 pComponentParameterStructure); 514} 515 516OMX_ERRORTYPE ComponentBase::CBaseSetParameter( 517 OMX_IN OMX_HANDLETYPE hComponent, 518 OMX_IN OMX_INDEXTYPE nIndex, 519 OMX_IN OMX_PTR pComponentParameterStructure) 520{ 521 OMX_ERRORTYPE ret = OMX_ErrorNone; 522 523 if (hComponent != handle) 524 return OMX_ErrorBadParameter; 525 526 switch (nIndex) { 527 case OMX_IndexParamAudioInit: 528 case OMX_IndexParamVideoInit: 529 case OMX_IndexParamImageInit: 530 case OMX_IndexParamOtherInit: { 531 OMX_PORT_PARAM_TYPE *p = (OMX_PORT_PARAM_TYPE *) 532 pComponentParameterStructure; 533 534 memcpy(&portparam, p, sizeof(*p)); 535 break; 536 } 537 case OMX_IndexParamPortDefinition: { 538 OMX_PARAM_PORTDEFINITIONTYPE *p = 539 (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; 540 OMX_U32 index = p->nPortIndex; 541 PortBase *port = ports[index]; 542 543 port->SetPortParam(p); 544 break; 545 } 546 case OMX_IndexParamAudioPortFormat: { 547 OMX_AUDIO_PARAM_PORTFORMATTYPE *p = 548 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure; 549 OMX_U32 index = p->nPortIndex; 550 PortBase *port = ports[index]; 551 552 port->SetAudioPortParam(p); 553 break; 554 } 555 case OMX_IndexParamCompBufferSupplier: 556 /* 557 * Todo 558 */ 559 560 ret = OMX_ErrorUnsupportedIndex; 561 break; 562 case OMX_IndexParamStandardComponentRole: { 563 OMX_PARAM_COMPONENTROLETYPE *p = 564 (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; 565 566 ret = SetWorkingRole((OMX_STRING)p->cRole); 567 if (ret != OMX_ErrorNone) 568 return ret; 569 break; 570 } 571 default: 572 ret = ComponentSetParameter(nIndex, pComponentParameterStructure); 573 } /* switch */ 574 575 return ret; 576} 577 578OMX_ERRORTYPE ComponentBase::GetConfig( 579 OMX_IN OMX_HANDLETYPE hComponent, 580 OMX_IN OMX_INDEXTYPE nIndex, 581 OMX_INOUT OMX_PTR pComponentConfigStructure) 582{ 583 ComponentBase *cbase; 584 585 if (!hComponent) 586 return OMX_ErrorBadParameter; 587 588 cbase = static_cast<ComponentBase *> 589 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 590 if (!cbase) 591 return OMX_ErrorBadParameter; 592 593 return cbase->CBaseGetConfig(hComponent, nIndex, 594 pComponentConfigStructure); 595} 596 597OMX_ERRORTYPE ComponentBase::CBaseGetConfig( 598 OMX_IN OMX_HANDLETYPE hComponent, 599 OMX_IN OMX_INDEXTYPE nIndex, 600 OMX_INOUT OMX_PTR pComponentConfigStructure) 601{ 602 OMX_ERRORTYPE ret; 603 604 if (hComponent != handle) 605 return OMX_ErrorBadParameter; 606 607 switch (nIndex) { 608 default: 609 ret = ComponentGetConfig(nIndex, pComponentConfigStructure); 610 } 611 612 return ret; 613} 614 615OMX_ERRORTYPE ComponentBase::SetConfig( 616 OMX_IN OMX_HANDLETYPE hComponent, 617 OMX_IN OMX_INDEXTYPE nIndex, 618 OMX_IN OMX_PTR pComponentConfigStructure) 619{ 620 ComponentBase *cbase; 621 622 if (!hComponent) 623 return OMX_ErrorBadParameter; 624 625 cbase = static_cast<ComponentBase *> 626 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 627 if (!cbase) 628 return OMX_ErrorBadParameter; 629 630 return cbase->CBaseSetConfig(hComponent, nIndex, 631 pComponentConfigStructure); 632} 633 634OMX_ERRORTYPE ComponentBase::CBaseSetConfig( 635 OMX_IN OMX_HANDLETYPE hComponent, 636 OMX_IN OMX_INDEXTYPE nIndex, 637 OMX_IN OMX_PTR pComponentConfigStructure) 638{ 639 OMX_ERRORTYPE ret; 640 641 if (hComponent != handle) 642 return OMX_ErrorBadParameter; 643 644 switch (nIndex) { 645 default: 646 ret = ComponentSetConfig(nIndex, pComponentConfigStructure); 647 } 648 649 return ret; 650} 651 652OMX_ERRORTYPE ComponentBase::GetExtensionIndex( 653 OMX_IN OMX_HANDLETYPE hComponent, 654 OMX_IN OMX_STRING cParameterName, 655 OMX_OUT OMX_INDEXTYPE* pIndexType) 656{ 657 ComponentBase *cbase; 658 659 if (!hComponent) 660 return OMX_ErrorBadParameter; 661 662 cbase = static_cast<ComponentBase *> 663 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 664 if (!cbase) 665 return OMX_ErrorBadParameter; 666 667 return cbase->CBaseGetExtensionIndex(hComponent, cParameterName, 668 pIndexType); 669} 670 671OMX_ERRORTYPE ComponentBase::CBaseGetExtensionIndex( 672 OMX_IN OMX_HANDLETYPE hComponent, 673 OMX_IN OMX_STRING cParameterName, 674 OMX_OUT OMX_INDEXTYPE* pIndexType) 675{ 676 /* 677 * Todo 678 */ 679 680 return OMX_ErrorNotImplemented; 681} 682 683OMX_ERRORTYPE ComponentBase::GetState( 684 OMX_IN OMX_HANDLETYPE hComponent, 685 OMX_OUT OMX_STATETYPE* pState) 686{ 687 ComponentBase *cbase; 688 689 if (!hComponent) 690 return OMX_ErrorBadParameter; 691 692 cbase = static_cast<ComponentBase *> 693 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 694 if (!cbase) 695 return OMX_ErrorBadParameter; 696 697 return cbase->CBaseGetState(hComponent, pState); 698} 699 700OMX_ERRORTYPE ComponentBase::CBaseGetState( 701 OMX_IN OMX_HANDLETYPE hComponent, 702 OMX_OUT OMX_STATETYPE* pState) 703{ 704 if (hComponent != handle) 705 return OMX_ErrorBadParameter; 706 707 *pState = state; 708 return OMX_ErrorNone; 709} 710 711OMX_ERRORTYPE ComponentBase::ComponentTunnelRequest( 712 OMX_IN OMX_HANDLETYPE hComponent, 713 OMX_IN OMX_U32 nPort, 714 OMX_IN OMX_HANDLETYPE hTunneledComponent, 715 OMX_IN OMX_U32 nTunneledPort, 716 OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup) 717{ 718 ComponentBase *cbase; 719 720 if (!hComponent) 721 return OMX_ErrorBadParameter; 722 723 cbase = static_cast<ComponentBase *> 724 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 725 if (!cbase) 726 return OMX_ErrorBadParameter; 727 728 return cbase->CBaseComponentTunnelRequest(hComponent, nPort, 729 hTunneledComponent, 730 nTunneledPort, pTunnelSetup); 731} 732 733OMX_ERRORTYPE ComponentBase::CBaseComponentTunnelRequest( 734 OMX_IN OMX_HANDLETYPE hComp, 735 OMX_IN OMX_U32 nPort, 736 OMX_IN OMX_HANDLETYPE hTunneledComp, 737 OMX_IN OMX_U32 nTunneledPort, 738 OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup) 739{ 740 /* 741 * Todo 742 */ 743 744 return OMX_ErrorNotImplemented; 745} 746 747OMX_ERRORTYPE ComponentBase::UseBuffer( 748 OMX_IN OMX_HANDLETYPE hComponent, 749 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 750 OMX_IN OMX_U32 nPortIndex, 751 OMX_IN OMX_PTR pAppPrivate, 752 OMX_IN OMX_U32 nSizeBytes, 753 OMX_IN OMX_U8 *pBuffer) 754{ 755 ComponentBase *cbase; 756 757 if (!hComponent) 758 return OMX_ErrorBadParameter; 759 760 cbase = static_cast<ComponentBase *> 761 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 762 if (!cbase) 763 return OMX_ErrorBadParameter; 764 765 return cbase->CBaseUseBuffer(hComponent, ppBufferHdr, nPortIndex, 766 pAppPrivate, nSizeBytes, pBuffer); 767} 768 769OMX_ERRORTYPE ComponentBase::CBaseUseBuffer( 770 OMX_IN OMX_HANDLETYPE hComponent, 771 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 772 OMX_IN OMX_U32 nPortIndex, 773 OMX_IN OMX_PTR pAppPrivate, 774 OMX_IN OMX_U32 nSizeBytes, 775 OMX_IN OMX_U8 *pBuffer) 776{ 777 PortBase *port = NULL; 778 OMX_ERRORTYPE ret; 779 780 if (hComponent != handle) 781 return OMX_ErrorBadParameter; 782 783 if (ports) 784 if (nPortIndex < nr_ports) 785 port = ports[nPortIndex]; 786 787 if (!port) 788 return OMX_ErrorBadParameter; 789 790 return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, 791 pBuffer); 792} 793 794OMX_ERRORTYPE ComponentBase::AllocateBuffer( 795 OMX_IN OMX_HANDLETYPE hComponent, 796 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 797 OMX_IN OMX_U32 nPortIndex, 798 OMX_IN OMX_PTR pAppPrivate, 799 OMX_IN OMX_U32 nSizeBytes) 800{ 801 ComponentBase *cbase; 802 803 if (!hComponent) 804 return OMX_ErrorBadParameter; 805 806 cbase = static_cast<ComponentBase *> 807 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 808 if (!cbase) 809 return OMX_ErrorBadParameter; 810 811 return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex, 812 pAppPrivate, nSizeBytes); 813} 814 815OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer( 816 OMX_IN OMX_HANDLETYPE hComponent, 817 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 818 OMX_IN OMX_U32 nPortIndex, 819 OMX_IN OMX_PTR pAppPrivate, 820 OMX_IN OMX_U32 nSizeBytes) 821{ 822 PortBase *port = NULL; 823 OMX_ERRORTYPE ret; 824 825 if (hComponent != handle) 826 return OMX_ErrorBadParameter; 827 828 if (ports) 829 if (nPortIndex < nr_ports) 830 port = ports[nPortIndex]; 831 832 if (!port) 833 return OMX_ErrorBadParameter; 834 835 return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes); 836} 837 838OMX_ERRORTYPE ComponentBase::FreeBuffer( 839 OMX_IN OMX_HANDLETYPE hComponent, 840 OMX_IN OMX_U32 nPortIndex, 841 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 842{ 843 ComponentBase *cbase; 844 845 if (!hComponent) 846 return OMX_ErrorBadParameter; 847 848 cbase = static_cast<ComponentBase *> 849 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 850 if (!cbase) 851 return OMX_ErrorBadParameter; 852 853 return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer); 854} 855 856OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer( 857 OMX_IN OMX_HANDLETYPE hComponent, 858 OMX_IN OMX_U32 nPortIndex, 859 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 860{ 861 PortBase *port = NULL; 862 OMX_ERRORTYPE ret; 863 864 if (hComponent != handle) 865 return OMX_ErrorBadParameter; 866 867 if (ports) 868 if (nPortIndex < nr_ports) 869 port = ports[nPortIndex]; 870 871 if (!port) 872 return OMX_ErrorBadParameter; 873 874 return port->FreeBuffer(nPortIndex, pBuffer); 875} 876 877OMX_ERRORTYPE ComponentBase::EmptyThisBuffer( 878 OMX_IN OMX_HANDLETYPE hComponent, 879 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 880{ 881 ComponentBase *cbase; 882 883 if (!hComponent) 884 return OMX_ErrorBadParameter; 885 886 cbase = static_cast<ComponentBase *> 887 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 888 if (!cbase) 889 return OMX_ErrorBadParameter; 890 891 return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer); 892} 893 894OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer( 895 OMX_IN OMX_HANDLETYPE hComponent, 896 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 897{ 898 PortBase *port = NULL; 899 OMX_U32 port_index; 900 OMX_ERRORTYPE ret; 901 902 if ((hComponent != handle) || !pBuffer) 903 return OMX_ErrorBadParameter; 904 905 port_index = pBuffer->nInputPortIndex; 906 if (port_index == (OMX_U32)-1) 907 return OMX_ErrorBadParameter; 908 909 if (ports) 910 if (port_index < nr_ports) 911 port = ports[port_index]; 912 913 if (!port) 914 return OMX_ErrorBadParameter; 915 916 ret = port->PushThisBuffer(pBuffer); 917 if (ret == OMX_ErrorNone) 918 bufferwork->ScheduleWork(this); 919 920 return ret; 921} 922 923OMX_ERRORTYPE ComponentBase::FillThisBuffer( 924 OMX_IN OMX_HANDLETYPE hComponent, 925 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 926{ 927 ComponentBase *cbase; 928 929 if (!hComponent) 930 return OMX_ErrorBadParameter; 931 932 cbase = static_cast<ComponentBase *> 933 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 934 if (!cbase) 935 return OMX_ErrorBadParameter; 936 937 return cbase->CBaseFillThisBuffer(hComponent, pBuffer); 938} 939 940OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer( 941 OMX_IN OMX_HANDLETYPE hComponent, 942 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 943{ 944 PortBase *port = NULL; 945 OMX_U32 port_index; 946 OMX_ERRORTYPE ret; 947 948 if ((hComponent != handle) || !pBuffer) 949 return OMX_ErrorBadParameter; 950 951 port_index = pBuffer->nOutputPortIndex; 952 if (port_index == (OMX_U32)-1) 953 return OMX_ErrorBadParameter; 954 955 if (ports) 956 if (port_index < nr_ports) 957 port = ports[port_index]; 958 959 if (!port) 960 return OMX_ErrorBadParameter; 961 962 ret = port->PushThisBuffer(pBuffer); 963 if (ret == OMX_ErrorNone) 964 bufferwork->ScheduleWork(this); 965 966 return ret; 967} 968 969OMX_ERRORTYPE ComponentBase::SetCallbacks( 970 OMX_IN OMX_HANDLETYPE hComponent, 971 OMX_IN OMX_CALLBACKTYPE* pCallbacks, 972 OMX_IN OMX_PTR pAppData) 973{ 974 ComponentBase *cbase; 975 976 if (!hComponent) 977 return OMX_ErrorBadParameter; 978 979 cbase = static_cast<ComponentBase *> 980 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 981 if (!cbase) 982 return OMX_ErrorBadParameter; 983 984 return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData); 985} 986 987OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks( 988 OMX_IN OMX_HANDLETYPE hComponent, 989 OMX_IN OMX_CALLBACKTYPE *pCallbacks, 990 OMX_IN OMX_PTR pAppData) 991{ 992 if (hComponent != handle) 993 return OMX_ErrorBadParameter; 994 995 appdata = pAppData; 996 callbacks = pCallbacks; 997 998 return OMX_ErrorNone; 999} 1000 1001OMX_ERRORTYPE ComponentBase::ComponentDeInit( 1002 OMX_IN OMX_HANDLETYPE hComponent) 1003{ 1004 ComponentBase *cbase; 1005 1006 if (!hComponent) 1007 return OMX_ErrorBadParameter; 1008 1009 cbase = static_cast<ComponentBase *> 1010 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1011 if (!cbase) 1012 return OMX_ErrorBadParameter; 1013 1014 return cbase->CBaseComponentDeInit(hComponent); 1015} 1016 1017OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit( 1018 OMX_IN OMX_HANDLETYPE hComponent) 1019{ 1020 /* 1021 * Todo 1022 */ 1023 1024 return OMX_ErrorNotImplemented; 1025} 1026 1027OMX_ERRORTYPE ComponentBase::UseEGLImage( 1028 OMX_IN OMX_HANDLETYPE hComponent, 1029 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1030 OMX_IN OMX_U32 nPortIndex, 1031 OMX_IN OMX_PTR pAppPrivate, 1032 OMX_IN void* eglImage) 1033{ 1034 ComponentBase *cbase; 1035 1036 if (!hComponent) 1037 return OMX_ErrorBadParameter; 1038 1039 cbase = static_cast<ComponentBase *> 1040 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1041 if (!cbase) 1042 return OMX_ErrorBadParameter; 1043 1044 return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex, 1045 pAppPrivate, eglImage); 1046} 1047 1048OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage( 1049 OMX_IN OMX_HANDLETYPE hComponent, 1050 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1051 OMX_IN OMX_U32 nPortIndex, 1052 OMX_IN OMX_PTR pAppPrivate, 1053 OMX_IN void* eglImage) 1054{ 1055 /* 1056 * Todo 1057 */ 1058 1059 return OMX_ErrorNotImplemented; 1060} 1061 1062OMX_ERRORTYPE ComponentBase::ComponentRoleEnum( 1063 OMX_IN OMX_HANDLETYPE hComponent, 1064 OMX_OUT OMX_U8 *cRole, 1065 OMX_IN OMX_U32 nIndex) 1066{ 1067 ComponentBase *cbase; 1068 1069 if (!hComponent) 1070 return OMX_ErrorBadParameter; 1071 1072 cbase = static_cast<ComponentBase *> 1073 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1074 if (!cbase) 1075 return OMX_ErrorBadParameter; 1076 1077 return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex); 1078} 1079 1080OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum( 1081 OMX_IN OMX_HANDLETYPE hComponent, 1082 OMX_OUT OMX_U8 *cRole, 1083 OMX_IN OMX_U32 nIndex) 1084{ 1085 if (hComponent != (OMX_HANDLETYPE *)this->handle) 1086 return OMX_ErrorBadParameter; 1087 1088 if (nIndex > nr_roles) 1089 return OMX_ErrorBadParameter; 1090 1091 strncpy((char *)cRole, (const char *)roles[nIndex], 1092 OMX_MAX_STRINGNAME_SIZE); 1093 return OMX_ErrorNone; 1094} 1095 1096/* implement CmdHandlerInterface */ 1097void ComponentBase::CmdHandler(struct cmd_s *cmd) 1098{ 1099 switch (cmd->cmd) { 1100 case OMX_CommandStateSet: { 1101 OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1; 1102 1103 TransState(transition); 1104 break; 1105 } 1106 case OMX_CommandFlush: 1107 /* 1108 * Todo 1109 */ 1110 break; 1111 case OMX_CommandPortDisable: 1112 /* 1113 * Todo 1114 */ 1115 break; 1116 case OMX_CommandPortEnable: 1117 /* 1118 * Todo 1119 */ 1120 break; 1121 case OMX_CommandMarkBuffer: 1122 /* 1123 * Todo 1124 */ 1125 break; 1126 } /* switch */ 1127} 1128 1129/* 1130 * SendCommand:OMX_CommandStateSet 1131 * called in CmdHandler or called in other parts of component for reporting 1132 * internal error (OMX_StateInvalid). 1133 */ 1134/* 1135 * Todo 1136 * Resource Management (OMX_StateWaitForResources) 1137 * for now, we never notify OMX_ErrorInsufficientResources, 1138 * so IL client doesn't try to set component' state OMX_StateWaitForResources 1139 */ 1140static const char *state_name[OMX_StateWaitForResources + 1] = { 1141 "OMX_StateInvalid", 1142 "OMX_StateLoaded", 1143 "OMX_StateIdle", 1144 "OMX_StateExecuting", 1145 "OMX_StatePause", 1146 "OMX_StateWaitForResources", 1147}; 1148 1149static inline const char *GetStateName(OMX_STATETYPE state) 1150{ 1151 if (state > OMX_StateWaitForResources) 1152 return "UnKnown"; 1153 1154 return state_name[state]; 1155} 1156 1157void ComponentBase::TransState(OMX_STATETYPE transition) 1158{ 1159 OMX_STATETYPE current = this->state; 1160 OMX_EVENTTYPE event; 1161 OMX_U32 data1; 1162 OMX_ERRORTYPE ret; 1163 1164 LOGD("current state = %s, transition state = %s\n", 1165 GetStateName(current), GetStateName(transition)); 1166 1167 /* same state */ 1168 if (current == transition) { 1169 ret = OMX_ErrorSameState; 1170 goto notify_event; 1171 } 1172 1173 /* invalid state */ 1174 if (current == OMX_StateInvalid) { 1175 ret = OMX_ErrorInvalidState; 1176 goto notify_event; 1177 } 1178 1179 if (transition == OMX_StateLoaded) 1180 ret = TransStateToLoaded(current); 1181 else if (transition == OMX_StateIdle) 1182 ret = TransStateToIdle(current); 1183 else if (transition == OMX_StateExecuting) 1184 ret = TransStateToExecuting(current); 1185 else if (transition == OMX_StatePause) 1186 ret = TransStateToPause(current); 1187 else if (transition == OMX_StateInvalid) 1188 ret = TransStateToInvalid(current); 1189 else if (transition == OMX_StateWaitForResources) 1190 ret = TransStateToWaitForResources(current); 1191 else 1192 ret = OMX_ErrorIncorrectStateTransition; 1193 1194notify_event: 1195 if (ret == OMX_ErrorNone) { 1196 event = OMX_EventCmdComplete; 1197 data1 = transition; 1198 1199 state = transition; 1200 LOGD("transition from %s to %s completed\n", 1201 GetStateName(current), GetStateName(transition)); 1202 } 1203 else { 1204 event = OMX_EventError; 1205 data1 = ret; 1206 1207 if (transition == OMX_StateInvalid) { 1208 state = transition; 1209 LOGD("transition from %s to %s completed\n", 1210 GetStateName(current), GetStateName(transition)); 1211 } 1212 } 1213 1214 callbacks->EventHandler(handle, appdata, event, data1, 0, NULL); 1215 1216 /* WaitForResources workaround */ 1217 if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources) 1218 callbacks->EventHandler(handle, appdata, 1219 OMX_EventResourcesAcquired, 0, 0, NULL); 1220} 1221 1222inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current) 1223{ 1224 OMX_ERRORTYPE ret; 1225 1226 if (current == OMX_StateIdle) { 1227 /* 1228 * Todo 1229 * 1. waits for completion of deallocation on each port 1230 * wokeup by FreeBuffer() 1231 * 2. deinitialize buffer process work 1232 * 3. deinitialize component's internal processor 1233 * (ex. deinitialize sw/hw codec) 1234 */ 1235 OMX_U32 i; 1236 1237 for (i = 0; i < nr_ports; i++) 1238 ports[i]->WaitPortBufferCompletion(); 1239 1240 ret = OMX_ErrorNone; 1241 } 1242 else if (current == OMX_StateWaitForResources) { 1243 LOGE("state transition's requested from WaitForResources to " 1244 "Loaded\n"); 1245 1246 /* 1247 * from WaitForResources to Loaded considered from Loaded to Loaded. 1248 * do nothing 1249 */ 1250 1251 ret = OMX_ErrorNone; 1252 } 1253 else 1254 ret = OMX_ErrorIncorrectStateOperation; 1255 1256 return ret; 1257} 1258 1259inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current) 1260{ 1261 OMX_ERRORTYPE ret; 1262 1263 if (current == OMX_StateLoaded) { 1264 /* 1265 * Todo 1266 * 1. waits for completion of allocation on each port. 1267 * wokeup by Allocate/UseBuffer() 1268 * 2. initialize buffer process work. 1269 * 3. initialize component's internal processor. 1270 * (ex. initialize sw/hw codec) 1271 */ 1272 OMX_U32 i; 1273 1274 ret = ApplyWorkingRole(); 1275 if (ret != OMX_ErrorNone) 1276 return ret; 1277 1278 for (i = 0; i < nr_ports; i++) 1279 ports[i]->WaitPortBufferCompletion(); 1280 1281 ret = OMX_ErrorNone; 1282 } 1283 else if (current == OMX_StateExecuting) { 1284 /* 1285 * Todo 1286 * 1. returns all buffers to thier suppliers. ! 1287 * call Fill/EmptyBufferDone() for all ports 1288 * 2. stop buffer process work ! 1289 * 3. stop component's internal processor 1290 */ 1291 OMX_U32 i; 1292 1293 pthread_mutex_lock(&ports_block); 1294 for (i = 0; i < nr_ports; i++) { 1295 ports[i]->FlushPort(); 1296 } 1297 pthread_mutex_unlock(&ports_block); 1298 1299 bufferwork->StopWork(); 1300 1301 ret = OMX_ErrorNone; 1302 } 1303 else if (current == OMX_StatePause) { 1304 /* 1305 * Todo 1306 * 1. returns all buffers to thier suppliers. ! 1307 * call Fill/EmptyBufferDone() for all ports 1308 * 2. discard queued work, stop buffer process work ! 1309 * 3. stop component's internal processor 1310 */ 1311 OMX_U32 i; 1312 1313 pthread_mutex_lock(&ports_block); 1314 for (i = 0; i < nr_ports; i++) { 1315 ports[i]->FlushPort(); 1316 } 1317 pthread_mutex_unlock(&ports_block); 1318 1319 bufferwork->CancelScheduledWork(this); 1320 bufferwork->StopWork(); 1321 1322 ret = OMX_ErrorNone; 1323 } 1324 else if (current == OMX_StateWaitForResources) { 1325 LOGE("state transition's requested from WaitForResources to Idle\n"); 1326 1327 /* same as Loaded to Idle BUT DO NOTHING for now */ 1328 1329 ret = OMX_ErrorNone; 1330 } 1331 else 1332 ret = OMX_ErrorIncorrectStateOperation; 1333 1334 return ret; 1335} 1336 1337inline OMX_ERRORTYPE 1338ComponentBase::TransStateToExecuting(OMX_STATETYPE current) 1339{ 1340 OMX_ERRORTYPE ret; 1341 1342 if (current == OMX_StateIdle) { 1343 /* 1344 * Todo 1345 * 1. start component's internal processor 1346 * 2. start processing buffers on each port ! 1347 */ 1348 1349 pthread_mutex_lock(&executing_lock); 1350 executing = true; 1351 pthread_mutex_unlock(&executing_lock); 1352 1353 bufferwork->StartWork(); 1354 ret = OMX_ErrorNone; 1355 } 1356 else if (current == OMX_StatePause) { 1357 /* 1358 * Todo 1359 * 1. resume component's internal processor 1360 * 2. resume buffer process work ! 1361 */ 1362 1363 pthread_mutex_lock(&executing_lock); 1364 executing = true; 1365 pthread_cond_signal(&executing_wait); 1366 pthread_mutex_unlock(&executing_lock); 1367 1368 ret = OMX_ErrorNone; 1369 } 1370 else 1371 ret = OMX_ErrorIncorrectStateOperation; 1372 1373 return ret; 1374} 1375 1376inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current) 1377{ 1378 OMX_ERRORTYPE ret; 1379 1380 if (current == OMX_StateIdle) { 1381 /* 1382 * Todo 1383 * 1. start(paused) component's internal processor 1384 * 2. start(paused) processing buffers on each port ! 1385 */ 1386 1387 /* turn off executing flag */ 1388 pthread_mutex_lock(&executing_lock); 1389 executing = false; 1390 pthread_mutex_unlock(&executing_lock); 1391 1392 bufferwork->StartWork(); 1393 1394 ret = OMX_ErrorNone; 1395 } 1396 else if (current == OMX_StateExecuting) { 1397 /* 1398 * Todo 1399 * 1. pause buffer process work ! 1400 * 2. pause component's internal processor 1401 */ 1402 1403 pthread_mutex_lock(&executing_lock); 1404 executing = false; 1405 pthread_mutex_unlock(&executing_lock); 1406 1407 ret = OMX_ErrorNone; 1408 } 1409 else 1410 ret = OMX_ErrorIncorrectStateOperation; 1411 1412 return ret; 1413} 1414 1415inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current) 1416{ 1417 OMX_ERRORTYPE ret = OMX_ErrorInvalidState; 1418 1419 /* 1420 * Todo 1421 * graceful escape 1422 */ 1423 1424 return ret; 1425} 1426 1427inline OMX_ERRORTYPE 1428ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current) 1429{ 1430 OMX_ERRORTYPE ret; 1431 1432 if (current == OMX_StateLoaded) { 1433 LOGE("state transition's requested from Loaded to WaitForResources\n"); 1434 ret = OMX_ErrorNone; 1435 } 1436 else 1437 ret = OMX_ErrorIncorrectStateOperation; 1438 1439 return ret; 1440} 1441 1442/* set working role */ 1443OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role) 1444{ 1445 OMX_U32 i; 1446 1447 if (!role) { 1448 working_role = NULL; 1449 return OMX_ErrorNone; 1450 } 1451 1452 for (i = 0; i < nr_roles; i++) { 1453 if (!strcmp((char *)&roles[i][0], role)) { 1454 working_role = (OMX_STRING)&roles[i][0]; 1455 return OMX_ErrorNone; 1456 } 1457 } 1458 1459 LOGE("cannot find %s role in %s\n", role, name); 1460 return OMX_ErrorBadParameter; 1461} 1462 1463/* apply a working role for a component having multiple roles */ 1464OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void) 1465{ 1466 OMX_ERRORTYPE ret; 1467 1468 if (!working_role) 1469 return OMX_ErrorBadParameter; 1470 1471 ret = AllocatePorts(); 1472 if (ret != OMX_ErrorNone) { 1473 LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret); 1474 return ret; 1475 } 1476 1477 return OMX_ErrorNone; 1478} 1479 1480OMX_ERRORTYPE ComponentBase::AllocatePorts(void) 1481{ 1482 OMX_ERRORTYPE ret; 1483 OMX_U32 i; 1484 1485 if (ports) 1486 return OMX_ErrorBadParameter; 1487 1488 if (!callbacks || !appdata) 1489 return OMX_ErrorBadParameter; 1490 1491 ret = ComponentAllocatePorts(); 1492 if (ret != OMX_ErrorNone) { 1493 LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n", 1494 name, ret); 1495 return ret; 1496 } 1497 1498 /* now we can access ports */ 1499 for (i = 0; i < nr_ports; i++) { 1500 ports[i]->SetOwner(handle); 1501 ports[i]->SetCallbacks(handle, callbacks, appdata); 1502 } 1503 1504 return OMX_ErrorNone; 1505} 1506 1507/* called int FreeHandle() */ 1508OMX_ERRORTYPE ComponentBase::FreePorts(void) 1509{ 1510 if (ports) { 1511 OMX_U32 i, this_nr_ports = this->nr_ports; 1512 1513 for (i = 0; i < this_nr_ports; i++) { 1514 if (ports[i]) { 1515 delete ports[i]; 1516 ports[i] = NULL; 1517 } 1518 } 1519 delete []ports; 1520 ports = NULL; 1521 } 1522 1523 return OMX_ErrorNone; 1524} 1525 1526/* buffer processing */ 1527/* implement WorkableInterface */ 1528void ComponentBase::Work(void) 1529{ 1530 OMX_BUFFERHEADERTYPE **buffers = NULL; 1531 OMX_U32 i; 1532 bool avail = false; 1533 1534 pthread_mutex_lock(&executing_lock); 1535 if (!executing) 1536 pthread_cond_wait(&executing_wait, &executing_lock); 1537 pthread_mutex_unlock(&executing_lock); 1538 1539 pthread_mutex_lock(&ports_block); 1540 1541 avail = IsAllBufferAvailable(); 1542 if (avail) { 1543 buffers = (OMX_BUFFERHEADERTYPE **) 1544 calloc(nr_ports, sizeof(OMX_BUFFERHEADERTYPE *)); 1545 if (!buffers) { 1546 bufferwork->ScheduleWork(this); 1547 return; 1548 } 1549 1550 for (i = 0; i < nr_ports; i++) 1551 buffers[i] = ports[i]->PopBuffer(); 1552 } 1553 ScheduleIfAllBufferAvailable(); 1554 1555 pthread_mutex_unlock(&ports_block); 1556 1557 if (buffers) { 1558 ComponentProcessBuffers(buffers, nr_ports); 1559 1560 free(buffers); 1561 buffers = NULL; 1562 } 1563} 1564 1565bool ComponentBase::IsAllBufferAvailable(void) 1566{ 1567 OMX_U32 i; 1568 OMX_U32 nr_avail = 0; 1569 1570 for (i = 0; i < nr_ports; i++) { 1571 OMX_U32 length; 1572 1573 length = ports[i]->BufferQueueLength(); 1574 if (length) 1575 nr_avail++; 1576 } 1577 1578 if (nr_avail == nr_ports) 1579 return true; 1580 else 1581 return false; 1582} 1583 1584void ComponentBase::ScheduleIfAllBufferAvailable(void) 1585{ 1586 bool avail; 1587 1588 avail = IsAllBufferAvailable(); 1589 if (avail) 1590 bufferwork->ScheduleWork(this); 1591} 1592 1593/* end of component methods & helpers */ 1594 1595/* 1596 * omx header manipuation 1597 */ 1598void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size) 1599{ 1600 OMX_U32 *nsize; 1601 OMX_VERSIONTYPE *nversion; 1602 1603 if (!type) 1604 return; 1605 1606 nsize = (OMX_U32 *)type; 1607 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 1608 1609 *nsize = size; 1610 nversion->nVersion = OMX_SPEC_VERSION; 1611} 1612 1613OMX_ERRORTYPE ComponentBase::CheckTypeHeader(OMX_PTR type, OMX_U32 size) 1614{ 1615 OMX_U32 *nsize; 1616 OMX_VERSIONTYPE *nversion; 1617 1618 if (!type) 1619 return OMX_ErrorBadParameter; 1620 1621 nsize = (OMX_U32 *)type; 1622 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 1623 1624 if (*nsize != size) 1625 return OMX_ErrorBadParameter; 1626 1627 if (nversion->nVersion != OMX_SPEC_VERSION) 1628 return OMX_ErrorVersionMismatch; 1629 1630 return OMX_ErrorNone; 1631} 1632 1633/* end of ComponentBase */ 1634