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