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