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