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