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