📄 stclkrv.c
字号:
ExtendedSTC->BaseBit32 = UpdatedSTC.BaseBit32;
ExtendedSTC->BaseValue = UpdatedSTC.BaseValue;
ExtendedSTC->Extension = UpdatedSTC.Extension;
ReturnCode = ST_NO_ERROR; /* everything OK */
}
}/* else failed to obtain STC */
} /* else not stc baseline mode */
return ReturnCode;
}
/****************************************************************************
Name : STCLKRV_GetSTC()
Description : Returns the decoder clock time if a recent PCR update has
been received. This is the addition of the PCR value and
elapsed time since the last packet (non PCR) was received.
If baselining is enabled the STCbaseline is incremented based
on the time elapsed since last update.
Parameters : STCLKRV_Handle_t Handle
U32 *STC pointer to caller's System Time Clock variable
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors occurred
ST_ERROR_BAD_PARAMETER One or more invalid parameters
ST_ERROR_INVALID_HANDLE Not open or invalid handle
STCLKRV_ERROR_PCR_UNAVAILABLE Accurate Decode unavailable
See Also : STCLKRV_Open()
****************************************************************************/
ST_ErrorCode_t STCLKRV_GetSTC( STCLKRV_Handle_t Handle,
U32 *STC )
{
ST_ErrorCode_t ReturnCode = STCLKRV_ERROR_PCR_UNAVAILABLE;
U32 ArrivalTime;
U32 ElapsedTime;
BOOL STCErrorRet = TRUE;
STCLKRV_ControlBlock_t *TmpCB_p;
clock_t MicroSecsSinceLastCall;
STCLKRV_ExtendedSTC_t FreerunIncSTC;
STCLKRV_ExtendedSTC_t UpdatedSTC;
U32 STCReferenceControl;
BOOL FreerunSTCActive;
BOOL ActvRefPCRValid;
clock_t FreerunSTCTimer;
STCLKRV_ExtendedSTC_t STCBaseline;
U32 ActvRefPCRBaseValue;
U32 ActvRefPCRTime;
#ifdef ST_5188
STDEMUX_Slot_t STPTISlot;
#else
STPTI_Slot_t STPTISlot;
#endif
#if defined (ST_5100)
clock_t HPTTicks;
#else
#ifdef ST_5188
STDEMUX_TimeStamp_t STCCurrentTime; /* @ 90 kHz*/
#else
STPTI_TimeStamp_t STCCurrentTime; /* @ 90 kHz*/
#endif
clock_t TimeIn90kHzUnits;
#endif
S32 STCOffset;
/* Check handle is valid */
TmpCB_p = FindInstanceByHandle(Handle);
if (TmpCB_p == NULL)
{
return( ST_ERROR_INVALID_HANDLE );
}
if( STC == NULL ) /* NULL variable ptr? */
{
return( ST_ERROR_BAD_PARAMETER );
}
/* Protect access and get shared data */
EnterCriticalSection();
STCReferenceControl = (U32)TmpCB_p->STCBaseline.STCReferenceControl;
FreerunSTCActive = TmpCB_p->FreerunSTC.Active;
FreerunSTCTimer = TmpCB_p->FreerunSTC.Timer;
STCBaseline = TmpCB_p->STCBaseline.STC;
ActvRefPCRValid = TmpCB_p->ActvRefPcr.Valid;
ActvRefPCRBaseValue = TmpCB_p->ActvRefPcr.PcrBaseValue;
ActvRefPCRTime = TmpCB_p->ActvRefPcr.Time;
STPTISlot = TmpCB_p->Slot;
STCOffset = TmpCB_p->OffsetInSTC;
LeaveCriticalSection();
/* For STC basline mode, freerunning is forced */
if ((STCReferenceControl == (U32)STCLKRV_STC_SOURCE_BASELINE) && (FreerunSTCActive == TRUE))
{
#if defined (ST_5100)
/* Get high priority timer ticks */
GetHPTimer(HPTTicks);
/* calc time elapsed in ticks */
MicroSecsSinceLastCall = STOS_time_minus(HPTTicks, FreerunSTCTimer);
/* Adjust to usecs */
AdjustHPTTicksToMicroSec(MicroSecsSinceLastCall);
/* Convert elapsed time to ExtSTC format */
ConvertMicroSecsToExtSTC(MicroSecsSinceLastCall, &FreerunIncSTC);
#else
#ifdef ST_5188
if (STDEMUX_GetCurrentTimer(TmpCB_p->InitPars.PTIDeviceName,
&STCCurrentTime) != ST_NO_ERROR)
#else
if (STPTI_GetCurrentPTITimer(TmpCB_p->InitPars.PTIDeviceName,
&STCCurrentTime) != ST_NO_ERROR)
#endif
{
return STCLKRV_ERROR_PCR_UNAVAILABLE;
}
TimeIn90kHzUnits = STOS_time_minus(STCCurrentTime.LSW, FreerunSTCTimer);
/* Convert elapsed time to ExtSTC format */
FreerunIncSTC.BaseValue = TimeIn90kHzUnits;
FreerunIncSTC.BaseBit32 = 0;
FreerunIncSTC.Extension = 0;
/* Approx value will work */
MicroSecsSinceLastCall = (TimeIn90kHzUnits * 11);
#endif
/* Add elapsed time in ExtSTC format to baseline */
AddTwoExtSTCValues(FreerunIncSTC, STCBaseline, &UpdatedSTC);
if (MicroSecsSinceLastCall >= STC_REBASELINE_TIME)
{
/* Protect data and update control values */
EnterCriticalSection();
TmpCB_p->STCBaseline.STC.BaseValue = UpdatedSTC.BaseValue;
TmpCB_p->STCBaseline.STC.BaseBit32 = UpdatedSTC.BaseBit32;
TmpCB_p->STCBaseline.STC.Extension = UpdatedSTC.Extension;
#if defined (ST_5100)
TmpCB_p->FreerunSTC.Timer = HPTTicks;
#else
TmpCB_p->FreerunSTC.Timer = STCCurrentTime.LSW;
#endif
LeaveCriticalSection();
}
/* Return updated 90kHz baseline value */
*STC = UpdatedSTC.BaseValue + STCOffset;
ReturnCode = ST_NO_ERROR;
}
else
{
if ((STCReferenceControl == (U32)STCLKRV_STC_SOURCE_PCR) && (ActvRefPCRValid))
{
#ifdef ST_5188
STCErrorRet = STDEMUX_GetCurrentTimer(TmpCB_p->InitPars.PTIDeviceName,
&STCCurrentTime);
ArrivalTime = STCCurrentTime.LSW*CONV90K_TO_27M;
#else
STCErrorRet = GetPacketArrivalTime(STPTISlot, &ArrivalTime);
#endif
if (!STCErrorRet)
{
/* Calulate time elapsed since reference point */
/* correctly handles wrap */
ElapsedTime = (STOS_time_minus(ArrivalTime, ActvRefPCRTime)
/ CONV90K_TO_27M);
#if defined (CLKRV_FILTERDEBUG)
STCLKRV_Print(("STCLKRV_GetSTC %u-%u=%u*300\n",
ArrivalTime, ActvRefPCRTime, ElapsedTime));
#endif
/* restrict elapsed time to reasonable level */
if ((ElapsedTime >> PCR_STALE_SHIFT) == 0)
{
*STC = ActvRefPCRBaseValue + ElapsedTime + STCOffset;
ReturnCode = ST_NO_ERROR; /* everything OK */
}
else
{
STTBX_Report((STTBX_REPORT_LEVEL_ERROR,
"%u-%u=%u*300 judged stale\n",
ArrivalTime, ActvRefPCRTime, ElapsedTime));
}
}
else
{
STTBX_Report((STTBX_REPORT_LEVEL_ERROR,
"STCLKRV_GetSTC: GetPacketArrivalTime failed\n"));
}
}
else
{
STTBX_Report((STTBX_REPORT_LEVEL_ERROR,
"STCLKRV_GetSTC: no valid PCR reference\n"));
}
}
return ReturnCode;
}
/****************************************************************************
Name : STCLKRV_SetSTCBaseline
Description : Loads given STC baseline value to UserBaseline storage area.
Takes time stamp for reference.
Parameters : STCLKRV_Handle_t Handle
STCLKRV_ExtendedSTC_t STC comprising 90KHz base value, bit32
and 27Mhz extension value.
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors determined
ST_ERROR_INVALID_HANDLE Invalid Handle
See Also : STCLKRV_Enable()
****************************************************************************/
ST_ErrorCode_t STCLKRV_SetSTCBaseline(STCLKRV_Handle_t Handle,
STCLKRV_ExtendedSTC_t *STC)
{
/* Temp ptr into instance list */
STCLKRV_ControlBlock_t *TmpCB_p = NULL;
#if defined (ST_5100)
clock_t HPTTicks;
#else
#ifdef ST_5188
STDEMUX_TimeStamp_t STCCurrentTime; /* @ 90 kHz*/
#else
STPTI_TimeStamp_t STCCurrentTime; /* @ 90 kHz*/
#endif
#endif
ST_ErrorCode_t ReturnCode = ST_NO_ERROR;
/* Check handle is valid */
TmpCB_p = FindInstanceByHandle(Handle);
if (TmpCB_p == NULL)
{
return (ST_ERROR_INVALID_HANDLE);
}
#if !defined (ST_5100)
#ifdef ST_5188
if (STDEMUX_GetCurrentTimer(TmpCB_p->InitPars.PTIDeviceName,
&STCCurrentTime) != ST_NO_ERROR)
#else
if (STPTI_GetCurrentPTITimer(TmpCB_p->InitPars.PTIDeviceName,
&STCCurrentTime) != ST_NO_ERROR)
#endif
{
return (ST_ERROR_UNKNOWN_DEVICE);
}
#endif
/* Exclusive access to data */
EnterCriticalSection();
/* Write given value to user baseline */
TmpCB_p->STCBaseline.STC.BaseBit32 = STC->BaseBit32;
TmpCB_p->STCBaseline.STC.BaseValue = STC->BaseValue;
TmpCB_p->STCBaseline.STC.Extension = STC->Extension;
/* Free run control */
TmpCB_p->FreerunSTC.Active = TRUE;
#if defined (ST_5100)
GetHPTimer(HPTTicks);
TmpCB_p->FreerunSTC.Timer = HPTTicks;
#else
TmpCB_p->FreerunSTC.Timer = STCCurrentTime.LSW;
#endif
LeaveCriticalSection();
return (ReturnCode);
}
/****************************************************************************
Name : STCLKRV_SetSTCOffset
Description : Sets the offset to be added in base value of returned STC
value from GET_XXXSTC APIs.
Parameters : STCLKRV_Handle_t Handle
S32 Offset given in 90kHz units
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors determined
ST_ERROR_INVALID_HANDLE Invalid Handle
See Also : STCLKRV_GetExtendedSTC()
****************************************************************************/
ST_ErrorCode_t STCLKRV_SetSTCOffset( STCLKRV_Handle_t Handle,
S32 Offset)
{
/* Temp ptr into instance list */
STCLKRV_ControlBlock_t *TmpCB_p = NULL;
ST_ErrorCode_t ReturnCode = ST_NO_ERROR;
/* Check handle is valid */
TmpCB_p = FindInstanceByHandle(Handle);
if (TmpCB_p == NULL)
{
return (ST_ERROR_INVALID_HANDLE);
}
EnterCriticalSection();
TmpCB_p->OffsetInSTC = Offset;
LeaveCriticalSection();
return ReturnCode;
}
/****************************************************************************
Name : STCLKRV_InvDecodeClk()
Description : Invalidates the PCR reference valid flag internally, causing
rapid PCR re-basing.
Parameters : STCLKRV_Handle_t Handle
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors determined
ST_ERROR_INVALID_HANDLE Invalid Handle
See Also : STCLKRV_Open()
****************************************************************************/
ST_ErrorCode_t STCLKRV_InvDecodeClk( STCLKRV_Handle_t Handle )
{
STCLKRV_ControlBlock_t *TmpCB_p = NULL; /* Temp ptr into instance list */
/* Check handle is valid */
TmpCB_p = FindInstanceByHandle(Handle);
if (TmpCB_p == NULL)
{
return( ST_ERROR_INVALID_HANDLE );
}
if (TmpCB_p->InitPars.DeviceType==STCLKRV_DEVICE_TYPE_BASELINE_ONLY)
{
/* Protect and update data */
EnterCriticalSect
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -