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