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