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