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