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