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