UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
UE::TimeManagement::TimecodeEstimation::FTimecodeEstimator Class Reference

#include <TimecodeEstimator.h>

Public Member Functions

UE_API FTimecodeEstimator (SIZE_T InNumSamples, UTimecodeProvider &InTimecode UE_LIFETIMEBOUND, IClockedTimeStep &InEngineCustomTimeStep UE_LIFETIMEBOUND)
 
UE_API TOptional< FFetchAndUpdateStatsFetchAndUpdate ()
 
UE_API FQualifiedFrameTime EstimateFrameTime () const
 

Detailed Description

Estimates the current timecode based on an IClockedTimeStep implementation, which is designed to be an UEngineCustomTimeStep.

The engine starts each frame by calling UEngineCustomTimeStep::UpdateTimeStep. Then, using UTimecodeProvider::FetchAndUpdate, the engine calls FApp::SetCurrentFrameTime with the result of UTimecodeProvider::GetQualifiedFrameTime. Workflow:

  • FTimecodeEstimator: FetchAndUpdate samples the time code and tags it using the underlying clock's actual time (platform time, PTP, etc.), which is retrieved using IClockedTimeStep.
  • FTimecodeEstimator::GetQualifiedFrameTime estimates the current frame's time code by using the FApp::CurrentTime for linear regression of the sampled time codes. For this to work, FApp::CurrentTime is expected to be accumulation of all past delta times the UCustomTimeStep step has issued, which is sometimes called "game time" or "simulation time".

If coupled with a UEngineCustomTimeStep that implements a fixed engine step rate, we can effectively handle hitching game frames, i.e. when frames take longer than the frame rate dedicated by the time code provider. Some systems, like Live Link, are used for querying external data; for the look-up, we use the frame's time code of the frame. However, when a frame takes longer, the subsequent frame needs to use the timecode value that was intended for that frame. The previous engine behaviour was to use FPlatformTime::Seconds() to determine the timecode the frame should have, which can cause the subsequent frame to inherit frame hitches.

Explaining the issue with an example (TC = timecode):

  • The external timecode device's frame is set to 24 FPS, i.e. the frame budget is 0.0416666667s
  • Frame n is annotated with TC = 00:09:15.004.
  • Frame n takes 0.2s to process.
  • While frame n was running, the timecode's frame actually increased by 5 frames to 00:09:15.009 (i.e. real time passed by 5 target frames worth). Behaviours:
  • Old:
    • We used to use the current platform time to determine timecode. This makes sense because TC is actually linearly correlated with physical time.
    • So frame n+1 would use 00:09:15.009. Passing this to Live Link would skip the 5 frames of past data, and we'd get jumps in evaluated data. So the simulation would skip 5 frames of live link data.
  • New (you'd use UTimecodeRegressionProvider):
    • We'll estimate the timecode using linear regression.
    • While the actual platform time has moved by 0.2s, FApp::CurrentTime should have only elapsed by DeltaTime (to simplify assume DeltaTime = 0.0416s).
    • We ASSUME that DeltaTime is in the same time unit as the clock used internally in the custom time step, which could be FPlatformTime, PTP, Rivermax time, Genlock time, etc. Basically, see what IClockedTimeStep::GetUnderlyingClockTime_AnyThread returns. So frame n+1 would now use 00:09:15.005, which corresponds to the data that was sent to Live Link by external devices.
    • Above we assumed that DeltaTime moves forward by 0.0416s, but the time step can decide this.
      • Keeping DeltaTime = 0.0416s may cause the engine to never catch up with the external world but ensures that every frame always processes the data for each frame (good for Take Recording).
      • Increasing DeltaTime will increase the game time faster, thus allowing the engine to catch up, but to also skip recorded frame data. It can result in visual jumps (good for real-time applications where the engine should not fall behind too much).

Constructor & Destructor Documentation

◆ FTimecodeEstimator()

UE::TimeManagement::TimecodeEstimation::FTimecodeEstimator::FTimecodeEstimator ( SIZE_T  InNumSamples,
UTimecodeProvider &InTimecode  UE_LIFETIMEBOUND,
IClockedTimeStep &InEngineCustomTimeStep  UE_LIFETIMEBOUND 
)
explicit
Parameters
InNumSamplesThe number of samples to used for linear regression.
InTimecodeThe timecoder provider for which we estimate the current frame's time. Caller ensures this outlives the constructed FTimecodeEstimator.
InEngineCustomTimeStepThe provider of the current clock time. Caller ensures this outlives the constructed FTimecodeEstimator.

Member Function Documentation

◆ EstimateFrameTime()

FQualifiedFrameTime UE::TimeManagement::TimecodeEstimation::FTimecodeEstimator::EstimateFrameTime ( ) const

Estimates what the current frame time should be given FApp::CurrentTime's value.

◆ FetchAndUpdate()

TOptional< FFetchAndUpdateStats > UE::TimeManagement::TimecodeEstimation::FTimecodeEstimator::FetchAndUpdate ( )

Samples the current timecode and associates it with the underlying clock value.

Returns
Metadata about how update has occured, e.g. the "real", frame time sampled from the timecode provider. Unset if the custom time step's clock could not be read.

The documentation for this class was generated from the following files: