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