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