|
OpenMAXBellagio 0.9.3
|
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