componentbase.cpp revision 9a24011eec9b06ae84b9335c651999b9d5e25329
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 ports = NULL; 118 nr_ports = 0; 119 memset(&portparam, 0, sizeof(portparam)); 120 121 state = OMX_StateUnloaded; 122 123 cmdwork = new CmdProcessWork(this); 124} 125 126ComponentBase::ComponentBase() 127{ 128 __ComponentBase(); 129} 130 131ComponentBase::ComponentBase(const OMX_STRING name) 132{ 133 __ComponentBase(); 134 SetName(name); 135} 136 137ComponentBase::~ComponentBase() 138{ 139 delete cmdwork; 140 141 if (roles) { 142 OMX_U32 i; 143 144 for (i = 0; i < nr_roles; i++) 145 free(roles[i]); 146 147 free(roles); 148 } 149} 150 151/* end of constructor & destructor */ 152 153/* 154 * accessor 155 */ 156/* name */ 157void ComponentBase::SetName(const OMX_STRING name) 158{ 159 strncpy(this->name, name, OMX_MAX_STRINGNAME_SIZE); 160 this->name[OMX_MAX_STRINGNAME_SIZE-1] = '\0'; 161} 162 163const OMX_STRING ComponentBase::GetName(void) 164{ 165 return name; 166} 167 168/* component module */ 169void ComponentBase::SetCModule(CModule *cmodule) 170{ 171 this->cmodule = cmodule; 172} 173 174CModule *ComponentBase::GetCModule(void) 175{ 176 return cmodule; 177} 178 179/* end of accessor */ 180 181/* 182 * core methods & helpers 183 */ 184/* roles */ 185OMX_ERRORTYPE ComponentBase::SetRolesOfComponent(OMX_U32 nr_roles, 186 const OMX_U8 **roles) 187{ 188 OMX_U32 i; 189 190 this->roles = (OMX_U8 **)malloc(sizeof(OMX_STRING) * nr_roles); 191 if (!this->roles) 192 return OMX_ErrorInsufficientResources; 193 194 for (i = 0; i < nr_roles; i++) { 195 this->roles[i] = (OMX_U8 *)malloc(OMX_MAX_STRINGNAME_SIZE); 196 if (!this->roles[i]) { 197 int j; 198 199 for (j = (int )i-1; j >= 0; j--) 200 free(this->roles[j]); 201 free(this->roles); 202 203 return OMX_ErrorInsufficientResources; 204 } 205 206 strncpy((OMX_STRING)&this->roles[i][0], 207 (const OMX_STRING)&roles[i][0], 208 OMX_MAX_STRINGNAME_SIZE); 209 } 210 211 this->nr_roles = nr_roles; 212 return OMX_ErrorNone; 213} 214 215OMX_ERRORTYPE ComponentBase::GetRolesOfComponent(OMX_U32 *nr_roles, 216 OMX_U8 **roles) 217{ 218 OMX_U32 i; 219 OMX_U32 this_nr_roles = this->nr_roles; 220 221 if (!roles) { 222 *nr_roles = this_nr_roles; 223 return OMX_ErrorNone; 224 } 225 226 if (!nr_roles || (*nr_roles != this_nr_roles)) 227 return OMX_ErrorBadParameter; 228 229 for (i = 0; i < this_nr_roles; i++) { 230 if (!roles[i]) 231 break; 232 233 if (roles && roles[i]) 234 strncpy((OMX_STRING)&roles[i][0], 235 (const OMX_STRING)&this->roles[i][0], 236 OMX_MAX_STRINGNAME_SIZE); 237 } 238 239 if (i != this_nr_roles) 240 return OMX_ErrorBadParameter; 241 242 *nr_roles = this_nr_roles; 243 return OMX_ErrorNone; 244} 245 246bool ComponentBase::QueryHavingThisRole(const OMX_STRING role) 247{ 248 OMX_U32 i; 249 250 if (!roles || !role) 251 return false; 252 253 for (i = 0; i < nr_roles; i++) { 254 if (!strcmp((OMX_STRING)&roles[i][0], role)) 255 return true; 256 } 257 258 return false; 259} 260 261/* GetHandle & FreeHandle */ 262OMX_ERRORTYPE ComponentBase::GetHandle(OMX_HANDLETYPE *pHandle, 263 OMX_PTR pAppData, 264 OMX_CALLBACKTYPE *pCallBacks) 265{ 266 OMX_U32 i; 267 OMX_ERRORTYPE ret; 268 269 if (handle) 270 return OMX_ErrorUndefined; 271 272 handle = (OMX_COMPONENTTYPE *)calloc(1, sizeof(*handle)); 273 if (!handle) 274 return OMX_ErrorInsufficientResources; 275 276 /* handle initialization */ 277 SetTypeHeader(handle, sizeof(*handle)); 278 handle->pComponentPrivate = static_cast<OMX_PTR>(this); 279 handle->pApplicationPrivate = pAppData; 280 281 /* virtual - see derived class */ 282 ret = InitComponent(); 283 if (ret != OMX_ErrorNone) { 284 LOGE("failed to %s::InitComponent(), ret = 0x%08x\n", 285 name, ret); 286 goto free_handle; 287 } 288 289 for (i = 0; i < nr_ports; i++) { 290 ports[i]->SetOwner(handle); 291 ports[i]->SetCallbacks(handle, pCallBacks, pAppData); 292 } 293 294 /* connect handle's functions */ 295 handle->GetComponentVersion = GetComponentVersion; 296 handle->SendCommand = SendCommand; 297 handle->GetParameter = GetParameter; 298 handle->SetParameter = SetParameter; 299 handle->GetConfig = GetConfig; 300 handle->SetConfig = SetConfig; 301 handle->GetExtensionIndex = GetExtensionIndex; 302 handle->GetState = GetState; 303 handle->ComponentTunnelRequest = ComponentTunnelRequest; 304 handle->UseBuffer = UseBuffer; 305 handle->AllocateBuffer = AllocateBuffer; 306 handle->FreeBuffer = FreeBuffer; 307 handle->EmptyThisBuffer = EmptyThisBuffer; 308 handle->FillThisBuffer = FillThisBuffer; 309 handle->SetCallbacks = SetCallbacks; 310 handle->ComponentDeInit = ComponentDeInit; 311 handle->UseEGLImage = UseEGLImage; 312 handle->ComponentRoleEnum = ComponentRoleEnum; 313 314 appdata = pAppData; 315 callbacks = pCallBacks; 316 *pHandle = (OMX_HANDLETYPE *)handle; 317 318 state = OMX_StateLoaded; 319 return OMX_ErrorNone; 320 321free_handle: 322 free(this->handle); 323 this->handle = NULL; 324 325 return ret; 326} 327 328OMX_ERRORTYPE ComponentBase::FreeHandle(OMX_HANDLETYPE hComponent) 329{ 330 OMX_ERRORTYPE ret; 331 332 if (hComponent != handle) 333 return OMX_ErrorBadParameter; 334 335 /* virtual - see derived class */ 336 ret = ExitComponent(); 337 if (ret != OMX_ErrorNone) 338 return ret; 339 340 free(handle); 341 342 appdata = NULL; 343 callbacks = NULL; 344 345 state = OMX_StateUnloaded; 346 return OMX_ErrorNone; 347} 348 349/* end of core methods & helpers */ 350 351/* 352 * component methods & helpers 353 */ 354OMX_ERRORTYPE ComponentBase::GetComponentVersion( 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 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->CBaseGetComponentVersion(hComponent, 372 pComponentName, 373 pComponentVersion, 374 pSpecVersion, 375 pComponentUUID); 376} 377 378OMX_ERRORTYPE ComponentBase::CBaseGetComponentVersion( 379 OMX_IN OMX_HANDLETYPE hComponent, 380 OMX_OUT OMX_STRING pComponentName, 381 OMX_OUT OMX_VERSIONTYPE* pComponentVersion, 382 OMX_OUT OMX_VERSIONTYPE* pSpecVersion, 383 OMX_OUT OMX_UUIDTYPE* pComponentUUID) 384{ 385 /* 386 * Todo 387 */ 388 389 return OMX_ErrorNotImplemented; 390} 391 392OMX_ERRORTYPE ComponentBase::SendCommand( 393 OMX_IN OMX_HANDLETYPE hComponent, 394 OMX_IN OMX_COMMANDTYPE Cmd, 395 OMX_IN OMX_U32 nParam1, 396 OMX_IN OMX_PTR pCmdData) 397{ 398 ComponentBase *cbase; 399 400 if (!hComponent) 401 return OMX_ErrorBadParameter; 402 403 cbase = static_cast<ComponentBase *> 404 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 405 if (!cbase) 406 return OMX_ErrorBadParameter; 407 408 return cbase->CBaseSendCommand(hComponent, Cmd, nParam1, pCmdData); 409} 410 411OMX_ERRORTYPE ComponentBase::CBaseSendCommand( 412 OMX_IN OMX_HANDLETYPE hComponent, 413 OMX_IN OMX_COMMANDTYPE Cmd, 414 OMX_IN OMX_U32 nParam1, 415 OMX_IN OMX_PTR pCmdData) 416{ 417 struct cmd_s *cmd; 418 419 if (hComponent != handle) 420 return OMX_ErrorInvalidComponent; 421 422 /* basic error check */ 423 switch (Cmd) { 424 case OMX_CommandStateSet: 425 /* 426 * Todo 427 */ 428 break; 429 case OMX_CommandFlush: 430 /* 431 * Todo 432 */ 433 //break; 434 case OMX_CommandPortDisable: 435 /* 436 * Todo 437 */ 438 //break; 439 case OMX_CommandPortEnable: 440 /* 441 * Todo 442 */ 443 //break; 444 case OMX_CommandMarkBuffer: 445 /* 446 * Todo 447 */ 448 //break; 449 default: 450 LOGE("command %d not supported\n", Cmd); 451 return OMX_ErrorUnsupportedIndex; 452 } 453 454 cmd = (struct cmd_s *)malloc(sizeof(*cmd)); 455 if (!cmd) 456 return OMX_ErrorInsufficientResources; 457 458 cmd->cmd = Cmd; 459 cmd->param1 = nParam1; 460 cmd->cmddata = pCmdData; 461 462 return cmdwork->PushCmdQueue(cmd); 463} 464 465OMX_ERRORTYPE ComponentBase::GetParameter( 466 OMX_IN OMX_HANDLETYPE hComponent, 467 OMX_IN OMX_INDEXTYPE nParamIndex, 468 OMX_INOUT OMX_PTR pComponentParameterStructure) 469{ 470 ComponentBase *cbase; 471 472 if (!hComponent) 473 return OMX_ErrorBadParameter; 474 475 cbase = static_cast<ComponentBase *> 476 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 477 if (!cbase) 478 return OMX_ErrorBadParameter; 479 480 return cbase->CBaseGetParameter(hComponent, nParamIndex, 481 pComponentParameterStructure); 482} 483 484OMX_ERRORTYPE ComponentBase::CBaseGetParameter( 485 OMX_IN OMX_HANDLETYPE hComponent, 486 OMX_IN OMX_INDEXTYPE nParamIndex, 487 OMX_INOUT OMX_PTR pComponentParameterStructure) 488{ 489 OMX_ERRORTYPE ret = OMX_ErrorNone; 490 491 if (hComponent != handle) 492 return OMX_ErrorBadParameter; 493 494 switch (nParamIndex) { 495 case OMX_IndexParamAudioInit: 496 case OMX_IndexParamVideoInit: 497 case OMX_IndexParamImageInit: 498 case OMX_IndexParamOtherInit: { 499 OMX_PORT_PARAM_TYPE *p = 500 (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure; 501 502 memcpy(p, &portparam, sizeof(*p)); 503 break; 504 } 505 case OMX_IndexParamPortDefinition: { 506 OMX_PARAM_PORTDEFINITIONTYPE *p = 507 (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; 508 OMX_U32 index = p->nPortIndex; 509 PortBase *port = ports[index]; 510 511 memcpy(p, port->GetPortParam(), sizeof(*p)); 512 break; 513 } 514 case OMX_IndexParamAudioPortFormat: { 515 OMX_AUDIO_PARAM_PORTFORMATTYPE *p = 516 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure; 517 OMX_U32 index = p->nPortIndex; 518 PortBase *port = ports[index]; 519 520 memcpy(p, port->GetAudioPortParam(), sizeof(*p)); 521 break; 522 } 523 case OMX_IndexParamCompBufferSupplier: 524 /* 525 * Todo 526 */ 527 528 ret = OMX_ErrorUnsupportedIndex; 529 break; 530 default: 531 ret = ComponentGetParameter(nParamIndex, pComponentParameterStructure); 532 } /* switch */ 533 534 return ret; 535} 536 537OMX_ERRORTYPE ComponentBase::SetParameter( 538 OMX_IN OMX_HANDLETYPE hComponent, 539 OMX_IN OMX_INDEXTYPE nIndex, 540 OMX_IN OMX_PTR pComponentParameterStructure) 541{ 542 ComponentBase *cbase; 543 544 if (!hComponent) 545 return OMX_ErrorBadParameter; 546 547 cbase = static_cast<ComponentBase *> 548 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 549 if (!cbase) 550 return OMX_ErrorBadParameter; 551 552 return cbase->CBaseSetParameter(hComponent, nIndex, 553 pComponentParameterStructure); 554} 555 556OMX_ERRORTYPE ComponentBase::CBaseSetParameter( 557 OMX_IN OMX_HANDLETYPE hComponent, 558 OMX_IN OMX_INDEXTYPE nIndex, 559 OMX_IN OMX_PTR pComponentParameterStructure) 560{ 561 OMX_ERRORTYPE ret = OMX_ErrorNone; 562 563 if (hComponent != handle) 564 return OMX_ErrorBadParameter; 565 566 switch (nIndex) { 567 case OMX_IndexParamAudioInit: 568 case OMX_IndexParamVideoInit: 569 case OMX_IndexParamImageInit: 570 case OMX_IndexParamOtherInit: { 571 OMX_PORT_PARAM_TYPE *p = (OMX_PORT_PARAM_TYPE *) 572 pComponentParameterStructure; 573 574 memcpy(&portparam, p, sizeof(*p)); 575 break; 576 } 577 case OMX_IndexParamPortDefinition: { 578 OMX_PARAM_PORTDEFINITIONTYPE *p = 579 (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; 580 OMX_U32 index = p->nPortIndex; 581 PortBase *port = ports[index]; 582 583 port->SetPortParam(p); 584 break; 585 } 586 case OMX_IndexParamAudioPortFormat: { 587 OMX_AUDIO_PARAM_PORTFORMATTYPE *p = 588 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure; 589 OMX_U32 index = p->nPortIndex; 590 PortBase *port = ports[index]; 591 592 port->SetAudioPortParam(p); 593 break; 594 } 595 case OMX_IndexParamCompBufferSupplier: 596 /* 597 * Todo 598 */ 599 600 ret = OMX_ErrorUnsupportedIndex; 601 break; 602 default: 603 ret = ComponentSetParameter(nIndex, pComponentParameterStructure); 604 } /* switch */ 605 606 return ret; 607} 608 609OMX_ERRORTYPE ComponentBase::GetConfig( 610 OMX_IN OMX_HANDLETYPE hComponent, 611 OMX_IN OMX_INDEXTYPE nIndex, 612 OMX_INOUT OMX_PTR pComponentConfigStructure) 613{ 614 ComponentBase *cbase; 615 616 if (!hComponent) 617 return OMX_ErrorBadParameter; 618 619 cbase = static_cast<ComponentBase *> 620 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 621 if (!cbase) 622 return OMX_ErrorBadParameter; 623 624 return cbase->CBaseGetConfig(hComponent, nIndex, 625 pComponentConfigStructure); 626} 627 628OMX_ERRORTYPE ComponentBase::CBaseGetConfig( 629 OMX_IN OMX_HANDLETYPE hComponent, 630 OMX_IN OMX_INDEXTYPE nIndex, 631 OMX_INOUT OMX_PTR pComponentConfigStructure) 632{ 633 OMX_ERRORTYPE ret; 634 635 if (hComponent != handle) 636 return OMX_ErrorBadParameter; 637 638 switch (nIndex) { 639 default: 640 ret = ComponentGetConfig(nIndex, pComponentConfigStructure); 641 } 642 643 return ret; 644} 645 646OMX_ERRORTYPE ComponentBase::SetConfig( 647 OMX_IN OMX_HANDLETYPE hComponent, 648 OMX_IN OMX_INDEXTYPE nIndex, 649 OMX_IN OMX_PTR pComponentConfigStructure) 650{ 651 ComponentBase *cbase; 652 653 if (!hComponent) 654 return OMX_ErrorBadParameter; 655 656 cbase = static_cast<ComponentBase *> 657 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 658 if (!cbase) 659 return OMX_ErrorBadParameter; 660 661 return cbase->CBaseSetConfig(hComponent, nIndex, 662 pComponentConfigStructure); 663} 664 665OMX_ERRORTYPE ComponentBase::CBaseSetConfig( 666 OMX_IN OMX_HANDLETYPE hComponent, 667 OMX_IN OMX_INDEXTYPE nIndex, 668 OMX_IN OMX_PTR pComponentConfigStructure) 669{ 670 OMX_ERRORTYPE ret; 671 672 if (hComponent != handle) 673 return OMX_ErrorBadParameter; 674 675 switch (nIndex) { 676 default: 677 ret = ComponentSetConfig(nIndex, pComponentConfigStructure); 678 } 679 680 return ret; 681} 682 683OMX_ERRORTYPE ComponentBase::GetExtensionIndex( 684 OMX_IN OMX_HANDLETYPE hComponent, 685 OMX_IN OMX_STRING cParameterName, 686 OMX_OUT OMX_INDEXTYPE* pIndexType) 687{ 688 ComponentBase *cbase; 689 690 if (!hComponent) 691 return OMX_ErrorBadParameter; 692 693 cbase = static_cast<ComponentBase *> 694 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 695 if (!cbase) 696 return OMX_ErrorBadParameter; 697 698 return cbase->CBaseGetExtensionIndex(hComponent, cParameterName, 699 pIndexType); 700} 701 702OMX_ERRORTYPE ComponentBase::CBaseGetExtensionIndex( 703 OMX_IN OMX_HANDLETYPE hComponent, 704 OMX_IN OMX_STRING cParameterName, 705 OMX_OUT OMX_INDEXTYPE* pIndexType) 706{ 707 /* 708 * Todo 709 */ 710 711 return OMX_ErrorNotImplemented; 712} 713 714OMX_ERRORTYPE ComponentBase::GetState( 715 OMX_IN OMX_HANDLETYPE hComponent, 716 OMX_OUT OMX_STATETYPE* pState) 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->CBaseGetState(hComponent, pState); 729} 730 731OMX_ERRORTYPE ComponentBase::CBaseGetState( 732 OMX_IN OMX_HANDLETYPE hComponent, 733 OMX_OUT OMX_STATETYPE* pState) 734{ 735 if (hComponent != handle) 736 return OMX_ErrorBadParameter; 737 738 *pState = state; 739 return OMX_ErrorNone; 740} 741 742OMX_ERRORTYPE ComponentBase::ComponentTunnelRequest( 743 OMX_IN OMX_HANDLETYPE hComponent, 744 OMX_IN OMX_U32 nPort, 745 OMX_IN OMX_HANDLETYPE hTunneledComponent, 746 OMX_IN OMX_U32 nTunneledPort, 747 OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup) 748{ 749 ComponentBase *cbase; 750 751 if (!hComponent) 752 return OMX_ErrorBadParameter; 753 754 cbase = static_cast<ComponentBase *> 755 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 756 if (!cbase) 757 return OMX_ErrorBadParameter; 758 759 return cbase->CBaseComponentTunnelRequest(hComponent, nPort, 760 hTunneledComponent, 761 nTunneledPort, pTunnelSetup); 762} 763 764OMX_ERRORTYPE ComponentBase::CBaseComponentTunnelRequest( 765 OMX_IN OMX_HANDLETYPE hComp, 766 OMX_IN OMX_U32 nPort, 767 OMX_IN OMX_HANDLETYPE hTunneledComp, 768 OMX_IN OMX_U32 nTunneledPort, 769 OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup) 770{ 771 /* 772 * Todo 773 */ 774 775 return OMX_ErrorNotImplemented; 776} 777 778OMX_ERRORTYPE ComponentBase::UseBuffer( 779 OMX_IN OMX_HANDLETYPE hComponent, 780 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 781 OMX_IN OMX_U32 nPortIndex, 782 OMX_IN OMX_PTR pAppPrivate, 783 OMX_IN OMX_U32 nSizeBytes, 784 OMX_IN OMX_U8 *pBuffer) 785{ 786 ComponentBase *cbase; 787 788 if (!hComponent) 789 return OMX_ErrorBadParameter; 790 791 cbase = static_cast<ComponentBase *> 792 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 793 if (!cbase) 794 return OMX_ErrorBadParameter; 795 796 return cbase->CBaseUseBuffer(hComponent, ppBufferHdr, nPortIndex, 797 pAppPrivate, nSizeBytes, pBuffer); 798} 799 800OMX_ERRORTYPE ComponentBase::CBaseUseBuffer( 801 OMX_IN OMX_HANDLETYPE hComponent, 802 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 803 OMX_IN OMX_U32 nPortIndex, 804 OMX_IN OMX_PTR pAppPrivate, 805 OMX_IN OMX_U32 nSizeBytes, 806 OMX_IN OMX_U8 *pBuffer) 807{ 808 PortBase *port = NULL; 809 OMX_ERRORTYPE ret; 810 811 if (hComponent != handle) 812 return OMX_ErrorBadParameter; 813 814 if (ports) 815 if (nPortIndex < nr_ports) 816 port = ports[nPortIndex]; 817 818 if (!port) 819 return OMX_ErrorBadParameter; 820 821 return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, 822 pBuffer); 823} 824 825OMX_ERRORTYPE ComponentBase::AllocateBuffer( 826 OMX_IN OMX_HANDLETYPE hComponent, 827 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 828 OMX_IN OMX_U32 nPortIndex, 829 OMX_IN OMX_PTR pAppPrivate, 830 OMX_IN OMX_U32 nSizeBytes) 831{ 832 ComponentBase *cbase; 833 834 if (!hComponent) 835 return OMX_ErrorBadParameter; 836 837 cbase = static_cast<ComponentBase *> 838 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 839 if (!cbase) 840 return OMX_ErrorBadParameter; 841 842 return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex, 843 pAppPrivate, nSizeBytes); 844} 845 846OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer( 847 OMX_IN OMX_HANDLETYPE hComponent, 848 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 849 OMX_IN OMX_U32 nPortIndex, 850 OMX_IN OMX_PTR pAppPrivate, 851 OMX_IN OMX_U32 nSizeBytes) 852{ 853 PortBase *port = NULL; 854 OMX_ERRORTYPE ret; 855 856 if (hComponent != handle) 857 return OMX_ErrorBadParameter; 858 859 if (ports) 860 if (nPortIndex < nr_ports) 861 port = ports[nPortIndex]; 862 863 if (!port) 864 return OMX_ErrorBadParameter; 865 866 return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes); 867} 868 869OMX_ERRORTYPE ComponentBase::FreeBuffer( 870 OMX_IN OMX_HANDLETYPE hComponent, 871 OMX_IN OMX_U32 nPortIndex, 872 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 873{ 874 ComponentBase *cbase; 875 876 if (!hComponent) 877 return OMX_ErrorBadParameter; 878 879 cbase = static_cast<ComponentBase *> 880 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 881 if (!cbase) 882 return OMX_ErrorBadParameter; 883 884 return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer); 885} 886 887OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer( 888 OMX_IN OMX_HANDLETYPE hComponent, 889 OMX_IN OMX_U32 nPortIndex, 890 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 891{ 892 PortBase *port = NULL; 893 OMX_ERRORTYPE ret; 894 895 if (hComponent != handle) 896 return OMX_ErrorBadParameter; 897 898 if (ports) 899 if (nPortIndex < nr_ports) 900 port = ports[nPortIndex]; 901 902 if (!port) 903 return OMX_ErrorBadParameter; 904 905 return port->FreeBuffer(nPortIndex, pBuffer); 906} 907 908OMX_ERRORTYPE ComponentBase::EmptyThisBuffer( 909 OMX_IN OMX_HANDLETYPE hComponent, 910 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 911{ 912 ComponentBase *cbase; 913 914 if (!hComponent) 915 return OMX_ErrorBadParameter; 916 917 cbase = static_cast<ComponentBase *> 918 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 919 if (!cbase) 920 return OMX_ErrorBadParameter; 921 922 return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer); 923} 924 925OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer( 926 OMX_IN OMX_HANDLETYPE hComponent, 927 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 928{ 929 PortBase *port = NULL; 930 OMX_U32 port_index; 931 OMX_ERRORTYPE ret; 932 933 if ((hComponent != handle) || !pBuffer) 934 return OMX_ErrorBadParameter; 935 936 port_index = pBuffer->nInputPortIndex; 937 if (port_index == (OMX_U32)-1) 938 return OMX_ErrorBadParameter; 939 940 if (ports) 941 if (port_index < nr_ports) 942 port = ports[port_index]; 943 944 if (!port) 945 return OMX_ErrorBadParameter; 946 947 return port->PushThisBuffer(pBuffer); 948} 949 950OMX_ERRORTYPE ComponentBase::FillThisBuffer( 951 OMX_IN OMX_HANDLETYPE hComponent, 952 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 953{ 954 ComponentBase *cbase; 955 956 if (!hComponent) 957 return OMX_ErrorBadParameter; 958 959 cbase = static_cast<ComponentBase *> 960 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 961 if (!cbase) 962 return OMX_ErrorBadParameter; 963 964 return cbase->CBaseFillThisBuffer(hComponent, pBuffer); 965} 966 967OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer( 968 OMX_IN OMX_HANDLETYPE hComponent, 969 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 970{ 971 PortBase *port = NULL; 972 OMX_U32 port_index; 973 OMX_ERRORTYPE ret; 974 975 if ((hComponent != handle) || !pBuffer) 976 return OMX_ErrorBadParameter; 977 978 port_index = pBuffer->nOutputPortIndex; 979 if (port_index == (OMX_U32)-1) 980 return OMX_ErrorBadParameter; 981 982 if (ports) 983 if (port_index < nr_ports) 984 port = ports[port_index]; 985 986 if (!port) 987 return OMX_ErrorBadParameter; 988 989 return port->PushThisBuffer(pBuffer); 990} 991 992OMX_ERRORTYPE ComponentBase::SetCallbacks( 993 OMX_IN OMX_HANDLETYPE hComponent, 994 OMX_IN OMX_CALLBACKTYPE* pCallbacks, 995 OMX_IN OMX_PTR pAppData) 996{ 997 ComponentBase *cbase; 998 999 if (!hComponent) 1000 return OMX_ErrorBadParameter; 1001 1002 cbase = static_cast<ComponentBase *> 1003 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1004 if (!cbase) 1005 return OMX_ErrorBadParameter; 1006 1007 return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData); 1008} 1009 1010OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks( 1011 OMX_IN OMX_HANDLETYPE hComponent, 1012 OMX_IN OMX_CALLBACKTYPE *pCallbacks, 1013 OMX_IN OMX_PTR pAppData) 1014{ 1015 if (hComponent != handle) 1016 return OMX_ErrorBadParameter; 1017 1018 appdata = pAppData; 1019 callbacks = pCallbacks; 1020 1021 return OMX_ErrorNone; 1022} 1023 1024OMX_ERRORTYPE ComponentBase::ComponentDeInit( 1025 OMX_IN OMX_HANDLETYPE hComponent) 1026{ 1027 ComponentBase *cbase; 1028 1029 if (!hComponent) 1030 return OMX_ErrorBadParameter; 1031 1032 cbase = static_cast<ComponentBase *> 1033 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1034 if (!cbase) 1035 return OMX_ErrorBadParameter; 1036 1037 return cbase->CBaseComponentDeInit(hComponent); 1038} 1039 1040OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit( 1041 OMX_IN OMX_HANDLETYPE hComponent) 1042{ 1043 /* 1044 * Todo 1045 */ 1046 1047 return OMX_ErrorNotImplemented; 1048} 1049 1050OMX_ERRORTYPE ComponentBase::UseEGLImage( 1051 OMX_IN OMX_HANDLETYPE hComponent, 1052 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1053 OMX_IN OMX_U32 nPortIndex, 1054 OMX_IN OMX_PTR pAppPrivate, 1055 OMX_IN void* eglImage) 1056{ 1057 ComponentBase *cbase; 1058 1059 if (!hComponent) 1060 return OMX_ErrorBadParameter; 1061 1062 cbase = static_cast<ComponentBase *> 1063 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1064 if (!cbase) 1065 return OMX_ErrorBadParameter; 1066 1067 return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex, 1068 pAppPrivate, eglImage); 1069} 1070 1071OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage( 1072 OMX_IN OMX_HANDLETYPE hComponent, 1073 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1074 OMX_IN OMX_U32 nPortIndex, 1075 OMX_IN OMX_PTR pAppPrivate, 1076 OMX_IN void* eglImage) 1077{ 1078 /* 1079 * Todo 1080 */ 1081 1082 return OMX_ErrorNotImplemented; 1083} 1084 1085OMX_ERRORTYPE ComponentBase::ComponentRoleEnum( 1086 OMX_IN OMX_HANDLETYPE hComponent, 1087 OMX_OUT OMX_U8 *cRole, 1088 OMX_IN OMX_U32 nIndex) 1089{ 1090 ComponentBase *cbase; 1091 1092 if (!hComponent) 1093 return OMX_ErrorBadParameter; 1094 1095 cbase = static_cast<ComponentBase *> 1096 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1097 if (!cbase) 1098 return OMX_ErrorBadParameter; 1099 1100 return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex); 1101} 1102 1103OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum( 1104 OMX_IN OMX_HANDLETYPE hComponent, 1105 OMX_OUT OMX_U8 *cRole, 1106 OMX_IN OMX_U32 nIndex) 1107{ 1108 if (hComponent != (OMX_HANDLETYPE *)this->handle) 1109 return OMX_ErrorBadParameter; 1110 1111 if (nIndex > nr_roles) 1112 return OMX_ErrorBadParameter; 1113 1114 strncpy((char *)cRole, (const char *)roles[nIndex], 1115 OMX_MAX_STRINGNAME_SIZE); 1116 return OMX_ErrorNone; 1117} 1118 1119/* implement CmdHandlerInterface */ 1120void ComponentBase::CmdHandler(struct cmd_s *cmd) 1121{ 1122 switch (cmd->cmd) { 1123 case OMX_CommandStateSet: { 1124 OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1; 1125 1126 TransState(transition); 1127 break; 1128 } 1129 case OMX_CommandFlush: 1130 /* 1131 * Todo 1132 */ 1133 break; 1134 case OMX_CommandPortDisable: 1135 /* 1136 * Todo 1137 */ 1138 break; 1139 case OMX_CommandPortEnable: 1140 /* 1141 * Todo 1142 */ 1143 break; 1144 case OMX_CommandMarkBuffer: 1145 /* 1146 * Todo 1147 */ 1148 break; 1149 } /* switch */ 1150} 1151 1152/* 1153 * SendCommand:OMX_CommandStateSet 1154 * called in CmdHandler or called in other parts of component for reporting 1155 * internal error (OMX_StateInvalid). 1156 */ 1157/* 1158 * Todo 1159 * Resource Management (OMX_StateWaitForResources) 1160 * for now, we never notify OMX_ErrorInsufficientResources, 1161 * so IL client doesn't try to set component' state OMX_StateWaitForResources 1162 */ 1163static const char *state_name[OMX_StateWaitForResources + 1] = { 1164 "OMX_StateInvalid", 1165 "OMX_StateLoaded", 1166 "OMX_StateIdle", 1167 "OMX_StateExecuting", 1168 "OMX_StatePause", 1169 "OMX_StateWaitForResources", 1170}; 1171 1172static inline const char *GetStateName(OMX_STATETYPE state) 1173{ 1174 if (state > OMX_StateWaitForResources) 1175 return "UnKnown"; 1176 1177 return state_name[state]; 1178} 1179 1180void ComponentBase::TransState(OMX_STATETYPE transition) 1181{ 1182 OMX_STATETYPE current = this->state; 1183 OMX_EVENTTYPE event; 1184 OMX_U32 data1; 1185 OMX_ERRORTYPE ret; 1186 1187 LOGD("current state = %s, transition state = %s\n", 1188 GetStateName(current), GetStateName(transition)); 1189 1190 /* same state */ 1191 if (current == transition) { 1192 ret = OMX_ErrorSameState; 1193 goto notify_event; 1194 } 1195 1196 /* invalid state */ 1197 if (current == OMX_StateInvalid) { 1198 ret = OMX_ErrorInvalidState; 1199 goto notify_event; 1200 } 1201 1202 if (transition == OMX_StateLoaded) 1203 ret = TransStateToLoaded(current); 1204 else if (transition == OMX_StateIdle) 1205 ret = TransStateToIdle(current); 1206 else if (transition == OMX_StateExecuting) 1207 ret = TransStateToExecuting(current); 1208 else if (transition == OMX_StatePause) 1209 ret = TransStateToPause(current); 1210 else if (transition == OMX_StateInvalid) 1211 ret = TransStateToInvalid(current); 1212 else if (transition == OMX_StateWaitForResources) 1213 ret = TransStateToWaitForResources(current); 1214 else 1215 ret = OMX_ErrorIncorrectStateTransition; 1216 1217notify_event: 1218 if (ret == OMX_ErrorNone) { 1219 event = OMX_EventCmdComplete; 1220 data1 = transition; 1221 1222 state = transition; 1223 LOGD("transition from %s to %s completed\n", 1224 GetStateName(current), GetStateName(transition)); 1225 } 1226 else { 1227 event = OMX_EventError; 1228 data1 = ret; 1229 1230 if (transition == OMX_StateInvalid) { 1231 state = transition; 1232 LOGD("transition from %s to %s completed\n", 1233 GetStateName(current), GetStateName(transition)); 1234 } 1235 } 1236 1237 callbacks->EventHandler(handle, appdata, event, data1, 0, NULL); 1238 1239 /* WaitForResources workaround */ 1240 if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources) 1241 callbacks->EventHandler(handle, appdata, 1242 OMX_EventResourcesAcquired, 0, 0, NULL); 1243} 1244 1245inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current) 1246{ 1247 OMX_ERRORTYPE ret; 1248 1249 if (current == OMX_StateIdle) { 1250 /* 1251 * Todo 1252 * 1. waits for completion of deallocation on each port 1253 * wokeup by FreeBuffer() 1254 * 2. deinitialize buffer process work 1255 * 3. deinitialize component's internal processor 1256 * (ex. deinitialize sw/hw codec) 1257 */ 1258 OMX_U32 i; 1259 1260 for (i = 0; i < nr_ports; i++) 1261 ports[i]->WaitPortBufferCompletion(); 1262 1263 ret = OMX_ErrorNone; 1264 } 1265 else if (current == OMX_StateWaitForResources) { 1266 LOGE("state transition's requested from WaitForResources to " 1267 "Loaded\n"); 1268 1269 /* 1270 * from WaitForResources to Loaded considered from Loaded to Loaded. 1271 * do nothing 1272 */ 1273 1274 ret = OMX_ErrorNone; 1275 } 1276 else 1277 ret = OMX_ErrorIncorrectStateOperation; 1278 1279 return ret; 1280} 1281 1282inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current) 1283{ 1284 OMX_ERRORTYPE ret; 1285 1286 if (current == OMX_StateLoaded) { 1287 /* 1288 * Todo 1289 * 1. waits for completion of allocation on each port. 1290 * wokeup by Allocate/UseBuffer() 1291 * 2. initialize buffer process work. 1292 * 3. initialize component's internal processor. 1293 * (ex. initialize sw/hw codec) 1294 */ 1295 OMX_U32 i; 1296 1297 for (i = 0; i < nr_ports; i++) 1298 ports[i]->WaitPortBufferCompletion(); 1299 1300 ret = OMX_ErrorNone; 1301 } 1302 else if (current == OMX_StateExecuting) { 1303 /* 1304 * Todo 1305 * 1. returns all buffers to thier suppliers. 1306 * call Fill/EmptyThisBuffer() for all ports 1307 * 2. stop buffer process work 1308 * 3. stop component's internal processor 1309 */ 1310 ret = OMX_ErrorNone; 1311 } 1312 else if (current == OMX_StatePause) { 1313 1314 /* same as Executing to Idle */ 1315 1316 ret = OMX_ErrorNone; 1317 } 1318 else if (current == OMX_StateWaitForResources) { 1319 LOGE("state transition's requested from WaitForResources to Idle\n"); 1320 1321 /* same as Loaded to Idle BUT DO NOTHING for now */ 1322 1323 ret = OMX_ErrorNone; 1324 } 1325 else 1326 ret = OMX_ErrorIncorrectStateOperation; 1327 1328 return ret; 1329} 1330 1331inline OMX_ERRORTYPE 1332ComponentBase::TransStateToExecuting(OMX_STATETYPE current) 1333{ 1334 OMX_ERRORTYPE ret; 1335 1336 if (current == OMX_StateIdle) { 1337 /* 1338 * Todo 1339 * 1. start component's internal processor 1340 * 2. start processing buffers on each port 1341 */ 1342 ret = OMX_ErrorNone; 1343 } 1344 else if (current == OMX_StatePause) { 1345 /* 1346 * Todo 1347 * 1. resume buffer process woraek 1348 * 2. resume component's internal processor 1349 */ 1350 ret = OMX_ErrorNone; 1351 } 1352 else 1353 ret = OMX_ErrorIncorrectStateOperation; 1354 1355 return ret; 1356} 1357 1358inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current) 1359{ 1360 OMX_ERRORTYPE ret; 1361 1362 if (current == OMX_StateIdle) { 1363 /* 1364 * same as Idle to Executing, 1365 * except for not starting buffer processing and internal processor 1366 */ 1367 ret = OMX_ErrorNone; 1368 } 1369 else if (current == OMX_StateExecuting) { 1370 /* 1371 * Todo 1372 * 1. pause buffer process work 1373 * 2. pause component's internal processor 1374 */ 1375 ret = OMX_ErrorNone; 1376 } 1377 else 1378 ret = OMX_ErrorIncorrectStateOperation; 1379 1380 return ret; 1381} 1382 1383inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current) 1384{ 1385 OMX_ERRORTYPE ret = OMX_ErrorInvalidState; 1386 1387 /* 1388 * Todo 1389 * graceful escape 1390 */ 1391 1392 return ret; 1393} 1394 1395inline OMX_ERRORTYPE 1396ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current) 1397{ 1398 OMX_ERRORTYPE ret; 1399 1400 if (current == OMX_StateLoaded) { 1401 LOGE("state transition's requested from Loaded to WaitForResources\n"); 1402 ret = OMX_ErrorNone; 1403 } 1404 else 1405 ret = OMX_ErrorIncorrectStateOperation; 1406 1407 return ret; 1408} 1409 1410/* end of component methods & helpers */ 1411 1412/* 1413 * omx header manipuation 1414 */ 1415void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size) 1416{ 1417 OMX_U32 *nsize; 1418 OMX_VERSIONTYPE *nversion; 1419 1420 if (!type) 1421 return; 1422 1423 nsize = (OMX_U32 *)type; 1424 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 1425 1426 *nsize = size; 1427 nversion->nVersion = OMX_SPEC_VERSION; 1428} 1429 1430OMX_ERRORTYPE ComponentBase::CheckTypeHeader(OMX_PTR type, OMX_U32 size) 1431{ 1432 OMX_U32 *nsize; 1433 OMX_VERSIONTYPE *nversion; 1434 1435 if (!type) 1436 return OMX_ErrorBadParameter; 1437 1438 nsize = (OMX_U32 *)type; 1439 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 1440 1441 if (*nsize != size) 1442 return OMX_ErrorBadParameter; 1443 1444 if (nversion->nVersion != OMX_SPEC_VERSION) 1445 return OMX_ErrorVersionMismatch; 1446 1447 return OMX_ErrorNone; 1448} 1449 1450/* end of ComponentBase */ 1451