OpenMAXBellagio 0.9.3
omx_clocksrc_component.c
Go to the documentation of this file.
00001 
00027 #include <omxcore.h>
00028 #include <omx_base_clock_port.h>
00029 #include <omx_clocksrc_component.h>
00030 #include <config.h>
00031 #include <unistd.h>
00032 
00035 OMX_ERRORTYPE omx_clocksrc_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,OMX_STRING cComponentName) {
00036   int                                 omxErr;
00037   omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private;
00038   OMX_U32 i;
00039 
00040     RM_RegisterComponent(CLOCK_COMP_NAME, MAX_CLOCK_COMPONENTS);
00041 
00042   if (!openmaxStandComp->pComponentPrivate) {
00043     openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_clocksrc_component_PrivateType));
00044     if(openmaxStandComp->pComponentPrivate==NULL) {
00045       return OMX_ErrorInsufficientResources;
00046     }
00047   }
00048 
00049   omx_clocksrc_component_Private = openmaxStandComp->pComponentPrivate;
00050   omx_clocksrc_component_Private->ports = NULL;
00051 
00052   omxErr = omx_base_source_Constructor(openmaxStandComp,cComponentName);
00053   if (omxErr != OMX_ErrorNone) {
00054     return OMX_ErrorInsufficientResources;
00055   }
00056 
00057   omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nStartPortNumber = 0;
00058   omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts = 3;
00059 
00061   if (omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts && !omx_clocksrc_component_Private->ports) {
00062     omx_clocksrc_component_Private->ports = calloc(omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts, sizeof(omx_base_PortType *));
00063     if (!omx_clocksrc_component_Private->ports) {
00064       return OMX_ErrorInsufficientResources;
00065     }
00066     for (i=0; i < omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts; i++) {
00067       omx_clocksrc_component_Private->ports[i] = calloc(1, sizeof(omx_base_clock_PortType));
00068       if (!omx_clocksrc_component_Private->ports[i]) {
00069         return OMX_ErrorInsufficientResources;
00070       }
00071       base_clock_port_Constructor(openmaxStandComp, &omx_clocksrc_component_Private->ports[i], i, OMX_FALSE);
00072       omx_clocksrc_component_Private->ports[i]->FlushProcessingBuffers = clocksrc_port_FlushProcessingBuffers;
00073     }
00074   }
00075 
00076 
00077   /* initializing the OMX_TIME_CONFIG_CLOCKSTATETYPE */
00078   setHeader(&omx_clocksrc_component_Private->sClockState, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE));
00079   omx_clocksrc_component_Private->sClockState.eState     = OMX_TIME_ClockStateStopped;
00080   omx_clocksrc_component_Private->sClockState.nStartTime = 0;
00081   omx_clocksrc_component_Private->sClockState.nOffset    = 0;
00082   omx_clocksrc_component_Private->sClockState.nWaitMask  = 0xFF;
00083 
00084   setHeader(&omx_clocksrc_component_Private->sMinStartTime, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
00085   omx_clocksrc_component_Private->sMinStartTime.nTimestamp = 0;
00086   omx_clocksrc_component_Private->sMinStartTime.nPortIndex = 0;
00087 
00088   setHeader(&omx_clocksrc_component_Private->sConfigScale, sizeof(OMX_TIME_CONFIG_SCALETYPE));
00089   omx_clocksrc_component_Private->sConfigScale.xScale = 1<<16;  /* normal play mode */
00090 
00091   setHeader(&omx_clocksrc_component_Private->sRefClock, sizeof(OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE));
00092   omx_clocksrc_component_Private->sRefClock.eClock = OMX_TIME_RefClockNone;
00093   omx_clocksrc_component_Private->eUpdateType = OMX_TIME_UpdateMax;
00094 
00095   if(!omx_clocksrc_component_Private->clockEventSem) {
00096     omx_clocksrc_component_Private->clockEventSem = calloc(1,sizeof(tsem_t));
00097     tsem_init(omx_clocksrc_component_Private->clockEventSem, 0);
00098   }
00099 
00100   if(!omx_clocksrc_component_Private->clockEventCompleteSem) {
00101     omx_clocksrc_component_Private->clockEventCompleteSem = calloc(1,sizeof(tsem_t));
00102     tsem_init(omx_clocksrc_component_Private->clockEventCompleteSem, 0);
00103   }
00104 
00105   omx_clocksrc_component_Private->BufferMgmtCallback = omx_clocksrc_component_BufferMgmtCallback;
00106   omx_clocksrc_component_Private->destructor = omx_clocksrc_component_Destructor;
00107   omx_clocksrc_component_Private->BufferMgmtFunction = omx_clocksrc_BufferMgmtFunction;
00108 
00109   openmaxStandComp->SetParameter  = omx_clocksrc_component_SetParameter;
00110   openmaxStandComp->GetParameter  = omx_clocksrc_component_GetParameter;
00111 
00112   openmaxStandComp->SetConfig  = omx_clocksrc_component_SetConfig;
00113   openmaxStandComp->GetConfig  = omx_clocksrc_component_GetConfig;
00114   openmaxStandComp->SendCommand = omx_clocksrc_component_SendCommand;
00115 
00116   return OMX_ErrorNone;
00117 }
00118 
00121 OMX_ERRORTYPE omx_clocksrc_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp) {
00122   omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private = openmaxStandComp->pComponentPrivate;
00123   OMX_U32 i;
00124 
00125   omx_clocksrc_component_Private->sClockState.eState = OMX_TIME_ClockStateMax;
00126 
00127   /*Deinitialize and free message semaphore*/
00128   if(omx_clocksrc_component_Private->clockEventSem) {
00129     tsem_deinit(omx_clocksrc_component_Private->clockEventSem);
00130     free(omx_clocksrc_component_Private->clockEventSem);
00131     omx_clocksrc_component_Private->clockEventSem=NULL;
00132   }
00133   if(omx_clocksrc_component_Private->clockEventCompleteSem) {
00134     tsem_deinit(omx_clocksrc_component_Private->clockEventCompleteSem);
00135     free(omx_clocksrc_component_Private->clockEventCompleteSem);
00136     omx_clocksrc_component_Private->clockEventCompleteSem=NULL;
00137   }
00138 
00139   /* frees port/s */
00140   if (omx_clocksrc_component_Private->ports) {
00141     for (i=0; i < omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts; i++) {
00142       if(omx_clocksrc_component_Private->ports[i])
00143         omx_clocksrc_component_Private->ports[i]->PortDestructor(omx_clocksrc_component_Private->ports[i]);
00144     }
00145     free(omx_clocksrc_component_Private->ports);
00146     omx_clocksrc_component_Private->ports=NULL;
00147   }
00148 
00149   return omx_base_source_Destructor(openmaxStandComp);
00150 }
00151 
00152 OMX_ERRORTYPE omx_clocksrc_component_GetParameter(
00153   OMX_HANDLETYPE hComponent,
00154   OMX_INDEXTYPE nParamIndex,
00155   OMX_PTR ComponentParameterStructure)
00156 {
00157   OMX_ERRORTYPE                          err = OMX_ErrorNone;
00158   OMX_OTHER_PARAM_PORTFORMATTYPE         *pOtherPortFormat;
00159   OMX_COMPONENTTYPE                      *openmaxStandComp = (OMX_COMPONENTTYPE*)hComponent;
00160   omx_clocksrc_component_PrivateType*    omx_clocksrc_component_Private = openmaxStandComp->pComponentPrivate;
00161   omx_base_clock_PortType*               pPort; // = (omx_base_clock_PortType *) omx_clocksrc_component_Private->ports[OMX_BASE_SOURCE_OUTPUTPORT_INDEX];
00162   OMX_PARAM_COMPONENTROLETYPE     *pComponentRole;
00163 
00164   if (ComponentParameterStructure == NULL) {
00165     return OMX_ErrorBadParameter;
00166   }
00167   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Getting parameter %i\n", nParamIndex);
00168   /* Check which structure we are being fed and fill its header */
00169   switch(nParamIndex) {
00170   case OMX_IndexParamOtherInit:
00171     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) {
00172       break;
00173     }
00174     memcpy(ComponentParameterStructure, &omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther], sizeof(OMX_PORT_PARAM_TYPE));
00175     break;
00176   case OMX_IndexParamOtherPortFormat:
00177     pOtherPortFormat = (OMX_OTHER_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
00178     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE))) != OMX_ErrorNone) {
00179       break;
00180     }
00181     if (pOtherPortFormat->nPortIndex < omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts) {
00182       pPort = (omx_base_clock_PortType *) omx_clocksrc_component_Private->ports[pOtherPortFormat->nPortIndex];
00183       memcpy(pOtherPortFormat, &pPort->sOtherParam, sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE));
00184     } else {
00185       return OMX_ErrorBadPortIndex;
00186     }
00187     break;
00188   case OMX_IndexParamStandardComponentRole:
00189     pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)ComponentParameterStructure;
00190     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_COMPONENTROLETYPE))) != OMX_ErrorNone) {
00191       break;
00192     }
00193     strcpy( (char*) pComponentRole->cRole, "");
00194     break;
00195   default: /*Call the base component function*/
00196     return omx_base_component_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00197   }
00198   return err;
00199 }
00200 
00201 OMX_ERRORTYPE omx_clocksrc_component_SetParameter(
00202   OMX_HANDLETYPE hComponent,
00203   OMX_INDEXTYPE nParamIndex,
00204   OMX_PTR ComponentParameterStructure)
00205 {
00206   OMX_ERRORTYPE                         err = OMX_ErrorNone;
00207   OMX_OTHER_PARAM_PORTFORMATTYPE        *pOtherPortFormat;
00208   OMX_COMPONENTTYPE                     *openmaxStandComp = (OMX_COMPONENTTYPE*)hComponent;
00209   omx_clocksrc_component_PrivateType*   omx_clocksrc_component_Private = openmaxStandComp->pComponentPrivate;
00210   omx_base_clock_PortType*              pPort;
00211   OMX_PARAM_COMPONENTROLETYPE     *pComponentRole;
00212 
00213   if (ComponentParameterStructure == NULL) {
00214     return OMX_ErrorBadParameter;
00215   }
00216 
00217   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Setting parameter %i\n", nParamIndex);
00218   /* Check which structure we are being fed and fill its header */
00219   switch(nParamIndex) {
00220   case OMX_IndexParamOtherPortFormat:
00221     pOtherPortFormat = (OMX_OTHER_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
00222     /*Check Structure Header and verify component state*/
00223     err = omx_base_component_ParameterSanityCheck(hComponent, pOtherPortFormat->nPortIndex, pOtherPortFormat, sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE));
00224     if(err!=OMX_ErrorNone) {
00225       DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n", __func__, err);
00226       break;
00227     }
00228     if (pOtherPortFormat->nPortIndex < omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts) {
00229       pPort = (omx_base_clock_PortType *) omx_clocksrc_component_Private->ports[pOtherPortFormat->nPortIndex];
00230       memcpy(&pPort->sOtherParam,pOtherPortFormat,sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE));
00231     } else {
00232       return OMX_ErrorBadPortIndex;
00233     }
00234     break;
00235   case OMX_IndexParamStandardComponentRole:
00236     pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)ComponentParameterStructure;
00237 
00238     if (omx_clocksrc_component_Private->state != OMX_StateLoaded && omx_clocksrc_component_Private->state != OMX_StateWaitForResources) {
00239       DEBUG(DEB_LEV_ERR, "In %s Incorrect State=%x lineno=%d\n",__func__, omx_clocksrc_component_Private->state, __LINE__);
00240       return OMX_ErrorIncorrectStateOperation;
00241     }
00242 
00243     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_COMPONENTROLETYPE))) != OMX_ErrorNone) {
00244       break;
00245     }
00246 
00247     if (strcmp( (char*) pComponentRole->cRole, "")) {
00248       return OMX_ErrorBadParameter;
00249     }
00250     break;
00251   default: /*Call the base component function*/
00252     return omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00253   }
00254   return err;
00255 }
00256 
00257 OMX_ERRORTYPE omx_clocksrc_component_SendCommand(
00258   OMX_HANDLETYPE hComponent,
00259   OMX_COMMANDTYPE Cmd,
00260   OMX_U32 nParam,
00261   OMX_PTR pCmdData) {
00262   OMX_COMPONENTTYPE*                  omxComponent = (OMX_COMPONENTTYPE*)hComponent;
00263   omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private = (omx_clocksrc_component_PrivateType*)omxComponent->pComponentPrivate;
00264   OMX_U32 nMask;
00265 
00266   switch (Cmd) {
00267   case OMX_CommandPortDisable:
00268     if (nParam >= omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts && nParam != OMX_ALL) {
00269       return OMX_ErrorBadPortIndex;
00270     }
00271     if(nParam == OMX_ALL) {
00272       nMask = 0xFF;
00273     } else {
00274       nMask = 0x1 << nParam;
00275     }
00276     omx_clocksrc_component_Private->sClockState.nWaitMask &= (~nMask);
00277     DEBUG(DEB_LEV_SIMPLE_SEQ,"In %s nWaitMask =%08x Musk=%x\n",__func__,
00278       (int)omx_clocksrc_component_Private->sClockState.nWaitMask,(int)(~nMask));
00279 
00280     break;
00281   case OMX_CommandPortEnable:
00282     if (nParam >= omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts && nParam != OMX_ALL) {
00283       return OMX_ErrorBadPortIndex;
00284     }
00285     if(nParam == OMX_ALL) {
00286       nMask = 0xFF;
00287     } else {
00288       nMask = 0x1 << nParam;
00289     }
00290     omx_clocksrc_component_Private->sClockState.nWaitMask &= nMask;
00291     DEBUG(DEB_LEV_SIMPLE_SEQ,"In %s nWaitMask =%08x Musk=%x\n",__func__,
00292       (int)omx_clocksrc_component_Private->sClockState.nWaitMask,(int)nMask);
00293     break;
00294   case OMX_CommandStateSet:
00295     if ((nParam == OMX_StateLoaded) && (omx_clocksrc_component_Private->state == OMX_StateIdle)) {
00296       omx_clocksrc_component_Private->transientState = OMX_TransStateIdleToLoaded;
00297       /*Signal buffer management thread to exit*/
00298       tsem_up(omx_clocksrc_component_Private->clockEventSem);
00299     } else if ((nParam == OMX_StateExecuting) && (omx_clocksrc_component_Private->state == OMX_StatePause)) {
00300       /*Dummy signal to the clock buffer management function*/
00301       omx_clocksrc_component_Private->transientState = OMX_TransStatePauseToExecuting;
00302       tsem_up(omx_clocksrc_component_Private->clockEventSem);
00303     } else if (nParam == OMX_StateInvalid) {
00304       omx_clocksrc_component_Private->transientState = OMX_TransStateInvalid;
00305       /*Signal buffer management thread to exit*/
00306       tsem_up(omx_clocksrc_component_Private->clockEventSem);
00307     }
00308     break;
00309   default:
00310     break;
00311   }
00312 
00313   DEBUG(DEB_LEV_SIMPLE_SEQ,"In %s calling omx_base_component_SendCommand\n",__func__);
00314 
00315   return omx_base_component_SendCommand(hComponent,Cmd,nParam,pCmdData);
00316 }
00317 
00318 OMX_ERRORTYPE omx_clocksrc_component_GetConfig(
00319   OMX_HANDLETYPE hComponent,
00320   OMX_INDEXTYPE nIndex,
00321   OMX_PTR pComponentConfigStructure) {
00322 
00323   OMX_COMPONENTTYPE*                  omxComponent = (OMX_COMPONENTTYPE*)hComponent;
00324   omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private = (omx_clocksrc_component_PrivateType*)omxComponent->pComponentPrivate;
00325   OMX_TIME_CONFIG_CLOCKSTATETYPE*     clockstate;
00326   OMX_TIME_CONFIG_TIMESTAMPTYPE*      timestamp;
00327   OMX_TIME_CONFIG_SCALETYPE           *pConfigScale;
00328   OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE  *pRefClock;
00329   struct timeval                      tv;
00330   struct timezone                     zv;
00331 
00332   switch (nIndex) {
00333   case OMX_IndexConfigTimeClockState :
00334     clockstate = (OMX_TIME_CONFIG_CLOCKSTATETYPE*) pComponentConfigStructure;
00335     memcpy(clockstate, &omx_clocksrc_component_Private->sClockState, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE));
00336     break;
00337   case OMX_IndexConfigTimeCurrentWallTime :
00338     timestamp = (OMX_TIME_CONFIG_TIMESTAMPTYPE*) pComponentConfigStructure;
00339     gettimeofday(&tv,&zv);
00340     timestamp->nTimestamp =  (tv.tv_sec)*1000+tv.tv_usec;  // converting the time read from gettimeofday into microseconds
00341     DEBUG(DEB_LEV_SIMPLE_SEQ,"wall time obtained in %s =%x\n",__func__,(int)timestamp->nTimestamp);
00342     break;
00343   case OMX_IndexConfigTimeCurrentMediaTime :
00344     DEBUG(DEB_LEV_SIMPLE_SEQ," TBD  portindex to be returned is OMX_ALL, OMX_IndexConfigTimeCurrentMediaTime in %s \n",__func__);
00345     break;
00346   case OMX_IndexConfigTimeScale:
00347     pConfigScale = (OMX_TIME_CONFIG_SCALETYPE*) pComponentConfigStructure;
00348     memcpy(pConfigScale, &omx_clocksrc_component_Private->sConfigScale, sizeof(OMX_TIME_CONFIG_SCALETYPE));
00349     break;
00350   case OMX_IndexConfigTimeActiveRefClock :
00351      pRefClock = (OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE*) pComponentConfigStructure;
00352      memcpy(pRefClock,&omx_clocksrc_component_Private->sRefClock, sizeof(OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE));
00353      break;
00354   default:
00355     return OMX_ErrorBadParameter;
00356     break;
00357   }
00358   return OMX_ErrorNone;
00359 }
00360 
00361 OMX_ERRORTYPE omx_clocksrc_component_SetConfig(
00362   OMX_HANDLETYPE hComponent,
00363   OMX_INDEXTYPE nIndex,
00364   OMX_PTR pComponentConfigStructure) {
00365 
00366   OMX_COMPONENTTYPE*                  omxComponent = (OMX_COMPONENTTYPE*)hComponent;
00367   omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private = (omx_clocksrc_component_PrivateType*)omxComponent->pComponentPrivate;
00368   OMX_TIME_CONFIG_CLOCKSTATETYPE*     clockstate;
00369   OMX_TIME_CONFIG_TIMESTAMPTYPE*      sRefTimeStamp;
00370   OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE* pRefClock;
00371   OMX_U32                             portIndex;
00372   omx_base_clock_PortType             *pPort;
00373   OMX_TIME_CONFIG_SCALETYPE           *pConfigScale;
00374   OMX_U32                             nMask;
00375   OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE* sMediaTimeRequest;
00376   int                                 i;
00377   struct timeval                      tv;
00378   struct timezone                     zv;
00379   OMX_TICKS                           walltime, mediatime, mediaTimediff, wallTimediff;
00380   OMX_S32                             Scale;
00381   unsigned int                        sleeptime;
00382 
00383   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00384 
00385   switch (nIndex) {
00386   case OMX_IndexConfigTimeClockState : {
00387     clockstate = (OMX_TIME_CONFIG_CLOCKSTATETYPE*) pComponentConfigStructure;
00388     switch (clockstate->eState) {
00389       case OMX_TIME_ClockStateRunning:
00390         if(omx_clocksrc_component_Private->sClockState.eState == OMX_TIME_ClockStateRunning) {
00391           DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Received OMX_TIME_ClockStateRunning again\n",__func__);
00392         }
00393         DEBUG(DEB_LEV_SIMPLE_SEQ,"in  %s ...set to OMX_TIME_ClockStateRunning\n",__func__);
00394         memcpy(&omx_clocksrc_component_Private->sClockState, clockstate, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE));
00395         omx_clocksrc_component_Private->eUpdateType = OMX_TIME_UpdateClockStateChanged;
00396         /* update the state change in all port */
00397         for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00398           pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[i];
00399           pPort->sMediaTime.eUpdateType                      = OMX_TIME_UpdateClockStateChanged;
00400           pPort->sMediaTime.eState                           = OMX_TIME_ClockStateRunning;
00401           pPort->sMediaTime.xScale                           = omx_clocksrc_component_Private->sConfigScale.xScale;
00402         }
00403         /*Signal Buffer Management Thread*/
00404         tsem_up(omx_clocksrc_component_Private->clockEventSem);
00405         DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for Clock Running Event for all ports\n");
00406         tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem);
00407       break;
00408       case OMX_TIME_ClockStateWaitingForStartTime:
00409         if(omx_clocksrc_component_Private->sClockState.eState == OMX_TIME_ClockStateRunning) {
00410           return OMX_ErrorIncorrectStateTransition;
00411         } else if(omx_clocksrc_component_Private->sClockState.eState == OMX_TIME_ClockStateWaitingForStartTime) {
00412           return OMX_ErrorSameState;
00413         }
00414         DEBUG(DEB_LEV_SIMPLE_SEQ," in  %s ...set to OMX_TIME_ClockStateWaitingForStartTime  mask sent=%d\n",__func__,(int)clockstate->nWaitMask);
00415         memcpy(&omx_clocksrc_component_Private->sClockState, clockstate, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE));
00416       break;
00417       case OMX_TIME_ClockStateStopped:
00418         DEBUG(DEB_LEV_SIMPLE_SEQ," in  %s ...set to OMX_TIME_ClockStateStopped\n",__func__);
00419         memcpy(&omx_clocksrc_component_Private->sClockState, clockstate, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE));
00420         omx_clocksrc_component_Private->eUpdateType = OMX_TIME_UpdateClockStateChanged;
00421         /* update the state change in all port */
00422         for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00423           pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[i];
00424           pPort->sMediaTime.eUpdateType                      = OMX_TIME_UpdateClockStateChanged;
00425           pPort->sMediaTime.eState                           = OMX_TIME_ClockStateStopped;
00426           pPort->sMediaTime.xScale                           = omx_clocksrc_component_Private->sConfigScale.xScale;
00427         }
00428         /*Signal Buffer Management Thread*/
00429         tsem_up(omx_clocksrc_component_Private->clockEventSem);
00430         DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for Clock Stop Event for all ports\n");
00431         tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem);
00432       break;
00433       default:
00434       break;
00435     }
00436    }
00437     break;
00438   case OMX_IndexConfigTimeClientStartTime:
00439     sRefTimeStamp = (OMX_TIME_CONFIG_TIMESTAMPTYPE*) pComponentConfigStructure;
00440     portIndex = sRefTimeStamp->nPortIndex;
00441     if(portIndex > omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts) {
00442      return OMX_ErrorBadPortIndex;
00443     }
00444 
00445     pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[portIndex];
00446     if(!PORT_IS_ENABLED(pPort)) {
00447      DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Port is disabled \n",__func__);
00448      return OMX_ErrorBadParameter;
00449     }
00450     memcpy(&pPort->sTimeStamp, sRefTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
00451 
00452     /* update the nWaitMask to clear the flag for the client which has sent its start time */
00453     if(omx_clocksrc_component_Private->sClockState.nWaitMask) {
00454       DEBUG(DEB_LEV_SIMPLE_SEQ,"refTime set is =%x \n",(int)pPort->sTimeStamp.nTimestamp);
00455       nMask = ~(0x1 << portIndex);
00456       omx_clocksrc_component_Private->sClockState.nWaitMask = omx_clocksrc_component_Private->sClockState.nWaitMask & nMask;
00457       if(omx_clocksrc_component_Private->sMinStartTime.nTimestamp >= pPort->sTimeStamp.nTimestamp){
00458          omx_clocksrc_component_Private->sMinStartTime.nTimestamp = pPort->sTimeStamp.nTimestamp;
00459          omx_clocksrc_component_Private->sMinStartTime.nPortIndex = pPort->sTimeStamp.nPortIndex;
00460       }
00461     }
00462     if(!omx_clocksrc_component_Private->sClockState.nWaitMask &&
00463        omx_clocksrc_component_Private->sClockState.eState == OMX_TIME_ClockStateWaitingForStartTime) {
00464        omx_clocksrc_component_Private->sClockState.eState = OMX_TIME_ClockStateRunning;
00465       omx_clocksrc_component_Private->sClockState.nStartTime = omx_clocksrc_component_Private->sMinStartTime.nTimestamp;
00466       omx_clocksrc_component_Private->MediaTimeBase          = omx_clocksrc_component_Private->sMinStartTime.nTimestamp;
00467       gettimeofday(&tv,&zv);
00468       walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec);
00469       omx_clocksrc_component_Private->WallTimeBase          = walltime;
00470       DEBUG(DEB_LEV_SIMPLE_SEQ,"Mediatimebase=%llx walltimebase=%llx \n",omx_clocksrc_component_Private->MediaTimeBase,omx_clocksrc_component_Private->WallTimeBase);
00471       omx_clocksrc_component_Private->eUpdateType        = OMX_TIME_UpdateClockStateChanged;
00472       /* update the state change in all port */
00473       for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00474         pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[i];
00475         pPort->sMediaTime.eUpdateType                      = OMX_TIME_UpdateClockStateChanged;
00476         pPort->sMediaTime.eState                           = OMX_TIME_ClockStateRunning;
00477         pPort->sMediaTime.xScale                           = omx_clocksrc_component_Private->sConfigScale.xScale;
00478       }
00479       /*Signal Buffer Management Thread*/
00480       tsem_up(omx_clocksrc_component_Private->clockEventSem);
00481       DEBUG(DEB_LEV_SIMPLE_SEQ,"setting the state to running from %s \n",__func__);
00482       DEBUG(DEB_LEV_SIMPLE_SEQ,"Waiting for Clock Running Event for all ports in case OMX_IndexConfigTimeClientStartTime\n");
00483       tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem);
00484     }
00485     break;
00486 
00487   case OMX_IndexConfigTimeActiveRefClock :
00488      pRefClock = (OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE*) pComponentConfigStructure;
00489      memcpy(&omx_clocksrc_component_Private->sRefClock, pRefClock, sizeof(OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE));
00490   break;
00491 
00492   case OMX_IndexConfigTimeCurrentAudioReference:
00493     sRefTimeStamp = (OMX_TIME_CONFIG_TIMESTAMPTYPE*) pComponentConfigStructure;
00494     portIndex = sRefTimeStamp->nPortIndex;
00495     if(portIndex > omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts) {
00496      return OMX_ErrorBadPortIndex;
00497     }
00498     pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[portIndex];
00499     memcpy(&pPort->sTimeStamp, sRefTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
00500     gettimeofday(&tv,&zv);
00501     walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec);
00502     omx_clocksrc_component_Private->WallTimeBase   = walltime;
00503     omx_clocksrc_component_Private->MediaTimeBase  = sRefTimeStamp->nTimestamp; /* set the mediatime base of the received time stamp*/
00504   break;
00505 
00506   case OMX_IndexConfigTimeCurrentVideoReference:
00507     sRefTimeStamp = (OMX_TIME_CONFIG_TIMESTAMPTYPE*) pComponentConfigStructure;
00508     portIndex = sRefTimeStamp->nPortIndex;
00509     if(portIndex > omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts) {
00510       return OMX_ErrorBadPortIndex;
00511     }
00512     pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[portIndex];
00513     memcpy(&pPort->sTimeStamp, sRefTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
00514     gettimeofday(&tv,&zv);
00515     walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec);
00516     omx_clocksrc_component_Private->WallTimeBase   = walltime;
00517     omx_clocksrc_component_Private->MediaTimeBase  = sRefTimeStamp->nTimestamp; /* set the mediatime base of the received time stamp*/
00518   break;
00519 
00520   case OMX_IndexConfigTimeScale:
00521     /* update the mediatime base and walltime base using the current scale value*/
00522     Scale = omx_clocksrc_component_Private->sConfigScale.xScale >> 16;  //* the scale currently in use, right shifted as Q16 format is used for the scale
00523     gettimeofday(&tv,&zv);
00524     walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec);
00525     mediatime = omx_clocksrc_component_Private->MediaTimeBase + Scale*(walltime - omx_clocksrc_component_Private->WallTimeBase);
00526     omx_clocksrc_component_Private->WallTimeBase   = walltime; // suitable start time to be used here
00527     omx_clocksrc_component_Private->MediaTimeBase  = mediatime;  // TODO - needs to be checked
00528 
00529     /* update the new scale value */
00530     pConfigScale = (OMX_TIME_CONFIG_SCALETYPE*) pComponentConfigStructure;
00531     memcpy( &omx_clocksrc_component_Private->sConfigScale,pConfigScale, sizeof(OMX_TIME_CONFIG_SCALETYPE));
00532     omx_clocksrc_component_Private->eUpdateType = OMX_TIME_UpdateScaleChanged;
00533     /* update the scale change in all ports */
00534     for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00535       pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[i];
00536       pPort->sMediaTime.eUpdateType                      = OMX_TIME_UpdateScaleChanged;
00537       pPort->sMediaTime.eState                           = OMX_TIME_ClockStateRunning;
00538       pPort->sMediaTime.xScale                           = omx_clocksrc_component_Private->sConfigScale.xScale;
00539       pPort->sMediaTime.nMediaTimestamp                  = omx_clocksrc_component_Private->MediaTimeBase;
00540       pPort->sMediaTime.nWallTimeAtMediaTime             = omx_clocksrc_component_Private->WallTimeBase;
00541       }
00542     /*Signal Buffer Management Thread*/
00543     tsem_up(omx_clocksrc_component_Private->clockEventSem);
00544     DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for Scale Change Event for all ports\n");
00545     tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem);
00546   break;
00547 
00548   case OMX_IndexConfigTimeMediaTimeRequest:
00549     Scale = omx_clocksrc_component_Private->sConfigScale.xScale >> 16;
00550 
00551     if(omx_clocksrc_component_Private->sClockState.eState != OMX_TIME_ClockStateStopped && Scale != 0) {//TODO-  what happens if request comes in pause mode
00552 
00553       sMediaTimeRequest = (OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE*) pComponentConfigStructure;
00554       portIndex = sMediaTimeRequest->nPortIndex;
00555       pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[portIndex];
00556       memcpy(&pPort->sMediaTimeRequest, sMediaTimeRequest, sizeof(OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE));
00557 
00558       gettimeofday(&tv,&zv);
00559       walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec);
00560       mediatime = omx_clocksrc_component_Private->MediaTimeBase + Scale*(walltime - omx_clocksrc_component_Private->WallTimeBase);
00561       int thresh=2000;  // TODO - what is a good threshold to use
00562       mediaTimediff = (sMediaTimeRequest->nMediaTimestamp - (sMediaTimeRequest->nOffset*Scale)) - mediatime;
00563       DEBUG(DEB_LEV_SIMPLE_SEQ," pI=%d MTD=%lld MT=%lld RT=%lld offset=%lld, Scale=%d\n",
00564                (int)portIndex,mediaTimediff,mediatime,sMediaTimeRequest->nMediaTimestamp,sMediaTimeRequest->nOffset,(int)Scale);
00565       if((mediaTimediff<0 && Scale>0) || (mediaTimediff>0 && Scale<0)) { /* if mediatime has already elapsed then request can not be fullfilled */
00566         DEBUG(DEB_LEV_SIMPLE_SEQ," pI=%d RNF MTD<0 MB=%lld WB=%lld MT=%lld RT=%lld WT=%lld offset=%lld, Scale=%d\n",
00567                  (int)portIndex,omx_clocksrc_component_Private->MediaTimeBase,omx_clocksrc_component_Private->WallTimeBase,
00568                   mediatime,sMediaTimeRequest->nMediaTimestamp,walltime,sMediaTimeRequest->nOffset,(int)Scale);
00569         pPort->sMediaTime.eUpdateType          =  OMX_TIME_UpdateRequestFulfillment; // TODO : to be checked
00570         pPort->sMediaTime.nMediaTimestamp      = sMediaTimeRequest->nMediaTimestamp;
00571         pPort->sMediaTime.nOffset              = 0xFFFFFFFF;
00572        }else{
00573          wallTimediff  = mediaTimediff/Scale;
00574          if(mediaTimediff){
00575             if(wallTimediff>thresh) {
00576                 sleeptime = (unsigned int) (wallTimediff-thresh);
00577                 usleep(sleeptime);
00578                 wallTimediff = thresh;  // ask : can I use this as the new walltimediff
00579                 gettimeofday(&tv,&zv);
00580                 walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec);
00581                 mediatime = omx_clocksrc_component_Private->MediaTimeBase + Scale*(walltime - omx_clocksrc_component_Private->WallTimeBase);
00582             }
00583             //pPort->sMediaTime.nMediaTimestamp      = mediatime;
00584             pPort->sMediaTime.nMediaTimestamp      = sMediaTimeRequest->nMediaTimestamp;  
00585             pPort->sMediaTime.nWallTimeAtMediaTime = walltime + wallTimediff;        //??????
00586             pPort->sMediaTime.nOffset              = wallTimediff;                   //????
00587             pPort->sMediaTime.xScale               = Scale;
00588             pPort->sMediaTime.eUpdateType          = OMX_TIME_UpdateRequestFulfillment;
00589             DEBUG(DEB_LEV_SIMPLE_SEQ,"pI=%d MB=%lld WB=%lld MT=%lld RT=%lld WT=%lld \n",(int)portIndex,
00590                 omx_clocksrc_component_Private->MediaTimeBase,omx_clocksrc_component_Private->WallTimeBase, mediatime,sMediaTimeRequest->nMediaTimestamp,walltime);
00591          }
00592       }
00593       /*Signal Buffer Management Thread*/
00594       tsem_up(omx_clocksrc_component_Private->clockEventSem);
00595       DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for Scale Change Event for all ports\n");
00596       tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem);
00597     } else {
00598        DEBUG(DEB_LEV_ERR,"In %s Clock State=%x Scale=%x Line=%d \n",
00599           __func__,(int)omx_clocksrc_component_Private->sClockState.eState,(int)Scale,__LINE__);
00600     }
00601   break;
00602 
00603   default:
00604     return OMX_ErrorBadParameter;
00605     break;
00606   }
00607   return OMX_ErrorNone;
00608 }
00609 
00613 void omx_clocksrc_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE* outputbuffer) {
00614   omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private = openmaxStandComp->pComponentPrivate;
00615   omx_base_clock_PortType             *pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[outputbuffer->nOutputPortIndex];
00616 
00617   memcpy(outputbuffer->pBuffer,&pPort->sMediaTime,sizeof(OMX_TIME_MEDIATIMETYPE));
00618   outputbuffer->nFilledLen = sizeof(OMX_TIME_MEDIATIMETYPE);
00619   pPort->sMediaTime.eUpdateType = OMX_TIME_UpdateMax; /* clear the update type */
00620 
00621 }
00628 void* omx_clocksrc_BufferMgmtFunction (void* param) {
00629   OMX_COMPONENTTYPE*                  openmaxStandComp = (OMX_COMPONENTTYPE*)param;
00630   omx_base_component_PrivateType*     omx_base_component_Private=(omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00631   omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private  = (omx_clocksrc_component_PrivateType*)omx_base_component_Private;
00632   omx_base_clock_PortType             *pOutPort[MAX_CLOCK_PORTS];
00633   tsem_t*                             pOutputSem[MAX_CLOCK_PORTS];
00634   queue_t*                            pOutputQueue[MAX_CLOCK_PORTS];
00635   OMX_BUFFERHEADERTYPE*               pOutputBuffer[MAX_CLOCK_PORTS];
00636   OMX_BOOL                            isOutputBufferNeeded[MAX_CLOCK_PORTS],bPortsBeingFlushed = OMX_FALSE;
00637   int                                 i,j,outBufExchanged[MAX_CLOCK_PORTS];
00638 
00639   for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00640     pOutPort[i]             = (omx_base_clock_PortType *)omx_clocksrc_component_Private->ports[i];
00641     pOutputSem[i]           = pOutPort[i]->pBufferSem;
00642     pOutputQueue[i]         = pOutPort[i]->pBufferQueue;
00643     pOutputBuffer[i]        = NULL;
00644     isOutputBufferNeeded[i] = OMX_TRUE;
00645     outBufExchanged[i]      = 0;
00646   }
00647 
00648   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00649   while(omx_clocksrc_component_Private->state == OMX_StateIdle
00650          || omx_clocksrc_component_Private->state == OMX_StateExecuting
00651          || omx_clocksrc_component_Private->state == OMX_StatePause
00652          || omx_clocksrc_component_Private->transientState == OMX_TransStateLoadedToIdle){
00653 
00654     /*Wait till the ports are being flushed*/
00655     pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
00656     for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00657       bPortsBeingFlushed |= PORT_IS_BEING_FLUSHED(pOutPort[i]);
00658     }
00659     while(bPortsBeingFlushed) {
00660       pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);
00661       for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00662           if(isOutputBufferNeeded[i]==OMX_FALSE && PORT_IS_BEING_FLUSHED(pOutPort[i])) {
00663           pOutPort[i]->ReturnBufferFunction((omx_base_PortType*)pOutPort[i],pOutputBuffer[i]);
00664           outBufExchanged[i]--;
00665           pOutputBuffer[1]=NULL;
00666           isOutputBufferNeeded[i]=OMX_TRUE;
00667           DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning output buffer for port %i\n",i);
00668         }
00669       }
00670 
00671       tsem_up(omx_clocksrc_component_Private->flush_all_condition);
00672       tsem_down(omx_clocksrc_component_Private->flush_condition);
00673       pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
00674 
00675       bPortsBeingFlushed = OMX_FALSE;
00676       for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00677         bPortsBeingFlushed |= PORT_IS_BEING_FLUSHED(pOutPort[i]);
00678       }
00679     }
00680     pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);
00681 
00682     /*Wait for clock state event*/
00683     DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Waiting for clock event\n",__func__);
00684     tsem_down(omx_clocksrc_component_Private->clockEventSem);
00685     DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s clock event occured semval=%d \n",__func__,omx_clocksrc_component_Private->clockEventSem->semval);
00686 
00687     /*If port is not tunneled then simply return the buffer except paused state*/
00688     if(omx_clocksrc_component_Private->transientState == OMX_TransStatePauseToExecuting) {
00689       for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00690         if(!PORT_IS_TUNNELED(pOutPort[i])) {
00691 
00692           if(pOutputSem[i]->semval>0 && isOutputBufferNeeded[i]==OMX_TRUE ) {
00693             tsem_down(pOutputSem[i]);
00694             if(pOutputQueue[i]->nelem>0){
00695               outBufExchanged[i]++;
00696               isOutputBufferNeeded[i]=OMX_FALSE;
00697               pOutputBuffer[i] = dequeue(pOutputQueue[i]);
00698               if(pOutputBuffer[i] == NULL){
00699                 DEBUG(DEB_LEV_ERR, "Had NULL output buffer!!\n");
00700                 break;
00701               }
00702             }
00703           }
00704 
00705           if(isOutputBufferNeeded[i]==OMX_FALSE) {
00706             /*Output Buffer has been produced or EOS. So, return output buffer and get new buffer*/
00707             if(pOutputBuffer[i]->nFilledLen!=0) {
00708               DEBUG(DEB_LEV_ERR, "In %s Returning Output nFilledLen=%d (line=%d)\n",
00709                 __func__,(int)pOutputBuffer[i]->nFilledLen,__LINE__);
00710               pOutPort[i]->ReturnBufferFunction((omx_base_PortType*)pOutPort[i],pOutputBuffer[i]);
00711               outBufExchanged[i]--;
00712               pOutputBuffer[i]=NULL;
00713               isOutputBufferNeeded[i]=OMX_TRUE;
00714             }
00715           }
00716         }
00717       }
00718       omx_clocksrc_component_Private->transientState = OMX_TransStateMax;
00719     }
00720 
00721     if(omx_clocksrc_component_Private->state == OMX_StateLoaded  ||
00722        omx_clocksrc_component_Private->state == OMX_StateInvalid ||
00723        omx_clocksrc_component_Private->transientState == OMX_TransStateIdleToLoaded ||
00724        omx_clocksrc_component_Private->transientState == OMX_TransStateInvalid) {
00725 
00726       DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting (line %d)\n",__func__,__LINE__);
00727       break;
00728     }
00729 
00730     for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00731       if(pOutPort[i]->sMediaTime.eUpdateType == OMX_TIME_UpdateClockStateChanged ||
00732          pOutPort[i]->sMediaTime.eUpdateType == OMX_TIME_UpdateScaleChanged      ||
00733          pOutPort[i]->sMediaTime.eUpdateType == OMX_TIME_UpdateRequestFulfillment) {
00734 
00735         if((isOutputBufferNeeded[i]==OMX_TRUE && pOutputSem[i]->semval==0) &&
00736           (omx_clocksrc_component_Private->state != OMX_StateLoaded && omx_clocksrc_component_Private->state != OMX_StateInvalid)
00737           && PORT_IS_ENABLED(pOutPort[i])) {
00738           //Signalled from EmptyThisBuffer or FillThisBuffer or some where else
00739           DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next output buffer %i\n",i);
00740           tsem_down(omx_clocksrc_component_Private->bMgmtSem);
00741         }
00742         if(omx_clocksrc_component_Private->state == OMX_StateLoaded  ||
00743            omx_clocksrc_component_Private->state == OMX_StateInvalid ||
00744            omx_clocksrc_component_Private->transientState == OMX_TransStateIdleToLoaded ||
00745            omx_clocksrc_component_Private->transientState == OMX_TransStateInvalid) {
00746           DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting (line %d)\n",__func__,__LINE__);
00747           break;
00748         }
00749 
00750         if(pOutputSem[i]->semval>0 && isOutputBufferNeeded[i]==OMX_TRUE ) {
00751           tsem_down(pOutputSem[i]);
00752           if(pOutputQueue[i]->nelem>0){
00753             outBufExchanged[i]++;
00754             isOutputBufferNeeded[i]=OMX_FALSE;
00755             pOutputBuffer[i] = dequeue(pOutputQueue[i]);
00756             if(pOutputBuffer[i] == NULL){
00757               DEBUG(DEB_LEV_ERR, "Had NULL output buffer!!\n");
00758               break;
00759             }
00760           }
00761         } else {
00762           DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Output buffer not available Port %d (line=%d)\n",__func__,(int)i,__LINE__);
00763 
00764           /*Check if any dummy bMgmtSem signal and ports are flushing*/
00765           pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
00766           bPortsBeingFlushed = OMX_FALSE;
00767           for(j=0;j<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;j++) {
00768             bPortsBeingFlushed |= PORT_IS_BEING_FLUSHED(pOutPort[j]);
00769           }
00770           pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);
00771           if(bPortsBeingFlushed) {
00772             DEBUG(DEB_LEV_ERR, "In %s Ports are being flushed - breaking (line %d)\n",__func__,__LINE__);
00773             break;
00774           }
00775         }
00776         /*Process Output buffer of Port i */
00777         if(isOutputBufferNeeded[i]==OMX_FALSE) {
00778           if (omx_clocksrc_component_Private->BufferMgmtCallback) {
00779             (*(omx_clocksrc_component_Private->BufferMgmtCallback))(openmaxStandComp, pOutputBuffer[i]);
00780           } else {
00781             /*If no buffer management call back then don't produce any output buffer*/
00782             pOutputBuffer[i]->nFilledLen = 0;
00783           }
00784 
00785            /*Output Buffer has been produced or EOS. So, return output buffer and get new buffer*/
00786           if(pOutputBuffer[i]->nFilledLen!=0) {
00787             pOutPort[i]->ReturnBufferFunction((omx_base_PortType*)pOutPort[i],pOutputBuffer[i]);
00788             outBufExchanged[i]--;
00789             pOutputBuffer[i]=NULL;
00790             isOutputBufferNeeded[i]=OMX_TRUE;
00791           }
00792         }
00793       }
00794     }
00795 
00796     DEBUG(DEB_LEV_SIMPLE_SEQ, "Sent Clock Event for all ports\n");
00797     tsem_up(omx_clocksrc_component_Private->clockEventCompleteSem);
00798   }
00799   DEBUG(DEB_LEV_SIMPLE_SEQ,"Exiting Buffer Management Thread\n");
00800   return NULL;
00801 }
00802 
00807 OMX_ERRORTYPE clocksrc_port_FlushProcessingBuffers(omx_base_PortType *openmaxStandPort) {
00808   omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private;
00809   OMX_BUFFERHEADERTYPE* pBuffer;
00810   int errQue;
00811 
00812   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00813   omx_clocksrc_component_Private = (omx_clocksrc_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate;
00814 
00815   pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
00816   openmaxStandPort->bIsPortFlushed=OMX_TRUE;
00817   /*Signal the buffer management thread of port flush,if it is waiting for buffers*/
00818   if(omx_clocksrc_component_Private->bMgmtSem->semval==0) {
00819     tsem_up(omx_clocksrc_component_Private->bMgmtSem);
00820   }
00821   tsem_up(omx_clocksrc_component_Private->clockEventSem);
00822   tsem_up(omx_clocksrc_component_Private->clockEventCompleteSem);
00823 
00824   if(omx_clocksrc_component_Private->state==OMX_StatePause ) {
00825     /*Waiting at paused state*/
00826     tsem_signal(omx_clocksrc_component_Private->bStateSem);
00827   }
00828   DEBUG(DEB_LEV_FULL_SEQ, "In %s waiting for flush all condition port index =%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex);
00829   /* Wait until flush is completed */
00830   pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);
00831   tsem_down(omx_clocksrc_component_Private->flush_all_condition);
00832 
00833   tsem_reset(omx_clocksrc_component_Private->bMgmtSem);
00834   tsem_reset(omx_clocksrc_component_Private->clockEventSem);
00835 
00836   /* Flush all the buffers not under processing */
00837   while (openmaxStandPort->pBufferSem->semval > 0) {
00838     DEBUG(DEB_LEV_FULL_SEQ, "In %s TFlag=%x Flusing Port=%d,Semval=%d Qelem=%d\n",
00839     __func__,(int)openmaxStandPort->nTunnelFlags,(int)openmaxStandPort->sPortParam.nPortIndex,
00840     (int)openmaxStandPort->pBufferSem->semval,(int)openmaxStandPort->pBufferQueue->nelem);
00841 
00842     tsem_down(openmaxStandPort->pBufferSem);
00843     pBuffer = dequeue(openmaxStandPort->pBufferQueue);
00844     if (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) {
00845       DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s is returning io:%d buffer\n",
00846         __func__,omx_clocksrc_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex);
00847       if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
00848         ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
00849       } else {
00850         ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
00851       }
00852     } else if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00853         errQue = queue(openmaxStandPort->pBufferQueue,pBuffer);
00854         if (errQue) {
00855           /* /TODO the queue is full. This can be handled in a fine way with
00856            * some retrials, or other checking. For the moment this is a critical error
00857            * and simply causes the failure of this call
00858            */
00859           return OMX_ErrorInsufficientResources;
00860         }
00861     } else {
00862       (*(openmaxStandPort->BufferProcessedCallback))(
00863         openmaxStandPort->standCompContainer,
00864         omx_clocksrc_component_Private->callbackData,
00865         pBuffer);
00866     }
00867   }
00868   /*Port is tunneled and supplier and didn't received all it's buffer then wait for the buffers*/
00869   if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00870     while(openmaxStandPort->pBufferQueue->nelem!= openmaxStandPort->nNumAssignedBuffers){
00871       tsem_down(openmaxStandPort->pBufferSem);
00872       DEBUG(DEB_LEV_PARAMS, "In %s Got a buffer qelem=%d\n",__func__,openmaxStandPort->pBufferQueue->nelem);
00873     }
00874     tsem_reset(openmaxStandPort->pBufferSem);
00875   }
00876 
00877   pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
00878   openmaxStandPort->bIsPortFlushed=OMX_FALSE;
00879   pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);
00880 
00881   tsem_up(omx_clocksrc_component_Private->flush_condition);
00882 
00883   DEBUG(DEB_LEV_FULL_SEQ, "Out %s Port Index=%d bIsPortFlushed=%d Component %s\n", __func__,
00884     (int)openmaxStandPort->sPortParam.nPortIndex,(int)openmaxStandPort->bIsPortFlushed,omx_clocksrc_component_Private->name);
00885 
00886   DEBUG(DEB_LEV_PARAMS, "In %s TFlag=%x Qelem=%d BSem=%d bMgmtsem=%d component=%s\n", __func__,
00887     (int)openmaxStandPort->nTunnelFlags,
00888     (int)openmaxStandPort->pBufferQueue->nelem,
00889     (int)openmaxStandPort->pBufferSem->semval,
00890     (int)omx_clocksrc_component_Private->bMgmtSem->semval,
00891     omx_clocksrc_component_Private->name);
00892 
00893   DEBUG(DEB_LEV_FUNCTION_NAME, "Out %s Port Index=%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex);
00894 
00895   return OMX_ErrorNone;
00896 }
00897