componentbase.cpp revision 35ff01df238a01bfef109b68eb68a82de8722c5f
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 749 if (!strcmp(cParameterName, "OMX.Intel.index.rotation")) { 750 *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtRotationDegrees); 751 return OMX_ErrorNone; 752 } 753 754 if (!strcmp(cParameterName, "OMX.Intel.index.enableSyncEncoding")) { 755 *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtSyncEncoding); 756 return OMX_ErrorNone; 757 } 758 759 if (!strcmp(cParameterName, "OMX.google.android.index.prependSPSPPSToIDRFrames")) { 760 *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtPrependSPSPPS); 761 return OMX_ErrorNone; 762 } 763 764#ifdef TARGET_HAS_VPP 765 if (!strcmp(cParameterName, "OMX.Intel.index.vppBufferNum")) { 766 *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtVppBufferNum); 767 return OMX_ErrorNone; 768 } 769#endif 770 771 if (!strcmp(cParameterName, "OMX.Intel.index.enableErrorReport")) { 772 *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableErrorReport); 773 return OMX_ErrorNone; 774 } 775 776 return OMX_ErrorUnsupportedIndex; 777} 778 779OMX_ERRORTYPE ComponentBase::GetState( 780 OMX_IN OMX_HANDLETYPE hComponent, 781 OMX_OUT OMX_STATETYPE* pState) 782{ 783 ComponentBase *cbase; 784 785 if (!hComponent) 786 return OMX_ErrorBadParameter; 787 788 cbase = static_cast<ComponentBase *> 789 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 790 if (!cbase) 791 return OMX_ErrorBadParameter; 792 793 return cbase->CBaseGetState(hComponent, pState); 794} 795 796OMX_ERRORTYPE ComponentBase::CBaseGetState( 797 OMX_IN OMX_HANDLETYPE hComponent, 798 OMX_OUT OMX_STATETYPE* pState) 799{ 800 if (hComponent != handle) 801 return OMX_ErrorBadParameter; 802 803 pthread_mutex_lock(&state_block); 804 *pState = state; 805 pthread_mutex_unlock(&state_block); 806 return OMX_ErrorNone; 807} 808OMX_ERRORTYPE ComponentBase::UseBuffer( 809 OMX_IN OMX_HANDLETYPE hComponent, 810 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 811 OMX_IN OMX_U32 nPortIndex, 812 OMX_IN OMX_PTR pAppPrivate, 813 OMX_IN OMX_U32 nSizeBytes, 814 OMX_IN OMX_U8 *pBuffer) 815{ 816 ComponentBase *cbase; 817 818 if (!hComponent) 819 return OMX_ErrorBadParameter; 820 821 cbase = static_cast<ComponentBase *> 822 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 823 if (!cbase) 824 return OMX_ErrorBadParameter; 825 826 return cbase->CBaseUseBuffer(hComponent, ppBufferHdr, nPortIndex, 827 pAppPrivate, nSizeBytes, pBuffer); 828} 829 830OMX_ERRORTYPE ComponentBase::CBaseUseBuffer( 831 OMX_IN OMX_HANDLETYPE hComponent, 832 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, 833 OMX_IN OMX_U32 nPortIndex, 834 OMX_IN OMX_PTR pAppPrivate, 835 OMX_IN OMX_U32 nSizeBytes, 836 OMX_IN OMX_U8 *pBuffer) 837{ 838 PortBase *port = NULL; 839 OMX_ERRORTYPE ret; 840 841 if (hComponent != handle) 842 return OMX_ErrorBadParameter; 843 844 if (!ppBufferHdr) 845 return OMX_ErrorBadParameter; 846 *ppBufferHdr = NULL; 847 848 if (!pBuffer) 849 return OMX_ErrorBadParameter; 850 851 if (ports) 852 if (nPortIndex < nr_ports) 853 port = ports[nPortIndex]; 854 855 if (!port) 856 return OMX_ErrorBadParameter; 857 858 if (port->IsEnabled()) { 859 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 860 return OMX_ErrorIncorrectStateOperation; 861 } 862 863 return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, 864 pBuffer); 865} 866 867OMX_ERRORTYPE ComponentBase::AllocateBuffer( 868 OMX_IN OMX_HANDLETYPE hComponent, 869 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 870 OMX_IN OMX_U32 nPortIndex, 871 OMX_IN OMX_PTR pAppPrivate, 872 OMX_IN OMX_U32 nSizeBytes) 873{ 874 ComponentBase *cbase; 875 876 if (!hComponent) 877 return OMX_ErrorBadParameter; 878 879 cbase = static_cast<ComponentBase *> 880 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 881 if (!cbase) 882 return OMX_ErrorBadParameter; 883 884 return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex, 885 pAppPrivate, nSizeBytes); 886} 887 888OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer( 889 OMX_IN OMX_HANDLETYPE hComponent, 890 OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, 891 OMX_IN OMX_U32 nPortIndex, 892 OMX_IN OMX_PTR pAppPrivate, 893 OMX_IN OMX_U32 nSizeBytes) 894{ 895 PortBase *port = NULL; 896 OMX_ERRORTYPE ret; 897 898 if (hComponent != handle) 899 return OMX_ErrorBadParameter; 900 901 if (!ppBuffer) 902 return OMX_ErrorBadParameter; 903 *ppBuffer = NULL; 904 905 if (ports) 906 if (nPortIndex < nr_ports) 907 port = ports[nPortIndex]; 908 909 if (!port) 910 return OMX_ErrorBadParameter; 911 912 if (port->IsEnabled()) { 913 if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) 914 return OMX_ErrorIncorrectStateOperation; 915 } 916 917 return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes); 918} 919 920OMX_ERRORTYPE ComponentBase::FreeBuffer( 921 OMX_IN OMX_HANDLETYPE hComponent, 922 OMX_IN OMX_U32 nPortIndex, 923 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 924{ 925 ComponentBase *cbase; 926 927 if (!hComponent) 928 return OMX_ErrorBadParameter; 929 930 cbase = static_cast<ComponentBase *> 931 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 932 if (!cbase) 933 return OMX_ErrorBadParameter; 934 935 return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer); 936} 937 938OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer( 939 OMX_IN OMX_HANDLETYPE hComponent, 940 OMX_IN OMX_U32 nPortIndex, 941 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 942{ 943 PortBase *port = NULL; 944 OMX_ERRORTYPE ret; 945 946 if (hComponent != handle) 947 return OMX_ErrorBadParameter; 948 949 if (!pBuffer) 950 return OMX_ErrorBadParameter; 951 952 if (ports) 953 if (nPortIndex < nr_ports) 954 port = ports[nPortIndex]; 955 956 if (!port) 957 return OMX_ErrorBadParameter; 958 959 ProcessorPreFreeBuffer(nPortIndex, pBuffer); 960 961 return port->FreeBuffer(nPortIndex, pBuffer); 962} 963 964OMX_ERRORTYPE ComponentBase::EmptyThisBuffer( 965 OMX_IN OMX_HANDLETYPE hComponent, 966 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) 967{ 968 ComponentBase *cbase; 969 970 if (!hComponent) 971 return OMX_ErrorBadParameter; 972 973 cbase = static_cast<ComponentBase *> 974 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 975 if (!cbase) 976 return OMX_ErrorBadParameter; 977 978 return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer); 979} 980 981OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer( 982 OMX_IN OMX_HANDLETYPE hComponent, 983 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 984{ 985 PortBase *port = NULL; 986 OMX_U32 port_index; 987 OMX_ERRORTYPE ret; 988 989 if ((hComponent != handle) || !pBuffer) 990 return OMX_ErrorBadParameter; 991 992 ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); 993 if (ret != OMX_ErrorNone) 994 return ret; 995 996 port_index = pBuffer->nInputPortIndex; 997 if (port_index == (OMX_U32)-1) 998 return OMX_ErrorBadParameter; 999 1000 if (ports) 1001 if (port_index < nr_ports) 1002 port = ports[port_index]; 1003 1004 if (!port) 1005 return OMX_ErrorBadParameter; 1006 1007 if (pBuffer->pInputPortPrivate != port) 1008 return OMX_ErrorBadParameter; 1009 1010 if (port->IsEnabled()) { 1011 if (state != OMX_StateIdle && state != OMX_StateExecuting && 1012 state != OMX_StatePause) 1013 return OMX_ErrorIncorrectStateOperation; 1014 } 1015 1016 if (!pBuffer->hMarkTargetComponent) { 1017 OMX_MARKTYPE *mark; 1018 1019 mark = port->PopMark(); 1020 if (mark) { 1021 pBuffer->hMarkTargetComponent = mark->hMarkTargetComponent; 1022 pBuffer->pMarkData = mark->pMarkData; 1023 free(mark); 1024 } 1025 } 1026 1027 ProcessorPreEmptyBuffer(pBuffer); 1028 1029 ret = port->PushThisBuffer(pBuffer); 1030 if (ret == OMX_ErrorNone) 1031 bufferwork->ScheduleWork(this); 1032 1033 return ret; 1034} 1035 1036OMX_ERRORTYPE ComponentBase::FillThisBuffer( 1037 OMX_IN OMX_HANDLETYPE hComponent, 1038 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 1039{ 1040 ComponentBase *cbase; 1041 1042 if (!hComponent) 1043 return OMX_ErrorBadParameter; 1044 1045 cbase = static_cast<ComponentBase *> 1046 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1047 if (!cbase) 1048 return OMX_ErrorBadParameter; 1049 1050 return cbase->CBaseFillThisBuffer(hComponent, pBuffer); 1051} 1052 1053OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer( 1054 OMX_IN OMX_HANDLETYPE hComponent, 1055 OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) 1056{ 1057 PortBase *port = NULL; 1058 OMX_U32 port_index; 1059 OMX_ERRORTYPE ret; 1060 1061 if ((hComponent != handle) || !pBuffer) 1062 return OMX_ErrorBadParameter; 1063 1064 ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); 1065 if (ret != OMX_ErrorNone) 1066 return ret; 1067 1068 port_index = pBuffer->nOutputPortIndex; 1069 if (port_index == (OMX_U32)-1) 1070 return OMX_ErrorBadParameter; 1071 1072 if (ports) 1073 if (port_index < nr_ports) 1074 port = ports[port_index]; 1075 1076 if (!port) 1077 return OMX_ErrorBadParameter; 1078 1079 if (pBuffer->pOutputPortPrivate != port) 1080 return OMX_ErrorBadParameter; 1081 1082 if (port->IsEnabled()) { 1083 if (state != OMX_StateIdle && state != OMX_StateExecuting && 1084 state != OMX_StatePause) 1085 return OMX_ErrorIncorrectStateOperation; 1086 } 1087 1088 ProcessorPreFillBuffer(pBuffer); 1089 1090 ret = port->PushThisBuffer(pBuffer); 1091 if (ret == OMX_ErrorNone) 1092 bufferwork->ScheduleWork(this); 1093 1094 return ret; 1095} 1096 1097OMX_ERRORTYPE ComponentBase::SetCallbacks( 1098 OMX_IN OMX_HANDLETYPE hComponent, 1099 OMX_IN OMX_CALLBACKTYPE* pCallbacks, 1100 OMX_IN OMX_PTR pAppData) 1101{ 1102 ComponentBase *cbase; 1103 1104 if (!hComponent) 1105 return OMX_ErrorBadParameter; 1106 1107 cbase = static_cast<ComponentBase *> 1108 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1109 if (!cbase) 1110 return OMX_ErrorBadParameter; 1111 1112 return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData); 1113} 1114 1115OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks( 1116 OMX_IN OMX_HANDLETYPE hComponent, 1117 OMX_IN OMX_CALLBACKTYPE *pCallbacks, 1118 OMX_IN OMX_PTR pAppData) 1119{ 1120 if (hComponent != handle) 1121 return OMX_ErrorBadParameter; 1122 1123 appdata = pAppData; 1124 callbacks = pCallbacks; 1125 1126 return OMX_ErrorNone; 1127} 1128 1129OMX_ERRORTYPE ComponentBase::ComponentRoleEnum( 1130 OMX_IN OMX_HANDLETYPE hComponent, 1131 OMX_OUT OMX_U8 *cRole, 1132 OMX_IN OMX_U32 nIndex) 1133{ 1134 ComponentBase *cbase; 1135 1136 if (!hComponent) 1137 return OMX_ErrorBadParameter; 1138 1139 cbase = static_cast<ComponentBase *> 1140 (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate); 1141 if (!cbase) 1142 return OMX_ErrorBadParameter; 1143 1144 return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex); 1145} 1146 1147OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum( 1148 OMX_IN OMX_HANDLETYPE hComponent, 1149 OMX_OUT OMX_U8 *cRole, 1150 OMX_IN OMX_U32 nIndex) 1151{ 1152 if (hComponent != (OMX_HANDLETYPE *)this->handle) 1153 return OMX_ErrorBadParameter; 1154 1155 if (nIndex >= nr_roles) 1156 return OMX_ErrorBadParameter; 1157 1158 strncpy((char *)cRole, (const char *)roles[nIndex], 1159 OMX_MAX_STRINGNAME_SIZE); 1160 return OMX_ErrorNone; 1161} 1162 1163/* implement CmdHandlerInterface */ 1164static const char *cmd_name[OMX_CommandMarkBuffer+2] = { 1165 "OMX_CommandStateSet", 1166 "OMX_CommandFlush", 1167 "OMX_CommandPortDisable", 1168 "OMX_CommandPortEnable", 1169 "OMX_CommandMarkBuffer", 1170 "Unknown Command", 1171}; 1172 1173static inline const char *GetCmdName(OMX_COMMANDTYPE cmd) 1174{ 1175 if (cmd > OMX_CommandMarkBuffer) 1176 cmd = (OMX_COMMANDTYPE)(OMX_CommandMarkBuffer+1); 1177 1178 return cmd_name[cmd]; 1179} 1180 1181void ComponentBase::CmdHandler(struct cmd_s *cmd) 1182{ 1183 LOGV("%s:%s: handling %s command\n", 1184 GetName(), GetWorkingRole(), GetCmdName(cmd->cmd)); 1185 1186 switch (cmd->cmd) { 1187 case OMX_CommandStateSet: { 1188 OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1; 1189 1190 pthread_mutex_lock(&state_block); 1191 TransState(transition); 1192 pthread_mutex_unlock(&state_block); 1193 break; 1194 } 1195 case OMX_CommandFlush: { 1196 OMX_U32 port_index = cmd->param1; 1197 pthread_mutex_lock(&ports_block); 1198 ProcessorFlush(port_index); 1199 FlushPort(port_index, 1); 1200 pthread_mutex_unlock(&ports_block); 1201 break; 1202 } 1203 case OMX_CommandPortDisable: { 1204 OMX_U32 port_index = cmd->param1; 1205 1206 TransStatePort(port_index, PortBase::OMX_PortDisabled); 1207 break; 1208 } 1209 case OMX_CommandPortEnable: { 1210 OMX_U32 port_index = cmd->param1; 1211 1212 TransStatePort(port_index, PortBase::OMX_PortEnabled); 1213 break; 1214 } 1215 case OMX_CommandMarkBuffer: { 1216 OMX_U32 port_index = (OMX_U32)cmd->param1; 1217 OMX_MARKTYPE *mark = (OMX_MARKTYPE *)cmd->cmddata; 1218 1219 PushThisMark(port_index, mark); 1220 break; 1221 } 1222 default: 1223 LOGE("%s:%s:%s: exit failure, command %d cannot be handled\n", 1224 GetName(), GetWorkingRole(), GetCmdName(cmd->cmd), cmd->cmd); 1225 break; 1226 } /* switch */ 1227 1228 LOGV("%s:%s: command %s handling done\n", 1229 GetName(), GetWorkingRole(), GetCmdName(cmd->cmd)); 1230} 1231 1232/* 1233 * SendCommand:OMX_CommandStateSet 1234 * called in CmdHandler or called in other parts of component for reporting 1235 * internal error (OMX_StateInvalid). 1236 */ 1237/* 1238 * Todo 1239 * Resource Management (OMX_StateWaitForResources) 1240 * for now, we never notify OMX_ErrorInsufficientResources, 1241 * so IL client doesn't try to set component' state OMX_StateWaitForResources 1242 */ 1243static const char *state_name[OMX_StateWaitForResources+2] = { 1244 "OMX_StateInvalid", 1245 "OMX_StateLoaded", 1246 "OMX_StateIdle", 1247 "OMX_StateExecuting", 1248 "OMX_StatePause", 1249 "OMX_StateWaitForResources", 1250 "Unknown State", 1251}; 1252 1253static inline const char *GetStateName(OMX_STATETYPE state) 1254{ 1255 if (state > OMX_StateWaitForResources) 1256 state = (OMX_STATETYPE)(OMX_StateWaitForResources+1); 1257 1258 return state_name[state]; 1259} 1260 1261void ComponentBase::TransState(OMX_STATETYPE transition) 1262{ 1263 OMX_STATETYPE current = this->state; 1264 OMX_EVENTTYPE event; 1265 OMX_U32 data1, data2; 1266 OMX_ERRORTYPE ret; 1267 1268 LOGV("%s:%s: try to transit state from %s to %s\n", 1269 GetName(), GetWorkingRole(), GetStateName(current), 1270 GetStateName(transition)); 1271 1272 /* same state */ 1273 if (current == transition) { 1274 ret = OMX_ErrorSameState; 1275 LOGE("%s:%s: exit failure, same state (%s)\n", 1276 GetName(), GetWorkingRole(), GetStateName(current)); 1277 goto notify_event; 1278 } 1279 1280 /* invalid state */ 1281 if (current == OMX_StateInvalid) { 1282 ret = OMX_ErrorInvalidState; 1283 LOGE("%s:%s: exit failure, current state is OMX_StateInvalid\n", 1284 GetName(), GetWorkingRole()); 1285 goto notify_event; 1286 } 1287 1288 if (transition == OMX_StateLoaded) 1289 ret = TransStateToLoaded(current); 1290 else if (transition == OMX_StateIdle) 1291 ret = TransStateToIdle(current); 1292 else if (transition == OMX_StateExecuting) 1293 ret = TransStateToExecuting(current); 1294 else if (transition == OMX_StatePause) 1295 ret = TransStateToPause(current); 1296 else if (transition == OMX_StateInvalid) 1297 ret = TransStateToInvalid(current); 1298 else if (transition == OMX_StateWaitForResources) 1299 ret = TransStateToWaitForResources(current); 1300 else 1301 ret = OMX_ErrorIncorrectStateTransition; 1302 1303notify_event: 1304 if (ret == OMX_ErrorNone) { 1305 event = OMX_EventCmdComplete; 1306 data1 = OMX_CommandStateSet; 1307 data2 = transition; 1308 1309 state = transition; 1310 LOGD("%s:%s: transition from %s to %s completed", 1311 GetName(), GetWorkingRole(), 1312 GetStateName(current), GetStateName(transition)); 1313 } 1314 else { 1315 event = OMX_EventError; 1316 data1 = ret; 1317 data2 = 0; 1318 1319 if (transition == OMX_StateInvalid || ret == OMX_ErrorInvalidState) { 1320 state = OMX_StateInvalid; 1321 LOGE("%s:%s: exit failure, transition from %s to %s, " 1322 "current state is %s\n", 1323 GetName(), GetWorkingRole(), GetStateName(current), 1324 GetStateName(transition), GetStateName(state)); 1325 } 1326 } 1327 1328 callbacks->EventHandler(handle, appdata, event, data1, data2, NULL); 1329 1330 /* WaitForResources workaround */ 1331 if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources) 1332 callbacks->EventHandler(handle, appdata, 1333 OMX_EventResourcesAcquired, 0, 0, NULL); 1334} 1335 1336inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current) 1337{ 1338 OMX_ERRORTYPE ret; 1339 1340 if (current == OMX_StateIdle) { 1341 OMX_U32 i; 1342 1343 for (i = 0; i < nr_ports; i++) 1344 { 1345 if (ports[i]->GetPortBufferCount() > 0) { 1346 ports[i]->WaitPortBufferCompletion(); 1347 }; 1348 }; 1349 1350 ret = ProcessorDeinit(); 1351 if (ret != OMX_ErrorNone) { 1352 LOGE("%s:%s: ProcessorDeinit() failed " 1353 "(ret : 0x%08x)\n", GetName(), GetWorkingRole(), 1354 ret); 1355 goto out; 1356 } 1357 } 1358 else if (current == OMX_StateWaitForResources) { 1359 LOGV("%s:%s: " 1360 "state transition's requested from WaitForResources to Loaded\n", 1361 GetName(), GetWorkingRole()); 1362 1363 /* 1364 * from WaitForResources to Loaded considered from Loaded to Loaded. 1365 * do nothing 1366 */ 1367 1368 ret = OMX_ErrorNone; 1369 } 1370 else 1371 ret = OMX_ErrorIncorrectStateTransition; 1372 1373out: 1374 return ret; 1375} 1376 1377inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current) 1378{ 1379 OMX_ERRORTYPE ret; 1380 1381 if (current == OMX_StateLoaded) { 1382 OMX_U32 i; 1383 for (i = 0; i < nr_ports; i++) { 1384 if (ports[i]->IsEnabled()) 1385 ports[i]->WaitPortBufferCompletion(); 1386 } 1387 1388 ret = ProcessorInit(); 1389 if (ret != OMX_ErrorNone) { 1390 LOGE("%s:%s: ProcessorInit() failed (ret : 0x%08x)\n", 1391 GetName(), GetWorkingRole(), ret); 1392 goto out; 1393 } 1394 } 1395 else if ((current == OMX_StatePause) || (current == OMX_StateExecuting)) { 1396 pthread_mutex_lock(&ports_block); 1397 FlushPort(OMX_ALL, 0); 1398 pthread_mutex_unlock(&ports_block); 1399 LOGV("%s:%s: flushed all ports\n", GetName(), GetWorkingRole()); 1400 1401 bufferwork->CancelScheduledWork(this); 1402 LOGV("%s:%s: discarded all scheduled buffer process work\n", 1403 GetName(), GetWorkingRole()); 1404 1405 if (current == OMX_StatePause) { 1406 bufferwork->ResumeWork(); 1407 LOGV("%s:%s: buffer process work resumed\n", 1408 GetName(), GetWorkingRole()); 1409 } 1410 1411 bufferwork->StopWork(); 1412 LOGV("%s:%s: buffer process work stopped\n", 1413 GetName(), GetWorkingRole()); 1414 1415 ret = ProcessorStop(); 1416 if (ret != OMX_ErrorNone) { 1417 LOGE("%s:%s: ProcessorStop() failed (ret : 0x%08x)\n", 1418 GetName(), GetWorkingRole(), ret); 1419 goto out; 1420 } 1421 } 1422 else if (current == OMX_StateWaitForResources) { 1423 LOGV("%s:%s: " 1424 "state transition's requested from WaitForResources to Idle\n", 1425 GetName(), GetWorkingRole()); 1426 1427 /* same as Loaded to Idle BUT DO NOTHING for now */ 1428 1429 ret = OMX_ErrorNone; 1430 } 1431 else 1432 ret = OMX_ErrorIncorrectStateTransition; 1433 1434out: 1435 return ret; 1436} 1437 1438inline OMX_ERRORTYPE 1439ComponentBase::TransStateToExecuting(OMX_STATETYPE current) 1440{ 1441 OMX_ERRORTYPE ret; 1442 1443 if (current == OMX_StateIdle) { 1444 bufferwork->StartWork(true); 1445 LOGV("%s:%s: buffer process work started with executing state\n", 1446 GetName(), GetWorkingRole()); 1447 1448 ret = ProcessorStart(); 1449 if (ret != OMX_ErrorNone) { 1450 LOGE("%s:%s: ProcessorStart() failed (ret : 0x%08x)\n", 1451 GetName(), GetWorkingRole(), ret); 1452 goto out; 1453 } 1454 } 1455 else if (current == OMX_StatePause) { 1456 bufferwork->ResumeWork(); 1457 LOGV("%s:%s: buffer process work resumed\n", 1458 GetName(), GetWorkingRole()); 1459 1460 ret = ProcessorResume(); 1461 if (ret != OMX_ErrorNone) { 1462 LOGE("%s:%s: ProcessorResume() failed (ret : 0x%08x)\n", 1463 GetName(), GetWorkingRole(), ret); 1464 goto out; 1465 } 1466 } 1467 else 1468 ret = OMX_ErrorIncorrectStateTransition; 1469 1470out: 1471 return ret; 1472} 1473 1474inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current) 1475{ 1476 OMX_ERRORTYPE ret; 1477 1478 if (current == OMX_StateIdle) { 1479 bufferwork->StartWork(false); 1480 LOGV("%s:%s: buffer process work started with paused state\n", 1481 GetName(), GetWorkingRole()); 1482 1483 ret = ProcessorStart(); 1484 if (ret != OMX_ErrorNone) { 1485 LOGE("%s:%s: ProcessorSart() failed (ret : 0x%08x)\n", 1486 GetName(), GetWorkingRole(), ret); 1487 goto out; 1488 } 1489 } 1490 else if (current == OMX_StateExecuting) { 1491 bufferwork->PauseWork(); 1492 LOGV("%s:%s: buffer process work paused\n", 1493 GetName(), GetWorkingRole()); 1494 1495 ret = ProcessorPause(); 1496 if (ret != OMX_ErrorNone) { 1497 LOGE("%s:%s: ProcessorPause() failed (ret : 0x%08x)\n", 1498 GetName(), GetWorkingRole(), ret); 1499 goto out; 1500 } 1501 } 1502 else 1503 ret = OMX_ErrorIncorrectStateTransition; 1504 1505out: 1506 return ret; 1507} 1508 1509inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current) 1510{ 1511 OMX_ERRORTYPE ret = OMX_ErrorInvalidState; 1512 1513 /* 1514 * Todo 1515 * graceful escape 1516 */ 1517 1518 return ret; 1519} 1520 1521inline OMX_ERRORTYPE 1522ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current) 1523{ 1524 OMX_ERRORTYPE ret; 1525 1526 if (current == OMX_StateLoaded) { 1527 LOGV("%s:%s: " 1528 "state transition's requested from Loaded to WaitForResources\n", 1529 GetName(), GetWorkingRole()); 1530 ret = OMX_ErrorNone; 1531 } 1532 else 1533 ret = OMX_ErrorIncorrectStateTransition; 1534 1535 return ret; 1536} 1537 1538/* mark buffer */ 1539void ComponentBase::PushThisMark(OMX_U32 port_index, OMX_MARKTYPE *mark) 1540{ 1541 PortBase *port = NULL; 1542 OMX_EVENTTYPE event; 1543 OMX_U32 data1, data2; 1544 OMX_ERRORTYPE ret; 1545 1546 if (ports) 1547 if (port_index < nr_ports) 1548 port = ports[port_index]; 1549 1550 if (!port) { 1551 ret = OMX_ErrorBadPortIndex; 1552 goto notify_event; 1553 } 1554 1555 ret = port->PushMark(mark); 1556 if (ret != OMX_ErrorNone) { 1557 /* don't report OMX_ErrorInsufficientResources */ 1558 ret = OMX_ErrorUndefined; 1559 goto notify_event; 1560 } 1561 1562notify_event: 1563 if (ret == OMX_ErrorNone) { 1564 event = OMX_EventCmdComplete; 1565 data1 = OMX_CommandMarkBuffer; 1566 data2 = port_index; 1567 } 1568 else { 1569 event = OMX_EventError; 1570 data1 = ret; 1571 data2 = 0; 1572 } 1573 1574 callbacks->EventHandler(handle, appdata, event, data1, data2, NULL); 1575} 1576 1577void ComponentBase::FlushPort(OMX_U32 port_index, bool notify) 1578{ 1579 OMX_U32 i, from_index, to_index; 1580 1581 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 1582 return; 1583 1584 if (port_index == OMX_ALL) { 1585 from_index = 0; 1586 to_index = nr_ports - 1; 1587 } 1588 else { 1589 from_index = port_index; 1590 to_index = port_index; 1591 } 1592 1593 LOGV("%s:%s: flush ports (from index %lu to %lu)\n", 1594 GetName(), GetWorkingRole(), from_index, to_index); 1595 1596 for (i = from_index; i <= to_index; i++) { 1597 ports[i]->FlushPort(); 1598 if (notify) 1599 callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete, 1600 OMX_CommandFlush, i, NULL); 1601 } 1602 1603 LOGV("%s:%s: flush ports done\n", GetName(), GetWorkingRole()); 1604} 1605 1606extern const char *GetPortStateName(OMX_U8 state); //portbase.cpp 1607 1608void ComponentBase::TransStatePort(OMX_U32 port_index, OMX_U8 state) 1609{ 1610 OMX_EVENTTYPE event; 1611 OMX_U32 data1, data2; 1612 OMX_U32 i, from_index, to_index; 1613 OMX_ERRORTYPE ret; 1614 1615 if ((port_index != OMX_ALL) && (port_index > nr_ports-1)) 1616 return; 1617 1618 if (port_index == OMX_ALL) { 1619 from_index = 0; 1620 to_index = nr_ports - 1; 1621 } 1622 else { 1623 from_index = port_index; 1624 to_index = port_index; 1625 } 1626 1627 LOGV("%s:%s: transit ports state to %s (from index %lu to %lu)\n", 1628 GetName(), GetWorkingRole(), GetPortStateName(state), 1629 from_index, to_index); 1630 1631 pthread_mutex_lock(&ports_block); 1632 for (i = from_index; i <= to_index; i++) { 1633 ret = ports[i]->TransState(state); 1634 if (ret == OMX_ErrorNone) { 1635 event = OMX_EventCmdComplete; 1636 if (state == PortBase::OMX_PortEnabled) { 1637 data1 = OMX_CommandPortEnable; 1638 ProcessorReset(); 1639 } else { 1640 data1 = OMX_CommandPortDisable; 1641 } 1642 data2 = i; 1643 } 1644 else { 1645 event = OMX_EventError; 1646 data1 = ret; 1647 data2 = 0; 1648 } 1649 callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete, 1650 data1, data2, NULL); 1651 } 1652 pthread_mutex_unlock(&ports_block); 1653 1654 LOGV("%s:%s: transit ports state to %s completed\n", 1655 GetName(), GetWorkingRole(), GetPortStateName(state)); 1656} 1657 1658/* set working role */ 1659OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role) 1660{ 1661 OMX_U32 i; 1662 1663 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1664 return OMX_ErrorIncorrectStateOperation; 1665 1666 if (!role) { 1667 working_role = NULL; 1668 return OMX_ErrorNone; 1669 } 1670 1671 for (i = 0; i < nr_roles; i++) { 1672 if (!strcmp((char *)&roles[i][0], role)) { 1673 working_role = (OMX_STRING)&roles[i][0]; 1674 return OMX_ErrorNone; 1675 } 1676 } 1677 1678 LOGE("%s: cannot find %s role\n", GetName(), role); 1679 return OMX_ErrorBadParameter; 1680} 1681 1682/* apply a working role for a component having multiple roles */ 1683OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void) 1684{ 1685 OMX_U32 i; 1686 OMX_ERRORTYPE ret; 1687 1688 if (state != OMX_StateUnloaded && state != OMX_StateLoaded) 1689 return OMX_ErrorIncorrectStateOperation; 1690 1691 if (!working_role) 1692 return OMX_ErrorBadParameter; 1693 1694 if (!callbacks || !appdata) 1695 return OMX_ErrorBadParameter; 1696 1697 ret = AllocatePorts(); 1698 if (ret != OMX_ErrorNone) { 1699 LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret); 1700 return ret; 1701 } 1702 1703 /* now we can access ports */ 1704 for (i = 0; i < nr_ports; i++) { 1705 ports[i]->SetOwner(handle); 1706 ports[i]->SetCallbacks(handle, callbacks, appdata); 1707 } 1708 1709 LOGI("%s: set working role %s:", GetName(), GetWorkingRole()); 1710 return OMX_ErrorNone; 1711} 1712 1713OMX_ERRORTYPE ComponentBase::AllocatePorts(void) 1714{ 1715 OMX_DIRTYPE dir; 1716 bool has_input, has_output; 1717 OMX_U32 i; 1718 OMX_ERRORTYPE ret; 1719 1720 if (ports) 1721 return OMX_ErrorBadParameter; 1722 1723 ret = ComponentAllocatePorts(); 1724 if (ret != OMX_ErrorNone) { 1725 LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n", 1726 name, ret); 1727 return ret; 1728 } 1729 1730 has_input = false; 1731 has_output = false; 1732 ret = OMX_ErrorNone; 1733 for (i = 0; i < nr_ports; i++) { 1734 dir = ports[i]->GetPortDirection(); 1735 if (dir == OMX_DirInput) 1736 has_input = true; 1737 else if (dir == OMX_DirOutput) 1738 has_output = true; 1739 else { 1740 ret = OMX_ErrorUndefined; 1741 break; 1742 } 1743 } 1744 if (ret != OMX_ErrorNone) 1745 goto free_ports; 1746 1747 if ((has_input == false) && (has_output == true)) 1748 cvariant = CVARIANT_SOURCE; 1749 else if ((has_input == true) && (has_output == true)) 1750 cvariant = CVARIANT_FILTER; 1751 else if ((has_input == true) && (has_output == false)) 1752 cvariant = CVARIANT_SINK; 1753 else 1754 goto free_ports; 1755 1756 return OMX_ErrorNone; 1757 1758free_ports: 1759 LOGE("%s(): exit, unknown component variant\n", __func__); 1760 FreePorts(); 1761 return OMX_ErrorUndefined; 1762} 1763 1764/* called int FreeHandle() */ 1765OMX_ERRORTYPE ComponentBase::FreePorts(void) 1766{ 1767 if (ports) { 1768 OMX_U32 i, this_nr_ports = this->nr_ports; 1769 1770 for (i = 0; i < this_nr_ports; i++) { 1771 if (ports[i]) { 1772 OMX_MARKTYPE *mark; 1773 /* it should be empty before this */ 1774 while ((mark = ports[i]->PopMark())) 1775 free(mark); 1776 1777 delete ports[i]; 1778 ports[i] = NULL; 1779 } 1780 } 1781 delete []ports; 1782 ports = NULL; 1783 } 1784 1785 return OMX_ErrorNone; 1786} 1787 1788/* buffer processing */ 1789/* implement WorkableInterface */ 1790void ComponentBase::Work(void) 1791{ 1792 OMX_BUFFERHEADERTYPE **buffers[nr_ports]; 1793 OMX_BUFFERHEADERTYPE *buffers_hdr[nr_ports]; 1794 OMX_BUFFERHEADERTYPE *buffers_org[nr_ports]; 1795 buffer_retain_t retain[nr_ports]; 1796 OMX_U32 i; 1797 OMX_ERRORTYPE ret; 1798 1799 if (nr_ports == 0) { 1800 return; 1801 } 1802 1803 pthread_mutex_lock(&ports_block); 1804 1805 while(IsAllBufferAvailable()) 1806 { 1807 for (i = 0; i < nr_ports; i++) { 1808 buffers_hdr[i] = ports[i]->PopBuffer(); 1809 buffers[i] = &buffers_hdr[i]; 1810 buffers_org[i] = buffers_hdr[i]; 1811 retain[i] = BUFFER_RETAIN_NOT_RETAIN; 1812 } 1813 1814 if (working_role != NULL && !strncmp((char*)working_role, "video_decoder", 13)){ 1815 ret = ProcessorProcess(buffers, &retain[0], nr_ports); 1816 }else{ 1817 ret = ProcessorProcess(buffers_hdr, &retain[0], nr_ports); 1818 } 1819 1820 if (ret == OMX_ErrorNone) { 1821 PostProcessBuffers(buffers, &retain[0]); 1822 1823 for (i = 0; i < nr_ports; i++) { 1824 if(retain[i] == BUFFER_RETAIN_GETAGAIN) { 1825 ports[i]->RetainThisBuffer(*buffers[i], false); 1826 } 1827 else if (retain[i] == BUFFER_RETAIN_ACCUMULATE) { 1828 ports[i]->RetainThisBuffer(*buffers[i], true); 1829 } 1830 else if (retain[i] == BUFFER_RETAIN_OVERRIDDEN) { 1831 ports[i]->RetainAndReturnBuffer(buffers_org[i], *buffers[i]); 1832 } 1833 else if (retain[i] == BUFFER_RETAIN_CACHE) { 1834 //nothing to do 1835 } else { 1836 ports[i]->ReturnThisBuffer(*buffers[i]); 1837 } 1838 } 1839 } 1840 else { 1841 1842 for (i = 0; i < nr_ports; i++) { 1843 /* return buffers by hands, these buffers're not in queue */ 1844 ports[i]->ReturnThisBuffer(*buffers[i]); 1845 /* flush ports */ 1846 ports[i]->FlushPort(); 1847 } 1848 1849 callbacks->EventHandler(handle, appdata, OMX_EventError, ret, 1850 0, NULL); 1851 } 1852 } 1853 1854 pthread_mutex_unlock(&ports_block); 1855} 1856 1857bool ComponentBase::IsAllBufferAvailable(void) 1858{ 1859 OMX_U32 i; 1860 OMX_U32 nr_avail = 0; 1861 1862 for (i = 0; i < nr_ports; i++) { 1863 OMX_U32 length = 0; 1864 1865 if (ports[i]->IsEnabled()) 1866 length = ports[i]->BufferQueueLength(); 1867 1868 if (length) 1869 nr_avail++; 1870 } 1871 1872 if (nr_avail == nr_ports) 1873 return true; 1874 else 1875 return false; 1876} 1877 1878inline void ComponentBase::SourcePostProcessBuffers( 1879 OMX_BUFFERHEADERTYPE ***buffers, 1880 const buffer_retain_t *retain) 1881{ 1882 OMX_U32 i; 1883 1884 for (i = 0; i < nr_ports; i++) { 1885 /* 1886 * in case of source component, buffers're marked when they come 1887 * from the ouput ports 1888 */ 1889 if (!(*buffers[i])->hMarkTargetComponent) { 1890 OMX_MARKTYPE *mark; 1891 1892 mark = ports[i]->PopMark(); 1893 if (mark) { 1894 (*buffers[i])->hMarkTargetComponent = mark->hMarkTargetComponent; 1895 (*buffers[i])->pMarkData = mark->pMarkData; 1896 free(mark); 1897 } 1898 } 1899 } 1900} 1901 1902inline void ComponentBase::FilterPostProcessBuffers( 1903 OMX_BUFFERHEADERTYPE ***buffers, 1904 const buffer_retain_t *retain) 1905{ 1906 OMX_MARKTYPE *mark; 1907 OMX_U32 i, j; 1908 1909 for (i = 0; i < nr_ports; i++) { 1910 if (ports[i]->GetPortDirection() == OMX_DirInput) { 1911 for (j = 0; j < nr_ports; j++) { 1912 if (ports[j]->GetPortDirection() != OMX_DirOutput) 1913 continue; 1914 1915 /* propagates EOS flag */ 1916 /* clear input EOS at the end of this loop */ 1917 if (retain[i] != BUFFER_RETAIN_GETAGAIN) { 1918 if ((*buffers[i])->nFlags & OMX_BUFFERFLAG_EOS) 1919 (*buffers[j])->nFlags |= OMX_BUFFERFLAG_EOS; 1920 } 1921 1922 /* propagates marks */ 1923 /* 1924 * if hMarkTargetComponent == handle then the mark's not 1925 * propagated 1926 */ 1927 if ((*buffers[i])->hMarkTargetComponent && 1928 ((*buffers[i])->hMarkTargetComponent != handle)) { 1929 if ((*buffers[j])->hMarkTargetComponent) { 1930 mark = (OMX_MARKTYPE *)malloc(sizeof(*mark)); 1931 if (mark) { 1932 mark->hMarkTargetComponent = 1933 (*buffers[i])->hMarkTargetComponent; 1934 mark->pMarkData = (*buffers[i])->pMarkData; 1935 ports[j]->PushMark(mark); 1936 mark = NULL; 1937 (*buffers[i])->hMarkTargetComponent = NULL; 1938 (*buffers[i])->pMarkData = NULL; 1939 } 1940 } 1941 else { 1942 mark = ports[j]->PopMark(); 1943 if (mark) { 1944 (*buffers[j])->hMarkTargetComponent = 1945 mark->hMarkTargetComponent; 1946 (*buffers[j])->pMarkData = mark->pMarkData; 1947 free(mark); 1948 1949 mark = (OMX_MARKTYPE *)malloc(sizeof(*mark)); 1950 if (mark) { 1951 mark->hMarkTargetComponent = 1952 (*buffers[i])->hMarkTargetComponent; 1953 mark->pMarkData = (*buffers[i])->pMarkData; 1954 ports[j]->PushMark(mark); 1955 mark = NULL; 1956 (*buffers[i])->hMarkTargetComponent = NULL; 1957 (*buffers[i])->pMarkData = NULL; 1958 } 1959 } 1960 else { 1961 (*buffers[j])->hMarkTargetComponent = 1962 (*buffers[i])->hMarkTargetComponent; 1963 (*buffers[j])->pMarkData = (*buffers[i])->pMarkData; 1964 (*buffers[i])->hMarkTargetComponent = NULL; 1965 (*buffers[i])->pMarkData = NULL; 1966 } 1967 } 1968 } 1969 } 1970 /* clear input buffer's EOS */ 1971 if (retain[i] != BUFFER_RETAIN_GETAGAIN) 1972 (*buffers[i])->nFlags &= ~OMX_BUFFERFLAG_EOS; 1973 } 1974 } 1975} 1976 1977inline void ComponentBase::SinkPostProcessBuffers( 1978 OMX_BUFFERHEADERTYPE ***buffers, 1979 const buffer_retain_t *retain) 1980{ 1981 return; 1982} 1983 1984void ComponentBase::PostProcessBuffers(OMX_BUFFERHEADERTYPE ***buffers, 1985 const buffer_retain_t *retain) 1986{ 1987 1988 if (cvariant == CVARIANT_SOURCE) 1989 SourcePostProcessBuffers(buffers, retain); 1990 else if (cvariant == CVARIANT_FILTER) 1991 FilterPostProcessBuffers(buffers, retain); 1992 else if (cvariant == CVARIANT_SINK) { 1993 SinkPostProcessBuffers(buffers, retain); 1994 } 1995 else { 1996 LOGE("%s(): fatal error unknown component variant (%d)\n", 1997 __func__, cvariant); 1998 } 1999} 2000 2001/* processor default callbacks */ 2002OMX_ERRORTYPE ComponentBase::ProcessorInit(void) 2003{ 2004 return OMX_ErrorNone; 2005} 2006OMX_ERRORTYPE ComponentBase::ProcessorDeinit(void) 2007{ 2008 return OMX_ErrorNone; 2009} 2010 2011OMX_ERRORTYPE ComponentBase::ProcessorStart(void) 2012{ 2013 return OMX_ErrorNone; 2014} 2015 2016OMX_ERRORTYPE ComponentBase::ProcessorReset(void) 2017{ 2018 return OMX_ErrorNone; 2019} 2020 2021 2022OMX_ERRORTYPE ComponentBase::ProcessorStop(void) 2023{ 2024 return OMX_ErrorNone; 2025} 2026 2027OMX_ERRORTYPE ComponentBase::ProcessorPause(void) 2028{ 2029 return OMX_ErrorNone; 2030} 2031 2032OMX_ERRORTYPE ComponentBase::ProcessorResume(void) 2033{ 2034 return OMX_ErrorNone; 2035} 2036 2037OMX_ERRORTYPE ComponentBase::ProcessorFlush(OMX_U32 port_index) 2038{ 2039 return OMX_ErrorNone; 2040} 2041 2042OMX_ERRORTYPE ComponentBase::ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE* buffer) 2043{ 2044 return OMX_ErrorNone; 2045} 2046 2047OMX_ERRORTYPE ComponentBase::ProcessorPreEmptyBuffer(OMX_BUFFERHEADERTYPE* buffer) 2048{ 2049 return OMX_ErrorNone; 2050} 2051 2052OMX_ERRORTYPE ComponentBase::ProcessorProcess(OMX_BUFFERHEADERTYPE **pBuffers, 2053 buffer_retain_t *retain, 2054 OMX_U32 nr_buffers) 2055{ 2056 LOGE("ProcessorProcess not be implemented"); 2057 return OMX_ErrorNotImplemented; 2058} 2059OMX_ERRORTYPE ComponentBase::ProcessorProcess(OMX_BUFFERHEADERTYPE ***pBuffers, 2060 buffer_retain_t *retain, 2061 OMX_U32 nr_buffers) 2062{ 2063 LOGE("ProcessorProcess not be implemented"); 2064 return OMX_ErrorNotImplemented; 2065} 2066 2067OMX_ERRORTYPE ComponentBase::ProcessorPreFreeBuffer(OMX_U32 nPortIndex, OMX_BUFFERHEADERTYPE* pBuffer) 2068{ 2069 return OMX_ErrorNone; 2070 2071} 2072/* end of processor callbacks */ 2073 2074/* helper for derived class */ 2075const OMX_STRING ComponentBase::GetWorkingRole(void) 2076{ 2077 return &working_role[0]; 2078} 2079 2080const OMX_COMPONENTTYPE *ComponentBase::GetComponentHandle(void) 2081{ 2082 return handle; 2083} 2084#if 0 2085void ComponentBase::DumpBuffer(const OMX_BUFFERHEADERTYPE *bufferheader, 2086 bool dumpdata) 2087{ 2088 OMX_U8 *pbuffer = bufferheader->pBuffer, *p; 2089 OMX_U32 offset = bufferheader->nOffset; 2090 OMX_U32 alloc_len = bufferheader->nAllocLen; 2091 OMX_U32 filled_len = bufferheader->nFilledLen; 2092 OMX_U32 left = filled_len, oneline; 2093 OMX_U32 index = 0, i; 2094 /* 0x%04lx: %02x %02x .. (n = 16)\n\0 */ 2095 char prbuffer[8 + 3 * 0x10 + 2], *pp; 2096 OMX_U32 prbuffer_len; 2097 2098 LOGD("Component %s DumpBuffer\n", name); 2099 LOGD("%s port index = %lu", 2100 (bufferheader->nInputPortIndex != 0x7fffffff) ? "input" : "output", 2101 (bufferheader->nInputPortIndex != 0x7fffffff) ? 2102 bufferheader->nInputPortIndex : bufferheader->nOutputPortIndex); 2103 LOGD("nAllocLen = %lu, nOffset = %lu, nFilledLen = %lu\n", 2104 alloc_len, offset, filled_len); 2105 LOGD("nTimeStamp = %lld, nTickCount = %lu", 2106 bufferheader->nTimeStamp, 2107 bufferheader->nTickCount); 2108 LOGD("nFlags = 0x%08lx\n", bufferheader->nFlags); 2109 LOGD("hMarkTargetComponent = %p, pMarkData = %p\n", 2110 bufferheader->hMarkTargetComponent, bufferheader->pMarkData); 2111 2112 if (!pbuffer || !alloc_len || !filled_len) 2113 return; 2114 2115 if (offset + filled_len > alloc_len) 2116 return; 2117 2118 if (!dumpdata) 2119 return; 2120 2121 p = pbuffer + offset; 2122 while (left) { 2123 oneline = left > 0x10 ? 0x10 : left; /* 16 items per 1 line */ 2124 pp += sprintf(pp, "0x%04lx: ", index); 2125 for (i = 0; i < oneline; i++) 2126 pp += sprintf(pp, " %02x", *(p + i)); 2127 pp += sprintf(pp, "\n"); 2128 *pp = '\0'; 2129 2130 index += 0x10; 2131 p += oneline; 2132 left -= oneline; 2133 2134 pp = &prbuffer[0]; 2135 LOGD("%s", pp); 2136 } 2137} 2138#endif 2139/* end of component methods & helpers */ 2140 2141/* 2142 * omx header manipuation 2143 */ 2144void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size) 2145{ 2146 OMX_U32 *nsize; 2147 OMX_VERSIONTYPE *nversion; 2148 2149 if (!type) 2150 return; 2151 2152 nsize = (OMX_U32 *)type; 2153 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 2154 2155 *nsize = size; 2156 nversion->nVersion = OMX_SPEC_VERSION; 2157} 2158 2159OMX_ERRORTYPE ComponentBase::CheckTypeHeader(const OMX_PTR type, OMX_U32 size) 2160{ 2161 OMX_U32 *nsize; 2162 OMX_VERSIONTYPE *nversion; 2163 2164 if (!type) 2165 return OMX_ErrorBadParameter; 2166 2167 nsize = (OMX_U32 *)type; 2168 nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32)); 2169 2170 if (*nsize != size) 2171 return OMX_ErrorBadParameter; 2172 2173 if (nversion->nVersion != OMX_SPEC_VERSION) 2174 return OMX_ErrorVersionMismatch; 2175 2176 return OMX_ErrorNone; 2177} 2178 2179/* end of ComponentBase */ 2180