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