componentbase.cpp revision b075b83b34ab602a1583879948042d697b43b58a
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 ProcessorPreFillBuffer(pBuffer); 1132 1133 ret = port->PushThisBuffer(pBuffer); 1134 if (ret == OMX_ErrorNone) 1135 bufferwork->ScheduleWork(this); 1136 1137 return ret; 1138} 1139 1140OMX_ERRORTYPE ComponentBase::SetCallbacks( 1141 OMX_IN OMX_HANDLETYPE hComponent, 1142 OMX_IN OMX_CALLBACKTYPE* pCallbacks, 1143 OMX_IN OMX_PTR pAppData) 1144{ 1145 ComponentBase *cbase; 1146 1147 if (!hComponent) 1148 return OMX_ErrorBadParameter; 1149 1150 cbase = static_cast<ComponentBase *> 1151 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1152 if (!cbase) 1153 return OMX_ErrorBadParameter; 1154 1155 return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData); 1156} 1157 1158OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks( 1159 OMX_IN OMX_HANDLETYPE hComponent, 1160 OMX_IN OMX_CALLBACKTYPE *pCallbacks, 1161 OMX_IN OMX_PTR pAppData) 1162{ 1163 if (hComponent != handle) 1164 return OMX_ErrorBadParameter; 1165 1166 appdata = pAppData; 1167 callbacks = pCallbacks; 1168 1169 return OMX_ErrorNone; 1170} 1171 1172OMX_ERRORTYPE ComponentBase::ComponentDeInit( 1173 OMX_IN OMX_HANDLETYPE hComponent) 1174{ 1175 ComponentBase *cbase; 1176 1177 if (!hComponent) 1178 return OMX_ErrorBadParameter; 1179 1180 cbase = static_cast<ComponentBase *> 1181 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1182 if (!cbase) 1183 return OMX_ErrorBadParameter; 1184 1185 return cbase->CBaseComponentDeInit(hComponent); 1186} 1187 1188OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit( 1189 OMX_IN OMX_HANDLETYPE hComponent) 1190{ 1191 /* 1192 * Todo 1193 */ 1194 1195 return OMX_ErrorNotImplemented; 1196} 1197 1198OMX_ERRORTYPE ComponentBase::UseEGLImage( 1199 OMX_IN OMX_HANDLETYPE hComponent, 1200 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1201 OMX_IN OMX_U32 nPortIndex, 1202 OMX_IN OMX_PTR pAppPrivate, 1203 OMX_IN void* eglImage) 1204{ 1205 ComponentBase *cbase; 1206 1207 if (!hComponent) 1208 return OMX_ErrorBadParameter; 1209 1210 cbase = static_cast<ComponentBase *> 1211 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1212 if (!cbase) 1213 return OMX_ErrorBadParameter; 1214 1215 return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex, 1216 pAppPrivate, eglImage); 1217} 1218 1219OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage( 1220 OMX_IN OMX_HANDLETYPE hComponent, 1221 OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, 1222 OMX_IN OMX_U32 nPortIndex, 1223 OMX_IN OMX_PTR pAppPrivate, 1224 OMX_IN void* eglImage) 1225{ 1226 /* 1227 * Todo 1228 */ 1229 1230 return OMX_ErrorNotImplemented; 1231} 1232 1233OMX_ERRORTYPE ComponentBase::ComponentRoleEnum( 1234 OMX_IN OMX_HANDLETYPE hComponent, 1235 OMX_OUT OMX_U8 *cRole, 1236 OMX_IN OMX_U32 nIndex) 1237{ 1238 ComponentBase *cbase; 1239 1240 if (!hComponent) 1241 return OMX_ErrorBadParameter; 1242 1243 cbase = static_cast<ComponentBase *> 1244 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1245 if (!cbase) 1246 return OMX_ErrorBadParameter; 1247 1248 return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex); 1249} 1250 1251OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum( 1252 OMX_IN OMX_HANDLETYPE hComponent, 1253 OMX_OUT OMX_U8 *cRole, 1254 OMX_IN OMX_U32 nIndex) 1255{ 1256 if (hComponent != (OMX_HANDLETYPE *)this->handle) 1257 return OMX_ErrorBadParameter; 1258 1259 if (nIndex > nr_roles) 1260 return OMX_ErrorBadParameter; 1261 1262 strncpy((char *)cRole, (const char *)roles[nIndex], 1263 OMX_MAX_STRINGNAME_SIZE); 1264 return OMX_ErrorNone; 1265} 1266 1267/* implement CmdHandlerInterface */ 1268static const char *cmd_name[OMX_CommandMarkBuffer+2] = { 1269 "OMX_CommandStateSet", 1270 "OMX_CommandFlush", 1271 "OMX_CommandPortDisable", 1272 "OMX_CommandPortEnable", 1273 "OMX_CommandMarkBuffer", 1274 "Unknown Command", 1275}; 1276 1277static inline const char *GetCmdName(OMX_COMMANDTYPE cmd) 1278{ 1279 if (cmd > OMX_CommandMarkBuffer) 1280 cmd = (OMX_COMMANDTYPE)(OMX_CommandMarkBuffer+1); 1281 1282 return cmd_name[cmd]; 1283} 1284 1285void ComponentBase::CmdHandler(struct cmd_s *cmd) 1286{ 1287 LOGV("%s:%s: handling %s command\n", 1288 GetName(), GetWorkingRole(), GetCmdName(cmd->cmd)); 1289 1290 switch (cmd->cmd) { 1291 case OMX_CommandStateSet: { 1292 OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1; 1293 1294 TransState(transition); 1295 break; 1296 } 1297 case OMX_CommandFlush: { 1298 OMX_U32 port_index = cmd->param1; 1299 pthread_mutex_lock(&ports_block); 1300 ProcessorFlush(port_index); 1301 FlushPort(port_index, 1); 1302 pthread_mutex_unlock(&ports_block); 1303 break; 1304 } 1305 case OMX_CommandPortDisable: { 1306 OMX_U32 port_index = cmd->param1; 1307 1308 TransStatePort(port_index, PortBase::OMX_PortDisabled); 1309 break; 1310 } 1311 case OMX_CommandPortEnable: { 1312 OMX_U32 port_index = cmd->param1; 1313 1314 TransStatePort(port_index, PortBase::OMX_PortEnabled); 1315 break; 1316 } 1317 case OMX_CommandMarkBuffer: { 1318 OMX_U32 port_index = (OMX_U32)cmd->param1; 1319 OMX_MARKTYPE *mark = (OMX_MARKTYPE *)cmd->cmddata; 1320 1321 PushThisMark(port_index, mark); 1322 break; 1323 } 1324 default: 1325 LOGE("%s:%s:%s: exit failure, command %d cannot be handled\n", 1326 GetName(), GetWorkingRole(), GetCmdName(cmd->cmd), cmd->cmd); 1327 break; 1328 } /* switch */ 1329 1330 LOGV("%s:%s: command %s handling done\n", 1331 GetName(), GetWorkingRole(), GetCmdName(cmd->cmd)); 1332} 1333 1334/* 1335 * SendCommand:OMX_CommandStateSet 1336 * called in CmdHandler or called in other parts of component for reporting 1337 * internal error (OMX_StateInvalid). 1338 */ 1339/* 1340 * Todo 1341 * Resource Management (OMX_StateWaitForResources) 1342 * for now, we never notify OMX_ErrorInsufficientResources, 1343 * so IL client doesn't try to set component' state OMX_StateWaitForResources 1344 */ 1345static const char *state_name[OMX_StateWaitForResources+2] = { 1346 "OMX_StateInvalid", 1347 "OMX_StateLoaded", 1348 "OMX_StateIdle", 1349 "OMX_StateExecuting", 1350 "OMX_StatePause", 1351 "OMX_StateWaitForResources", 1352 "Unknown State", 1353}; 1354 1355static inline const char *GetStateName(OMX_STATETYPE state) 1356{ 1357 if (state > OMX_StateWaitForResources) 1358 state = (OMX_STATETYPE)(OMX_StateWaitForResources+1); 1359 1360 return state_name[state]; 1361} 1362 1363void ComponentBase::TransState(OMX_STATETYPE transition) 1364{ 1365 OMX_STATETYPE current = this->state; 1366 OMX_EVENTTYPE event; 1367 OMX_U32 data1, data2; 1368 OMX_ERRORTYPE ret; 1369 1370 LOGV("%s:%s: try to transit state from %s to %s\n", 1371 GetName(), GetWorkingRole(), GetStateName(current), 1372 GetStateName(transition)); 1373 1374 /* same state */ 1375 if (current == transition) { 1376 ret = OMX_ErrorSameState; 1377 LOGE("%s:%s: exit failure, same state (%s)\n", 1378 GetName(), GetWorkingRole(), GetStateName(current)); 1379 goto notify_event; 1380 } 1381 1382 /* invalid state */ 1383 if (current == OMX_StateInvalid) { 1384 ret = OMX_ErrorInvalidState; 1385 LOGE("%s:%s: exit failure, current state is OMX_StateInvalid\n", 1386 GetName(), GetWorkingRole()); 1387 goto notify_event; 1388 } 1389 1390 if (transition == OMX_StateLoaded) 1391 ret = TransStateToLoaded(current); 1392 else if (transition == OMX_StateIdle) 1393 ret = TransStateToIdle(current); 1394 else if (transition == OMX_StateExecuting) 1395 ret = TransStateToExecuting(current); 1396 else if (transition == OMX_StatePause) 1397 ret = TransStateToPause(current); 1398 else if (transition == OMX_StateInvalid) 1399 ret = TransStateToInvalid(current); 1400 else if (transition == OMX_StateWaitForResources) 1401 ret = TransStateToWaitForResources(current); 1402 else 1403 ret = OMX_ErrorIncorrectStateTransition; 1404 1405notify_event: 1406 if (ret == OMX_ErrorNone) { 1407 event = OMX_EventCmdComplete; 1408 data1 = OMX_CommandStateSet; 1409 data2 = transition; 1410 1411 state = transition; 1412 LOGD("%s:%s: transition from %s to %s completed", 1413 GetName(), GetWorkingRole(), 1414 GetStateName(current), GetStateName(transition)); 1415 } 1416 else { 1417 event = OMX_EventError; 1418 data1 = ret; 1419 data2 = 0; 1420 1421 if (transition == OMX_StateInvalid || ret == OMX_ErrorInvalidState) { 1422 state = OMX_StateInvalid; 1423 LOGE("%s:%s: exit failure, transition from %s to %s, " 1424 "current state is %s\n", 1425 GetName(), GetWorkingRole(), GetStateName(current), 1426 GetStateName(transition), GetStateName(state)); 1427 } 1428 } 1429 1430 callbacks->EventHandler(handle, appdata, event, data1, data2, NULL); 1431 1432 /* WaitForResources workaround */ 1433 if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources) 1434 callbacks->EventHandler(handle, appdata, 1435 OMX_EventResourcesAcquired, 0, 0, NULL); 1436} 1437 1438inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current) 1439{ 1440 OMX_ERRORTYPE ret; 1441 1442 if (current == OMX_StateIdle) { 1443 OMX_U32 i; 1444 1445 for (i = 0; i < nr_ports; i++) 1446 { 1447 if (ports[i]->GetPortBufferCount() > 0) { 1448 ports[i]->WaitPortBufferCompletion(); 1449 }; 1450 }; 1451 1452 ret = ProcessorDeinit(); 1453 if (ret != OMX_ErrorNone) { 1454 LOGE("%s:%s: ProcessorDeinit() failed " 1455 "(ret : 0x%08x)\n", GetName(), GetWorkingRole(), 1456 ret); 1457 goto out; 1458 } 1459 } 1460 else if (current == OMX_StateWaitForResources) { 1461 LOGV("%s:%s: " 1462 "state transition's requested from WaitForResources to Loaded\n", 1463 GetName(), GetWorkingRole()); 1464 1465 /* 1466 * from WaitForResources to Loaded considered from Loaded to Loaded. 1467 * do nothing 1468 */ 1469 1470 ret = OMX_ErrorNone; 1471 } 1472 else 1473 ret = OMX_ErrorIncorrectStateTransition; 1474 1475out: 1476 return ret; 1477} 1478 1479inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current) 1480{ 1481 OMX_ERRORTYPE ret; 1482 1483 if (current == OMX_StateLoaded) { 1484 OMX_U32 i; 1485 1486 ret = ProcessorInit(); 1487 if (ret != OMX_ErrorNone) { 1488 LOGE("%s:%s: ProcessorInit() failed (ret : 0x%08x)\n", 1489 GetName(), GetWorkingRole(), ret); 1490 goto out; 1491 } 1492 1493 for (i = 0; i < nr_ports; i++) { 1494 if (ports[i]->IsEnabled()) 1495 ports[i]->WaitPortBufferCompletion(); 1496 } 1497 } 1498 else if ((current == OMX_StatePause) || (current == OMX_StateExecuting)) { 1499 pthread_mutex_lock(&ports_block); 1500 FlushPort(OMX_ALL, 0); 1501 pthread_mutex_unlock(&ports_block); 1502 LOGV("%s:%s: flushed all ports\n", GetName(), GetWorkingRole()); 1503 1504 bufferwork->CancelScheduledWork(this); 1505 LOGV("%s:%s: discarded all scheduled buffer process work\n", 1506 GetName(), GetWorkingRole()); 1507 1508 if (current == OMX_StatePause) { 1509 bufferwork->ResumeWork(); 1510 LOGV("%s:%s: buffer process work resumed\n", 1511 GetName(), GetWorkingRole()); 1512 } 1513 1514 bufferwork->StopWork(); 1515 LOGV("%s:%s: buffer process work stopped\n", 1516 GetName(), GetWorkingRole()); 1517 1518 ret = ProcessorStop(); 1519 if (ret != OMX_ErrorNone) { 1520 LOGE("%s:%s: ProcessorStop() failed (ret : 0x%08x)\n", 1521 GetName(), GetWorkingRole(), ret); 1522 goto out; 1523 } 1524 } 1525 else if (current == OMX_StateWaitForResources) { 1526 LOGV("%s:%s: " 1527 "state transition's requested from WaitForResources to Idle\n", 1528 GetName(), GetWorkingRole()); 1529 1530 /* same as Loaded to Idle BUT DO NOTHING for now */ 1531 1532 ret = OMX_ErrorNone; 1533 } 1534 else 1535 ret = OMX_ErrorIncorrectStateTransition; 1536 1537out: 1538 return ret; 1539} 1540 1541inline OMX_ERRORTYPE 1542ComponentBase::TransStateToExecuting(OMX_STATETYPE current) 1543{ 1544 OMX_ERRORTYPE ret; 1545 1546 if (current == OMX_StateIdle) { 1547 bufferwork->StartWork(true); 1548 LOGV("%s:%s: buffer process work started with executing state\n", 1549 GetName(), GetWorkingRole()); 1550 1551 ret = ProcessorStart(); 1552 if (ret != OMX_ErrorNone) { 1553 LOGE("%s:%s: ProcessorStart() failed (ret : 0x%08x)\n", 1554 GetName(), GetWorkingRole(), ret); 1555 goto out; 1556 } 1557 } 1558 else if (current == OMX_StatePause) { 1559 bufferwork->ResumeWork(); 1560 LOGV("%s:%s: buffer process work resumed\n", 1561 GetName(), GetWorkingRole()); 1562 1563 ret = ProcessorResume(); 1564 if (ret != OMX_ErrorNone) { 1565 LOGE("%s:%s: ProcessorResume() failed (ret : 0x%08x)\n", 1566 GetName(), GetWorkingRole(), ret); 1567 goto out; 1568 } 1569 } 1570 else 1571 ret = OMX_ErrorIncorrectStateTransition; 1572 1573out: 1574 return ret; 1575} 1576 1577inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current) 1578{ 1579 OMX_ERRORTYPE ret; 1580 1581 if (current == OMX_StateIdle) { 1582 bufferwork->StartWork(false); 1583 LOGV("%s:%s: buffer process work started with paused state\n", 1584 GetName(), GetWorkingRole()); 1585 1586 ret = ProcessorStart(); 1587 if (ret != OMX_ErrorNone) { 1588 LOGE("%s:%s: ProcessorSart() failed (ret : 0x%08x)\n", 1589 GetName(), GetWorkingRole(), ret); 1590 goto out; 1591 } 1592 } 1593 else if (current == OMX_StateExecuting) { 1594 bufferwork->PauseWork(); 1595 LOGV("%s:%s: buffer process work paused\n", 1596 GetName(), GetWorkingRole()); 1597 1598 ret = ProcessorPause(); 1599 if (ret != OMX_ErrorNone) { 1600 LOGE("%s:%s: ProcessorPause() failed (ret : 0x%08x)\n", 1601 GetName(), GetWorkingRole(), ret); 1602 goto out; 1603 } 1604 } 1605 else 1606 ret = OMX_ErrorIncorrectStateTransition; 1607 1608out: 1609 return ret; 1610} 1611 1612inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current) 1613{ 1614 OMX_ERRORTYPE ret = OMX_ErrorInvalidState; 1615 1616 /* 1617 * Todo 1618 * graceful escape 1619 */ 1620 1621 return ret; 1622} 1623 1624inline OMX_ERRORTYPE 1625ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current) 1626{ 1627 OMX_ERRORTYPE ret; 1628 1629 if (current == OMX_StateLoaded) { 1630 LOGV("%s:%s: " 1631 "state transition's requested from Loaded to WaitForResources\n", 1632 GetName(), GetWorkingRole()); 1633 ret = OMX_ErrorNone; 1634 } 1635 else 1636 ret = OMX_ErrorIncorrectStateTransition; 1637 1638 return ret; 1639} 1640 1641/* mark buffer */ 1642void ComponentBase::PushThisMark(OMX_U32 port_index, OMX_MARKTYPE *mark) 1643{ 1644 PortBase *port = NULL; 1645 OMX_EVENTTYPE event; 1646 OMX_U32 data1, data2; 1647 OMX_ERRORTYPE ret; 1648 1649 if (ports) 1650 if (port_index < nr_ports) 1651 port = ports[port_index]; 1652 1653 if (!port) { 1654 ret = OMX_ErrorBadPortIndex; 1655 goto notify_event; 1656 } 1657 1658 ret = port->PushMark(mark); 1659 if (ret != OMX_ErrorNone) { 1660 /* don't report OMX_ErrorInsufficientResources */ 1661 ret = OMX_ErrorUndefined; 1662 goto notify_event; 1663 } 1664 1665notify_event: 1666 if (ret == OMX_ErrorNone) { 1667 event = OMX_EventCmdComplete; 1668 data1 = OMX_CommandMarkBuffer; 1669 data2 = port_index; 1670 } 1671 else { 1672 event = OMX_EventError; 1673 data1 = ret; 1674 data2 = 0; 1675 } 1676 1677 callbacks->EventHandler(handle, appdata, event, data1, data2, NULL); 1678} 1679 1680void ComponentBase::FlushPort(OMX_U32 port_index, bool notify) 1681{ 1682 OMX_U32 i, from_index, to_index; 1683 1684 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 1685 return; 1686 1687 if (port_index == OMX_ALL) { 1688 from_index = 0; 1689 to_index = nr_ports - 1; 1690 } 1691 else { 1692 from_index = port_index; 1693 to_index = port_index; 1694 } 1695 1696 LOGV("%s:%s: flush ports (from index %lu to %lu)\n", 1697 GetName(), GetWorkingRole(), from_index, to_index); 1698 1699 for (i = from_index; i <= to_index; i++) { 1700 ports[i]->FlushPort(); 1701 if (notify) 1702 callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete, 1703 OMX_CommandFlush, i, NULL); 1704 } 1705 1706 LOGV("%s:%s: flush ports done\n", GetName(), GetWorkingRole()); 1707} 1708 1709extern const char *GetPortStateName(OMX_U8 state); //portbase.cpp 1710 1711void ComponentBase::TransStatePort(OMX_U32 port_index, OMX_U8 state) 1712{ 1713 OMX_EVENTTYPE event; 1714 OMX_U32 data1, data2; 1715 OMX_U32 i, from_index, to_index; 1716 OMX_ERRORTYPE ret; 1717 1718 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 1719 return; 1720 1721 if (port_index == OMX_ALL) { 1722 from_index = 0; 1723 to_index = nr_ports - 1; 1724 } 1725 else { 1726 from_index = port_index; 1727 to_index = port_index; 1728 } 1729 1730 LOGV("%s:%s: transit ports state to %s (from index %lu to %lu)\n", 1731 GetName(), GetWorkingRole(), GetPortStateName(state), 1732 from_index, to_index); 1733 1734 pthread_mutex_lock(&ports_block); 1735 for (i = from_index; i <= to_index; i++) { 1736 ret = ports[i]->TransState(state); 1737 if (ret == OMX_ErrorNone) { 1738 event = OMX_EventCmdComplete; 1739 if (state == PortBase::OMX_PortEnabled) { 1740 data1 = OMX_CommandPortEnable; 1741 ProcessorReset(); 1742 } 1743 else 1744 data1 = OMX_CommandPortDisable; 1745 data2 = i; 1746 } 1747 else { 1748 event = OMX_EventError; 1749 data1 = ret; 1750 data2 = 0; 1751 } 1752 callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete, 1753 data1, data2, NULL); 1754 } 1755 pthread_mutex_unlock(&ports_block); 1756 1757 LOGV("%s:%s: transit ports state to %s completed\n", 1758 GetName(), GetWorkingRole(), GetPortStateName(state)); 1759} 1760 1761/* set working role */ 1762OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role) 1763{ 1764 OMX_U32 i; 1765 1766 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1767 return OMX_ErrorIncorrectStateOperation; 1768 1769 if (!role) { 1770 working_role = NULL; 1771 return OMX_ErrorNone; 1772 } 1773 1774 for (i = 0; i < nr_roles; i++) { 1775 if (!strcmp((char *)&roles[i][0], role)) { 1776 working_role = (OMX_STRING)&roles[i][0]; 1777 return OMX_ErrorNone; 1778 } 1779 } 1780 1781 LOGE("%s: cannot find %s role\n", GetName(), role); 1782 return OMX_ErrorBadParameter; 1783} 1784 1785/* apply a working role for a component having multiple roles */ 1786OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void) 1787{ 1788 OMX_U32 i; 1789 OMX_ERRORTYPE ret; 1790 1791 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1792 return OMX_ErrorIncorrectStateOperation; 1793 1794 if (!working_role) 1795 return OMX_ErrorBadParameter; 1796 1797 if (!callbacks || !appdata) 1798 return OMX_ErrorBadParameter; 1799 1800 ret = AllocatePorts(); 1801 if (ret != OMX_ErrorNone) { 1802 LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret); 1803 return ret; 1804 } 1805 1806 /* now we can access ports */ 1807 for (i = 0; i < nr_ports; i++) { 1808 ports[i]->SetOwner(handle); 1809 ports[i]->SetCallbacks(handle, callbacks, appdata); 1810 } 1811 1812 LOGI("%s: set working role %s:", GetName(), GetWorkingRole()); 1813 return OMX_ErrorNone; 1814} 1815 1816OMX_ERRORTYPE ComponentBase::AllocatePorts(void) 1817{ 1818 OMX_DIRTYPE dir; 1819 bool has_input, has_output; 1820 OMX_U32 i; 1821 OMX_ERRORTYPE ret; 1822 1823 if (ports) 1824 return OMX_ErrorBadParameter; 1825 1826 ret = ComponentAllocatePorts(); 1827 if (ret != OMX_ErrorNone) { 1828 LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n", 1829 name, ret); 1830 return ret; 1831 } 1832 1833 has_input = false; 1834 has_output = false; 1835 ret = OMX_ErrorNone; 1836 for (i = 0; i < nr_ports; i++) { 1837 dir = ports[i]->GetPortDirection(); 1838 if (dir == OMX_DirInput) 1839 has_input = true; 1840 else if (dir == OMX_DirOutput) 1841 has_output = true; 1842 else { 1843 ret = OMX_ErrorUndefined; 1844 break; 1845 } 1846 } 1847 if (ret != OMX_ErrorNone) 1848 goto free_ports; 1849 1850 if ((has_input == false) && (has_output == true)) 1851 cvariant = CVARIANT_SOURCE; 1852 else if ((has_input == true) && (has_output == true)) 1853 cvariant = CVARIANT_FILTER; 1854 else if ((has_input == true) && (has_output == false)) 1855 cvariant = CVARIANT_SINK; 1856 else 1857 goto free_ports; 1858 1859 return OMX_ErrorNone; 1860 1861free_ports: 1862 LOGE("%s(): exit, unknown component variant\n", __func__); 1863 FreePorts(); 1864 return ret; 1865} 1866 1867/* called int FreeHandle() */ 1868OMX_ERRORTYPE ComponentBase::FreePorts(void) 1869{ 1870 if (ports) { 1871 OMX_U32 i, this_nr_ports = this->nr_ports; 1872 1873 for (i = 0; i < this_nr_ports; i++) { 1874 if (ports[i]) { 1875 OMX_MARKTYPE *mark; 1876 /* it should be empty before this */ 1877 while ((mark = ports[i]->PopMark())) 1878 free(mark); 1879 1880 delete ports[i]; 1881 ports[i] = NULL; 1882 } 1883 } 1884 delete []ports; 1885 ports = NULL; 1886 } 1887 1888 return OMX_ErrorNone; 1889} 1890 1891/* buffer processing */ 1892/* implement WorkableInterface */ 1893void ComponentBase::Work(void) 1894{ 1895 OMX_BUFFERHEADERTYPE **buffers[nr_ports]; 1896 OMX_BUFFERHEADERTYPE *buffers_hdr[nr_ports]; 1897 OMX_BUFFERHEADERTYPE *buffers_org[nr_ports]; 1898 buffer_retain_t retain[nr_ports]; 1899 OMX_U32 i; 1900 OMX_ERRORTYPE ret; 1901 1902 pthread_mutex_lock(&ports_block); 1903 1904 while(IsAllBufferAvailable()) 1905 { 1906 for (i = 0; i < nr_ports; i++) { 1907 buffers_hdr[i] = ports[i]->PopBuffer(); 1908 buffers[i] = &buffers_hdr[i]; 1909 buffers_org[i] = buffers_hdr[i]; 1910 retain[i] = BUFFER_RETAIN_NOT_RETAIN; 1911 } 1912 1913 if (working_role != NULL && !strncmp((char*)working_role, "video_decoder", 13)){ 1914 ret = ProcessorProcess(buffers, &retain[0], nr_ports); 1915 }else{ 1916 ret = ProcessorProcess(buffers_hdr, &retain[0], nr_ports); 1917 } 1918 1919 if (ret == OMX_ErrorNone) { 1920 PostProcessBuffers(buffers, &retain[0]); 1921 1922 for (i = 0; i < nr_ports; i++) { 1923 if(retain[i] == BUFFER_RETAIN_GETAGAIN) { 1924 ports[i]->RetainThisBuffer(*buffers[i], false); 1925 } 1926 else if (retain[i] == BUFFER_RETAIN_ACCUMULATE) { 1927 ports[i]->RetainThisBuffer(*buffers[i], true); 1928 } 1929 else if (retain[i] == BUFFER_RETAIN_OVERRIDDEN) { 1930 ports[i]->RetainAndReturnBuffer(buffers_org[i], *buffers[i]); 1931 } else { 1932 ports[i]->ReturnThisBuffer(*buffers[i]); 1933 } 1934 } 1935 } 1936 else { 1937 1938 for (i = 0; i < nr_ports; i++) { 1939 /* return buffers by hands, these buffers're not in queue */ 1940 ports[i]->ReturnThisBuffer(*buffers[i]); 1941 /* flush ports */ 1942 ports[i]->FlushPort(); 1943 } 1944 1945 callbacks->EventHandler(handle, appdata, OMX_EventError, ret, 1946 0, NULL); 1947 } 1948 } 1949 1950 pthread_mutex_unlock(&ports_block); 1951} 1952 1953bool ComponentBase::IsAllBufferAvailable(void) 1954{ 1955 OMX_U32 i; 1956 OMX_U32 nr_avail = 0; 1957 1958 for (i = 0; i < nr_ports; i++) { 1959 OMX_U32 length = 0; 1960 1961 if (ports[i]->IsEnabled()) 1962 length = ports[i]->BufferQueueLength(); 1963 1964 if (length) 1965 nr_avail++; 1966 } 1967 1968 if (nr_avail == nr_ports) 1969 return true; 1970 else 1971 return false; 1972} 1973 1974inline void ComponentBase::SourcePostProcessBuffers( 1975 OMX_BUFFERHEADERTYPE ***buffers, 1976 const buffer_retain_t *retain) 1977{ 1978 OMX_U32 i; 1979 1980 for (i = 0; i < nr_ports; i++) { 1981 /* 1982 * in case of source component, buffers're marked when they come 1983 * from the ouput ports 1984 */ 1985 if (!(*buffers[i])->hMarkTargetComponent) { 1986 OMX_MARKTYPE *mark; 1987 1988 mark = ports[i]->PopMark(); 1989 if (mark) { 1990 (*buffers[i])->hMarkTargetComponent = mark->hMarkTargetComponent; 1991 (*buffers[i])->pMarkData = mark->pMarkData; 1992 free(mark); 1993 } 1994 } 1995 } 1996} 1997 1998inline void ComponentBase::FilterPostProcessBuffers( 1999 OMX_BUFFERHEADERTYPE ***buffers, 2000 const buffer_retain_t *retain) 2001{ 2002 OMX_MARKTYPE *mark; 2003 OMX_U32 i, j; 2004 2005 for (i = 0; i < nr_ports; i++) { 2006 if (ports[i]->GetPortDirection() == OMX_DirInput) { 2007 for (j = 0; j < nr_ports; j++) { 2008 if (ports[j]->GetPortDirection() != OMX_DirOutput) 2009 continue; 2010 2011 /* propagates EOS flag */ 2012 /* clear input EOS at the end of this loop */ 2013 if (retain[i] != BUFFER_RETAIN_GETAGAIN) { 2014 if ((*buffers[i])->nFlags & OMX_BUFFERFLAG_EOS) 2015 (*buffers[j])->nFlags |= OMX_BUFFERFLAG_EOS; 2016 } 2017 2018 /* propagates marks */ 2019 /* 2020 * if hMarkTargetComponent == handle then the mark's not 2021 * propagated 2022 */ 2023 if ((*buffers[i])->hMarkTargetComponent && 2024 ((*buffers[i])->hMarkTargetComponent != handle)) { 2025 if ((*buffers[j])->hMarkTargetComponent) { 2026 mark = (OMX_MARKTYPE *)malloc(sizeof(*mark)); 2027 if (mark) { 2028 mark->hMarkTargetComponent = 2029 (*buffers[i])->hMarkTargetComponent; 2030 mark->pMarkData = (*buffers[i])->pMarkData; 2031 ports[j]->PushMark(mark); 2032 mark = NULL; 2033 (*buffers[i])->hMarkTargetComponent = NULL; 2034 (*buffers[i])->pMarkData = NULL; 2035 } 2036 } 2037 else { 2038 mark = ports[j]->PopMark(); 2039 if (mark) { 2040 (*buffers[j])->hMarkTargetComponent = 2041 mark->hMarkTargetComponent; 2042 (*buffers[j])->pMarkData = mark->pMarkData; 2043 free(mark); 2044 2045 mark = (OMX_MARKTYPE *)malloc(sizeof(*mark)); 2046 if (mark) { 2047 mark->hMarkTargetComponent = 2048 (*buffers[i])->hMarkTargetComponent; 2049 mark->pMarkData = (*buffers[i])->pMarkData; 2050 ports[j]->PushMark(mark); 2051 mark = NULL; 2052 (*buffers[i])->hMarkTargetComponent = NULL; 2053 (*buffers[i])->pMarkData = NULL; 2054 } 2055 } 2056 else { 2057 (*buffers[j])->hMarkTargetComponent = 2058 (*buffers[i])->hMarkTargetComponent; 2059 (*buffers[j])->pMarkData = (*buffers[i])->pMarkData; 2060 (*buffers[i])->hMarkTargetComponent = NULL; 2061 (*buffers[i])->pMarkData = NULL; 2062 } 2063 } 2064 } 2065 } 2066 /* clear input buffer's EOS */ 2067 if (retain[i] != BUFFER_RETAIN_GETAGAIN) 2068 (*buffers[i])->nFlags &= ~OMX_BUFFERFLAG_EOS; 2069 } 2070 } 2071} 2072 2073inline void ComponentBase::SinkPostProcessBuffers( 2074 OMX_BUFFERHEADERTYPE ***buffers, 2075 const buffer_retain_t *retain) 2076{ 2077 return; 2078} 2079 2080void ComponentBase::PostProcessBuffers(OMX_BUFFERHEADERTYPE ***buffers, 2081 const buffer_retain_t *retain) 2082{ 2083 2084 if (cvariant == CVARIANT_SOURCE) 2085 SourcePostProcessBuffers(buffers, retain); 2086 else if (cvariant == CVARIANT_FILTER) 2087 FilterPostProcessBuffers(buffers, retain); 2088 else if (cvariant == CVARIANT_SINK) { 2089 SinkPostProcessBuffers(buffers, retain); 2090 } 2091 else { 2092 LOGE("%s(): fatal error unknown component variant (%d)\n", 2093 __func__, cvariant); 2094 } 2095} 2096 2097/* processor default callbacks */ 2098OMX_ERRORTYPE ComponentBase::ProcessorInit(void) 2099{ 2100 return OMX_ErrorNone; 2101} 2102OMX_ERRORTYPE ComponentBase::ProcessorDeinit(void) 2103{ 2104 return OMX_ErrorNone; 2105} 2106 2107OMX_ERRORTYPE ComponentBase::ProcessorStart(void) 2108{ 2109 return OMX_ErrorNone; 2110} 2111 2112OMX_ERRORTYPE ComponentBase::ProcessorReset(void) 2113{ 2114 return OMX_ErrorNone; 2115} 2116 2117 2118OMX_ERRORTYPE ComponentBase::ProcessorStop(void) 2119{ 2120 return OMX_ErrorNone; 2121} 2122 2123OMX_ERRORTYPE ComponentBase::ProcessorPause(void) 2124{ 2125 return OMX_ErrorNone; 2126} 2127 2128OMX_ERRORTYPE ComponentBase::ProcessorResume(void) 2129{ 2130 return OMX_ErrorNone; 2131} 2132 2133OMX_ERRORTYPE ComponentBase::ProcessorFlush(OMX_U32 port_index) 2134{ 2135 return OMX_ErrorNone; 2136} 2137 2138OMX_ERRORTYPE ComponentBase::ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE* buffer) 2139{ 2140 return OMX_ErrorNone; 2141} 2142 2143OMX_ERRORTYPE ComponentBase::ProcessorProcess(OMX_BUFFERHEADERTYPE **pBuffers, 2144 buffer_retain_t *retain, 2145 OMX_U32 nr_buffers) 2146{ 2147 LOGE("ProcessorProcess not be implemented"); 2148 return OMX_ErrorNotImplemented; 2149} 2150OMX_ERRORTYPE ComponentBase::ProcessorProcess(OMX_BUFFERHEADERTYPE ***pBuffers, 2151 buffer_retain_t *retain, 2152 OMX_U32 nr_buffers) 2153{ 2154 LOGE("ProcessorProcess not be implemented"); 2155 return OMX_ErrorNotImplemented; 2156} 2157 2158OMX_ERRORTYPE ComponentBase::ProcessorPreFreeBuffer(OMX_U32 nPortIndex, OMX_BUFFERHEADERTYPE* pBuffer) 2159{ 2160 return OMX_ErrorNone; 2161 2162} 2163 2164/* end of processor callbacks */ 2165 2166/* helper for derived class */ 2167const OMX_STRING ComponentBase::GetWorkingRole(void) 2168{ 2169 return &working_role[0]; 2170} 2171 2172const OMX_COMPONENTTYPE *ComponentBase::GetComponentHandle(void) 2173{ 2174 return handle; 2175} 2176 2177void ComponentBase::DumpBuffer(const OMX_BUFFERHEADERTYPE *bufferheader, 2178 bool dumpdata) 2179{ 2180 OMX_U8 *pbuffer = bufferheader->pBuffer, *p; 2181 OMX_U32 offset = bufferheader->nOffset; 2182 OMX_U32 alloc_len = bufferheader->nAllocLen; 2183 OMX_U32 filled_len = bufferheader->nFilledLen; 2184 OMX_U32 left = filled_len, oneline; 2185 OMX_U32 index = 0, i; 2186 /* 0x%04lx: %02x %02x .. (n = 16)\n\0 */ 2187 char prbuffer[8 + 3 * 0x10 + 2], *pp; 2188 OMX_U32 prbuffer_len; 2189 2190 LOGD("Component %s DumpBuffer\n", name); 2191 LOGD("%s port index = %lu", 2192 (bufferheader->nInputPortIndex != 0x7fffffff) ? "input" : "output", 2193 (bufferheader->nInputPortIndex != 0x7fffffff) ? 2194 bufferheader->nInputPortIndex : bufferheader->nOutputPortIndex); 2195 LOGD("nAllocLen = %lu, nOffset = %lu, nFilledLen = %lu\n", 2196 alloc_len, offset, filled_len); 2197 LOGD("nTimeStamp = %lld, nTickCount = %lu", 2198 bufferheader->nTimeStamp, 2199 bufferheader->nTickCount); 2200 LOGD("nFlags = 0x%08lx\n", bufferheader->nFlags); 2201 LOGD("hMarkTargetComponent = %p, pMarkData = %p\n", 2202 bufferheader->hMarkTargetComponent, bufferheader->pMarkData); 2203 2204 if (!pbuffer || !alloc_len || !filled_len) 2205 return; 2206 2207 if (offset + filled_len > alloc_len) 2208 return; 2209 2210 if (!dumpdata) 2211 return; 2212 2213 p = pbuffer + offset; 2214 while (left) { 2215 oneline = left > 0x10 ? 0x10 : left; /* 16 items per 1 line */ 2216 pp += sprintf(pp, "0x%04lx: ", index); 2217 for (i = 0; i < oneline; i++) 2218 pp += sprintf(pp, " %02x", *(p + i)); 2219 pp += sprintf(pp, "\n"); 2220 *pp = '\0'; 2221 2222 index += 0x10; 2223 p += oneline; 2224 left -= oneline; 2225 2226 pp = &prbuffer[0]; 2227 LOGD("%s", pp); 2228 } 2229} 2230 2231/* end of component methods & helpers */ 2232 2233/* 2234 * omx header manipuation 2235 */ 2236void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size) 2237{ 2238 OMX_U32 *nsize; 2239 OMX_VERSIONTYPE *nversion; 2240 2241 if (!type) 2242 return; 2243 2244 nsize = (OMX_U32 *)type; 2245 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 2246 2247 *nsize = size; 2248 nversion->nVersion = OMX_SPEC_VERSION; 2249} 2250 2251OMX_ERRORTYPE ComponentBase::CheckTypeHeader(const OMX_PTR type, OMX_U32 size) 2252{ 2253 OMX_U32 *nsize; 2254 OMX_VERSIONTYPE *nversion; 2255 2256 if (!type) 2257 return OMX_ErrorBadParameter; 2258 2259 nsize = (OMX_U32 *)type; 2260 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 2261 2262 if (*nsize != size) 2263 return OMX_ErrorBadParameter; 2264 2265 if (nversion->nVersion != OMX_SPEC_VERSION) 2266 return OMX_ErrorVersionMismatch; 2267 2268 return OMX_ErrorNone; 2269} 2270 2271/* end of ComponentBase */ 2272