omx_clocksrc_component.c

Go to the documentation of this file.
00001 
00031 #include <omxcore.h>
00032 #include <omx_base_clock_port.h>
00033 #include <omx_clocksrc_component.h>
00034 #include <config.h>
00035 #include <unistd.h>
00036 
00037 #define MAX_COMPONENT_CLOCKSRC 1
00038 
00039 #ifdef AV_SYNC_LOG
00040 static FILE *fd;
00041 #endif
00042 
00044 static OMX_U32 noClocksrcInstance=0;
00045 
00048 OMX_ERRORTYPE omx_clocksrc_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,OMX_STRING cComponentName) {
00049   int                                 omxErr;
00050   omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private;
00051   OMX_U32 i;
00052 
00053   if (!openmaxStandComp->pComponentPrivate) {
00054     openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_clocksrc_component_PrivateType));
00055     if(openmaxStandComp->pComponentPrivate==NULL) {
00056       return OMX_ErrorInsufficientResources;
00057     }
00058   }
00059 
00060   omx_clocksrc_component_Private = openmaxStandComp->pComponentPrivate;
00061   omx_clocksrc_component_Private->ports = NULL;
00062   
00063   omxErr = omx_base_source_Constructor(openmaxStandComp,cComponentName);
00064   if (omxErr != OMX_ErrorNone) {
00065     return OMX_ErrorInsufficientResources;
00066   }
00067 
00068   omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nStartPortNumber = 0;
00069   omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts = 3;
00070 
00072   if (omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts && !omx_clocksrc_component_Private->ports) {
00073     omx_clocksrc_component_Private->ports = calloc(omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts, sizeof(omx_base_PortType *));
00074     if (!omx_clocksrc_component_Private->ports) {
00075       return OMX_ErrorInsufficientResources;
00076     }
00077     for (i=0; i < omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts; i++) {
00078       omx_clocksrc_component_Private->ports[i] = calloc(1, sizeof(omx_base_clock_PortType));
00079       if (!omx_clocksrc_component_Private->ports[i]) {
00080         return OMX_ErrorInsufficientResources;
00081       }
00082       base_clock_port_Constructor(openmaxStandComp, &omx_clocksrc_component_Private->ports[i], i, OMX_FALSE);
00083       omx_clocksrc_component_Private->ports[i]->FlushProcessingBuffers = clocksrc_port_FlushProcessingBuffers;
00084     }
00085   }
00086 
00087   
00088   /* initializing the OMX_TIME_CONFIG_CLOCKSTATETYPE */
00089   setHeader(&omx_clocksrc_component_Private->sClockState, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE));  
00090   omx_clocksrc_component_Private->sClockState.eState     = OMX_TIME_ClockStateStopped;
00091   omx_clocksrc_component_Private->sClockState.nStartTime = 0;
00092   omx_clocksrc_component_Private->sClockState.nOffset    = 0;
00093   omx_clocksrc_component_Private->sClockState.nWaitMask  = 0xFF;
00094 
00095   setHeader(&omx_clocksrc_component_Private->sMinStartTime, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));  
00096   omx_clocksrc_component_Private->sMinStartTime.nTimestamp = 0;
00097   omx_clocksrc_component_Private->sMinStartTime.nPortIndex = 0;
00098 
00099   setHeader(&omx_clocksrc_component_Private->sConfigScale, sizeof(OMX_TIME_CONFIG_SCALETYPE));  
00100   omx_clocksrc_component_Private->sConfigScale.xScale = 1<<16;  /* normal play mode */
00101 
00102   setHeader(&omx_clocksrc_component_Private->sRefClock, sizeof(OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE));  
00103   omx_clocksrc_component_Private->sRefClock.eClock = OMX_TIME_RefClockNone;
00104   omx_clocksrc_component_Private->eUpdateType = OMX_TIME_UpdateMax;
00105 
00106   if(!omx_clocksrc_component_Private->clockEventSem) {
00107     omx_clocksrc_component_Private->clockEventSem = calloc(1,sizeof(tsem_t));
00108     tsem_init(omx_clocksrc_component_Private->clockEventSem, 0);
00109   }
00110 
00111   if(!omx_clocksrc_component_Private->clockEventCompleteSem) {
00112     omx_clocksrc_component_Private->clockEventCompleteSem = calloc(1,sizeof(tsem_t));
00113     tsem_init(omx_clocksrc_component_Private->clockEventCompleteSem, 0);
00114   }
00115 
00116   omx_clocksrc_component_Private->BufferMgmtCallback = omx_clocksrc_component_BufferMgmtCallback;
00117   omx_clocksrc_component_Private->destructor = omx_clocksrc_component_Destructor;
00118   omx_clocksrc_component_Private->BufferMgmtFunction = omx_clocksrc_BufferMgmtFunction;
00119 
00120 #ifdef AV_SYNC_LOG
00121  fd = fopen("clock_timestamps.out","w");
00122 #endif
00123 
00124   noClocksrcInstance++;
00125   if(noClocksrcInstance > MAX_COMPONENT_CLOCKSRC) {
00126     return OMX_ErrorInsufficientResources;
00127   }
00128   
00129   openmaxStandComp->SetParameter  = omx_clocksrc_component_SetParameter;
00130   openmaxStandComp->GetParameter  = omx_clocksrc_component_GetParameter;
00131 
00132   openmaxStandComp->SetConfig  = omx_clocksrc_component_SetConfig;
00133   openmaxStandComp->GetConfig  = omx_clocksrc_component_GetConfig;
00134   openmaxStandComp->SendCommand = omx_clocksrc_component_SendCommand;
00135 
00136   return OMX_ErrorNone;
00137 }
00138 
00141 OMX_ERRORTYPE omx_clocksrc_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp) {
00142   omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private = openmaxStandComp->pComponentPrivate;
00143   OMX_U32 i;
00144 
00145   omx_clocksrc_component_Private->sClockState.eState = OMX_TIME_ClockStateMax;
00146 
00147   /*Deinitialize and free message semaphore*/
00148   if(omx_clocksrc_component_Private->clockEventSem) {
00149     tsem_deinit(omx_clocksrc_component_Private->clockEventSem);
00150     free(omx_clocksrc_component_Private->clockEventSem);
00151     omx_clocksrc_component_Private->clockEventSem=NULL;
00152   }
00153   if(omx_clocksrc_component_Private->clockEventCompleteSem) {
00154     tsem_deinit(omx_clocksrc_component_Private->clockEventCompleteSem);
00155     free(omx_clocksrc_component_Private->clockEventCompleteSem);
00156     omx_clocksrc_component_Private->clockEventCompleteSem=NULL;
00157   }
00158   
00159   /* frees port/s */
00160   if (omx_clocksrc_component_Private->ports) {
00161     for (i=0; i < omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts; i++) {
00162       if(omx_clocksrc_component_Private->ports[i])
00163         omx_clocksrc_component_Private->ports[i]->PortDestructor(omx_clocksrc_component_Private->ports[i]);
00164     }
00165     free(omx_clocksrc_component_Private->ports);
00166     omx_clocksrc_component_Private->ports=NULL;
00167   }
00168 
00169 #ifdef AV_SYNC_LOG
00170      fclose(fd);
00171 #endif
00172   
00173   noClocksrcInstance--;
00174 
00175   return omx_base_source_Destructor(openmaxStandComp);
00176 }
00177 
00178 OMX_ERRORTYPE omx_clocksrc_component_GetParameter(
00179   OMX_IN  OMX_HANDLETYPE hComponent,
00180   OMX_IN  OMX_INDEXTYPE nParamIndex,
00181   OMX_INOUT OMX_PTR ComponentParameterStructure)
00182 {
00183   OMX_ERRORTYPE                          err = OMX_ErrorNone;
00184   OMX_OTHER_PARAM_PORTFORMATTYPE         *pOtherPortFormat;
00185   OMX_COMPONENTTYPE                      *openmaxStandComp = (OMX_COMPONENTTYPE*)hComponent;
00186   omx_clocksrc_component_PrivateType*    omx_clocksrc_component_Private = openmaxStandComp->pComponentPrivate;
00187   omx_base_clock_PortType*               pPort; // = (omx_base_clock_PortType *) omx_clocksrc_component_Private->ports[OMX_BASE_SOURCE_OUTPUTPORT_INDEX];  
00188   if (ComponentParameterStructure == NULL) {
00189     return OMX_ErrorBadParameter;
00190   }
00191   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Getting parameter %i\n", nParamIndex);
00192   /* Check which structure we are being fed and fill its header */
00193   switch(nParamIndex) {
00194   case OMX_IndexParamOtherInit:
00195     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) { 
00196       break;
00197     }
00198     memcpy(ComponentParameterStructure, &omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther], sizeof(OMX_PORT_PARAM_TYPE));
00199     break; 
00200   case OMX_IndexParamOtherPortFormat:
00201     pOtherPortFormat = (OMX_OTHER_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
00202     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE))) != OMX_ErrorNone) { 
00203       break;
00204     }
00205     if (pOtherPortFormat->nPortIndex < omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts) {
00206       pPort = (omx_base_clock_PortType *) omx_clocksrc_component_Private->ports[pOtherPortFormat->nPortIndex];  
00207       memcpy(pOtherPortFormat, &pPort->sOtherParam, sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE));
00208     } else {
00209       return OMX_ErrorBadPortIndex;
00210     }
00211     break;    
00212   default: /*Call the base component function*/
00213     return omx_base_component_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00214   }
00215   return err;
00216 }
00217 
00218 OMX_ERRORTYPE omx_clocksrc_component_SetParameter(
00219   OMX_IN  OMX_HANDLETYPE hComponent,
00220   OMX_IN  OMX_INDEXTYPE nParamIndex,
00221   OMX_INOUT OMX_PTR ComponentParameterStructure)
00222 {
00223   OMX_ERRORTYPE                         err = OMX_ErrorNone;
00224   OMX_OTHER_PARAM_PORTFORMATTYPE        *pOtherPortFormat;
00225   OMX_COMPONENTTYPE                     *openmaxStandComp = (OMX_COMPONENTTYPE*)hComponent;
00226   omx_clocksrc_component_PrivateType*   omx_clocksrc_component_Private = openmaxStandComp->pComponentPrivate;
00227   omx_base_clock_PortType*              pPort; 
00228 
00229   if (ComponentParameterStructure == NULL) {
00230     return OMX_ErrorBadParameter;
00231   }
00232 
00233   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Setting parameter %i\n", nParamIndex);
00234   /* Check which structure we are being fed and fill its header */
00235   switch(nParamIndex) {
00236   case OMX_IndexParamOtherPortFormat:
00237     pOtherPortFormat = (OMX_OTHER_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
00238     /*Check Structure Header and verify component state*/
00239     err = omx_base_component_ParameterSanityCheck(hComponent, pOtherPortFormat->nPortIndex, pOtherPortFormat, sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE));
00240     if(err!=OMX_ErrorNone) { 
00241       DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n", __func__, err); 
00242       break;
00243     } 
00244     if (pOtherPortFormat->nPortIndex < omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts) {
00245       pPort = (omx_base_clock_PortType *) omx_clocksrc_component_Private->ports[pOtherPortFormat->nPortIndex];  
00246       memcpy(&pPort->sOtherParam,pOtherPortFormat,sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE));
00247     } else {
00248       return OMX_ErrorBadPortIndex;
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_IN  OMX_HANDLETYPE hComponent,
00259   OMX_IN  OMX_COMMANDTYPE Cmd,
00260   OMX_IN  OMX_U32 nParam,
00261   OMX_IN  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_IN  OMX_HANDLETYPE hComponent,
00320   OMX_IN  OMX_INDEXTYPE nIndex,
00321   OMX_INOUT 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_IN  OMX_HANDLETYPE hComponent,
00363   OMX_IN  OMX_INDEXTYPE nIndex,
00364   OMX_IN  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_ALL_MESS," 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_ALL_MESS,"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 #ifdef AV_SYNC_LOG
00592               fprintf(fd,"%d %lld %lld %lld %lld %lld\n",
00593                   (int)portIndex,sMediaTimeRequest->nMediaTimestamp,mediatime,pPort->sMediaTime.nWallTimeAtMediaTime,wallTimediff,mediaTimediff);
00594 #endif
00595          } 
00596       }
00597       /*Signal Buffer Management Thread*/
00598       tsem_up(omx_clocksrc_component_Private->clockEventSem);
00599       DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for Scale Change Event for all ports\n");
00600       tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem);
00601     }
00602   break;
00603 
00604   default:
00605     return OMX_ErrorBadParameter;
00606     break;
00607   }
00608   return OMX_ErrorNone;
00609 }
00610 
00614 void omx_clocksrc_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE* outputbuffer) {
00615   omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private = openmaxStandComp->pComponentPrivate;
00616   omx_base_clock_PortType             *pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[outputbuffer->nOutputPortIndex];
00617 
00618   memcpy(outputbuffer->pBuffer,&pPort->sMediaTime,sizeof(OMX_TIME_MEDIATIMETYPE));
00619   outputbuffer->nFilledLen = sizeof(OMX_TIME_MEDIATIMETYPE);
00620   pPort->sMediaTime.eUpdateType = OMX_TIME_UpdateMax; /* clear the update type */
00621 
00622 }
00629 void* omx_clocksrc_BufferMgmtFunction (void* param) {
00630   OMX_COMPONENTTYPE*                  openmaxStandComp = (OMX_COMPONENTTYPE*)param;
00631   omx_base_component_PrivateType*     omx_base_component_Private=(omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00632   omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private  = (omx_clocksrc_component_PrivateType*)omx_base_component_Private;
00633   omx_base_clock_PortType             *pOutPort[MAX_CLOCK_PORTS];    
00634   tsem_t*                             pOutputSem[MAX_CLOCK_PORTS];
00635   queue_t*                            pOutputQueue[MAX_CLOCK_PORTS];
00636   OMX_BUFFERHEADERTYPE*               pOutputBuffer[MAX_CLOCK_PORTS];
00637   OMX_BOOL                            isOutputBufferNeeded[MAX_CLOCK_PORTS],bPortsBeingFlushed = OMX_FALSE;
00638   int                                 i,j,outBufExchanged[MAX_CLOCK_PORTS];
00639 
00640   for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00641     pOutPort[i]             = (omx_base_clock_PortType *)omx_clocksrc_component_Private->ports[i];
00642     pOutputSem[i]           = pOutPort[i]->pBufferSem;
00643     pOutputQueue[i]         = pOutPort[i]->pBufferQueue;
00644     pOutputBuffer[i]        = NULL;
00645     isOutputBufferNeeded[i] = OMX_TRUE;
00646     outBufExchanged[i]      = 0;
00647   }
00648 
00649   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00650   while(omx_clocksrc_component_Private->state == OMX_StateIdle 
00651          || omx_clocksrc_component_Private->state == OMX_StateExecuting 
00652          || omx_clocksrc_component_Private->state == OMX_StatePause 
00653          || omx_clocksrc_component_Private->transientState == OMX_TransStateLoadedToIdle){
00654 
00655     /*Wait till the ports are being flushed*/
00656     pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
00657     for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00658       bPortsBeingFlushed |= PORT_IS_BEING_FLUSHED(pOutPort[i]);
00659     }
00660     while(bPortsBeingFlushed) {
00661       pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);
00662       for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00663           if(isOutputBufferNeeded[i]==OMX_FALSE && PORT_IS_BEING_FLUSHED(pOutPort[i])) {
00664           pOutPort[i]->ReturnBufferFunction((omx_base_PortType*)pOutPort[i],pOutputBuffer[i]);
00665           outBufExchanged[i]--;
00666           pOutputBuffer[1]=NULL;
00667           isOutputBufferNeeded[i]=OMX_TRUE;
00668           DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning output buffer for port %i\n",i);
00669         }
00670       }
00671       
00672       pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
00673       pthread_cond_signal(&omx_clocksrc_component_Private->flush_all_condition);
00674       pthread_cond_wait(&omx_clocksrc_component_Private->flush_condition,&omx_clocksrc_component_Private->flush_mutex);
00675 
00676       bPortsBeingFlushed = OMX_FALSE;
00677       for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00678         bPortsBeingFlushed |= PORT_IS_BEING_FLUSHED(pOutPort[i]);
00679       }
00680     }
00681     pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);
00682 
00683     /*Wait for clock state event*/
00684     DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Waiting for clock event\n",__func__);
00685     tsem_down(omx_clocksrc_component_Private->clockEventSem);
00686     DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s clock event occured semval=%d \n",__func__,omx_clocksrc_component_Private->clockEventSem->semval);
00687 
00688     /*If port is not tunneled then simply return the buffer except paused state*/
00689     if(omx_clocksrc_component_Private->transientState == OMX_TransStatePauseToExecuting) {
00690       for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00691         if(!PORT_IS_TUNNELED(pOutPort[i])) {
00692 
00693           if(pOutputSem[i]->semval>0 && isOutputBufferNeeded[i]==OMX_TRUE ) {
00694             tsem_down(pOutputSem[i]);
00695             if(pOutputQueue[i]->nelem>0){
00696               outBufExchanged[i]++;
00697               isOutputBufferNeeded[i]=OMX_FALSE;
00698               pOutputBuffer[i] = dequeue(pOutputQueue[i]);
00699               if(pOutputBuffer[i] == NULL){
00700                 DEBUG(DEB_LEV_ERR, "Had NULL output buffer!!\n");
00701                 break;
00702               }
00703             }
00704           }
00705 
00706           if(isOutputBufferNeeded[i]==OMX_FALSE) {
00707             /*Output Buffer has been produced or EOS. So, return output buffer and get new buffer*/
00708             if(pOutputBuffer[i]->nFilledLen!=0) {
00709               pOutPort[i]->ReturnBufferFunction((omx_base_PortType*)pOutPort[i],pOutputBuffer[i]);
00710               outBufExchanged[i]--;
00711               pOutputBuffer[i]=NULL;
00712               isOutputBufferNeeded[i]=OMX_TRUE;
00713             }
00714           }
00715         }
00716       }
00717       omx_clocksrc_component_Private->transientState = OMX_TransStateMax;
00718     }
00719     
00720     if(omx_clocksrc_component_Private->state == OMX_StateLoaded  || 
00721        omx_clocksrc_component_Private->state == OMX_StateInvalid ||
00722        omx_clocksrc_component_Private->transientState == OMX_TransStateIdleToLoaded ||
00723        omx_clocksrc_component_Private->transientState == OMX_TransStateInvalid) {
00724 
00725       DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
00726       break;
00727     }
00728 
00729     for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
00730       if(pOutPort[i]->sMediaTime.eUpdateType == OMX_TIME_UpdateClockStateChanged || 
00731          pOutPort[i]->sMediaTime.eUpdateType == OMX_TIME_UpdateScaleChanged      || 
00732          pOutPort[i]->sMediaTime.eUpdateType == OMX_TIME_UpdateRequestFulfillment){  
00733 
00734         if((isOutputBufferNeeded[i]==OMX_TRUE && pOutputSem[i]->semval==0) && 
00735           (omx_clocksrc_component_Private->state != OMX_StateLoaded && omx_clocksrc_component_Private->state != OMX_StateInvalid) 
00736           && PORT_IS_ENABLED(pOutPort[i])) {
00737           //Signalled from EmptyThisBuffer or FillThisBuffer or some where else
00738           DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for next output buffer %i\n",i);
00739           tsem_down(omx_clocksrc_component_Private->bMgmtSem);
00740         }
00741         if(omx_clocksrc_component_Private->state == OMX_StateLoaded  || 
00742            omx_clocksrc_component_Private->state == OMX_StateInvalid ||
00743            omx_clocksrc_component_Private->transientState == OMX_TransStateIdleToLoaded ||
00744            omx_clocksrc_component_Private->transientState == OMX_TransStateInvalid) {
00745           DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
00746           break;
00747         }
00748         pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
00749         bPortsBeingFlushed = OMX_FALSE;
00750         for(j=0;j<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;j++) {
00751           bPortsBeingFlushed |= PORT_IS_BEING_FLUSHED(pOutPort[j]);
00752         }
00753         pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);
00754         if(bPortsBeingFlushed) {
00755           break;
00756         }
00757         if(pOutputSem[i]->semval>0 && isOutputBufferNeeded[i]==OMX_TRUE ) {
00758           tsem_down(pOutputSem[i]);
00759           if(pOutputQueue[i]->nelem>0){
00760             outBufExchanged[i]++;
00761             isOutputBufferNeeded[i]=OMX_FALSE;
00762             pOutputBuffer[i] = dequeue(pOutputQueue[i]);
00763             if(pOutputBuffer[i] == NULL){
00764               DEBUG(DEB_LEV_ERR, "Had NULL output buffer!!\n");
00765               break;
00766             }
00767           }
00768         }
00769         /*Process Output buffer of Port i */
00770         if(isOutputBufferNeeded[i]==OMX_FALSE) {
00771           if (omx_clocksrc_component_Private->BufferMgmtCallback) {
00772             (*(omx_clocksrc_component_Private->BufferMgmtCallback))(openmaxStandComp, pOutputBuffer[i]);
00773           } else {
00774             /*If no buffer management call back then don't produce any output buffer*/
00775             pOutputBuffer[i]->nFilledLen = 0;
00776           }
00777       
00778            /*Output Buffer has been produced or EOS. So, return output buffer and get new buffer*/
00779           if(pOutputBuffer[i]->nFilledLen!=0) {
00780             pOutPort[i]->ReturnBufferFunction((omx_base_PortType*)pOutPort[i],pOutputBuffer[i]);
00781             outBufExchanged[i]--;
00782             pOutputBuffer[i]=NULL;
00783             isOutputBufferNeeded[i]=OMX_TRUE;
00784           }
00785         }
00786       }
00787     }
00788 
00789     DEBUG(DEB_LEV_SIMPLE_SEQ, "Sent Clock Event for all ports\n");
00790     tsem_up(omx_clocksrc_component_Private->clockEventCompleteSem);
00791   }
00792   DEBUG(DEB_LEV_SIMPLE_SEQ,"Exiting Buffer Management Thread\n");
00793   return NULL;
00794 }
00795 
00800 OMX_ERRORTYPE clocksrc_port_FlushProcessingBuffers(omx_base_PortType *openmaxStandPort) {
00801   omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private;
00802   OMX_BUFFERHEADERTYPE* pBuffer;
00803 
00804   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00805   omx_clocksrc_component_Private = (omx_clocksrc_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate;
00806 
00807   pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
00808   openmaxStandPort->bIsPortFlushed=OMX_TRUE;
00809   /*Signal the buffer management thread of port flush,if it is waiting for buffers*/
00810   if(omx_clocksrc_component_Private->bMgmtSem->semval==0) {
00811     tsem_up(omx_clocksrc_component_Private->bMgmtSem);
00812   }
00813   tsem_up(omx_clocksrc_component_Private->clockEventSem);
00814 
00815   if(omx_clocksrc_component_Private->state==OMX_StatePause ) {
00816     /*Waiting at paused state*/
00817     tsem_signal(omx_clocksrc_component_Private->bStateSem);
00818   }
00819   DEBUG(DEB_LEV_FULL_SEQ, "In %s waiting for flush all condition port index =%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex);
00820   /* Wait until flush is completed */
00821   pthread_cond_wait(&omx_clocksrc_component_Private->flush_all_condition,&omx_clocksrc_component_Private->flush_mutex);
00822   pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);
00823 
00824   tsem_reset(omx_clocksrc_component_Private->bMgmtSem);
00825   tsem_reset(omx_clocksrc_component_Private->clockEventSem);
00826 
00827   /* Flush all the buffers not under processing */
00828   while (openmaxStandPort->pBufferSem->semval > 0) {
00829     DEBUG(DEB_LEV_FULL_SEQ, "In %s TFlag=%x Flusing Port=%d,Semval=%d Qelem=%d\n", 
00830     __func__,(int)openmaxStandPort->nTunnelFlags,(int)openmaxStandPort->sPortParam.nPortIndex,
00831     (int)openmaxStandPort->pBufferSem->semval,(int)openmaxStandPort->pBufferQueue->nelem);
00832 
00833     tsem_down(openmaxStandPort->pBufferSem);
00834     pBuffer = dequeue(openmaxStandPort->pBufferQueue);
00835     if (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) {
00836       DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s is returning io:%d buffer\n", 
00837         __func__,omx_clocksrc_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex);
00838       if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
00839         ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
00840       } else {
00841         ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
00842       }
00843     } else if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00844       queue(openmaxStandPort->pBufferQueue,pBuffer);
00845     } else {
00846       (*(openmaxStandPort->BufferProcessedCallback))(
00847         openmaxStandPort->standCompContainer,
00848         omx_clocksrc_component_Private->callbackData,
00849         pBuffer);
00850     }
00851   }
00852   /*Port is tunneled and supplier and didn't received all it's buffer then wait for the buffers*/
00853   if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00854     while(openmaxStandPort->pBufferQueue->nelem!= openmaxStandPort->nNumAssignedBuffers){
00855       tsem_down(openmaxStandPort->pBufferSem);
00856       DEBUG(DEB_LEV_PARAMS, "In %s Got a buffer qelem=%d\n",__func__,openmaxStandPort->pBufferQueue->nelem);
00857     }
00858     tsem_reset(openmaxStandPort->pBufferSem);
00859   }
00860 
00861   openmaxStandPort->bIsPortFlushed=OMX_FALSE;
00862 
00863   pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
00864   pthread_cond_signal(&omx_clocksrc_component_Private->flush_condition);
00865   pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);
00866 
00867   DEBUG(DEB_LEV_FULL_SEQ, "Out %s Port Index=%d bIsPortFlushed=%d Component %s\n", __func__,
00868     (int)openmaxStandPort->sPortParam.nPortIndex,(int)openmaxStandPort->bIsPortFlushed,omx_clocksrc_component_Private->name);
00869 
00870   DEBUG(DEB_LEV_PARAMS, "In %s TFlag=%x Qelem=%d BSem=%d bMgmtsem=%d component=%s\n", __func__,
00871     (int)openmaxStandPort->nTunnelFlags,
00872     (int)openmaxStandPort->pBufferQueue->nelem,
00873     (int)openmaxStandPort->pBufferSem->semval,
00874     (int)omx_clocksrc_component_Private->bMgmtSem->semval,
00875     omx_clocksrc_component_Private->name);
00876 
00877   DEBUG(DEB_LEV_FUNCTION_NAME, "Out %s Port Index=%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex);
00878 
00879   return OMX_ErrorNone;
00880 }
00881 

Generated for OpenMAX Bellagio rel. 0.9.0 by  doxygen 1.5.1
SourceForge.net Logo