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