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