5#include "Containers/UnrealString.h"
6#include "GenericPlatform/GenericPlatformMath.h"
7#include "HAL/Platform.h"
8#include "Math/UnrealMathUtility.h"
9#include "Misc/FrameNumber.h"
10#include "Misc/FrameRate.h"
11#include "Misc/Timespan.h"
14
15
16
20
21
31
32
33
34
35
36 explicit FTimecode(int32 InHours, int32 InMinutes, int32 InSeconds, int32 InFrames,
bool InbDropFrame)
45
46
47
48
49
50
51
52 explicit FTimecode(
double InSeconds,
const FFrameRate& InFrameRate,
bool InbDropFrame,
bool InbRollover)
56 const int32 NumberOfSecondsPerDay = 60 * 60 * 24;
57 double IntegralPart = 0.0;
58 double Fractional = FMath::Modf(InSeconds, &IntegralPart);
59 const int32 CurrentRolloverSeconds = (int32)IntegralPart % NumberOfSecondsPerDay;
60 InSeconds = (
double)CurrentRolloverSeconds + Fractional;
63 const int32 NumberOfFrames = (int32)FMath::RoundToDouble(InSeconds * InFrameRate.AsDecimal());
68
69
70
71
85
86
89 const int32 NumberOfFramesInSecond = FMath::CeilToInt((
float)InFrameRate.AsDecimal());
90 const int32 NumberOfFramesInMinute = NumberOfFramesInSecond * 60;
91 const int32 NumberOfFramesInHour = NumberOfFramesInMinute * 60;
93 if (NumberOfFramesInSecond <= 0)
99 int32 SafeSeconds =
Seconds +
Frames / NumberOfFramesInSecond;
100 int32 SafeFrames =
Frames % NumberOfFramesInSecond;
102 int32 SafeMinutes =
Minutes + SafeSeconds / 60;
103 SafeSeconds = SafeSeconds % 60;
105 int32 SafeHours =
Hours + SafeMinutes / 60;
106 SafeMinutes = SafeMinutes % 60;
110 const int32 NumberOfTimecodesToDrop = NumberOfFramesInSecond <= 30 ? 2 : 4;
113 int32 TotalMinutes = (SafeHours * 60) + SafeMinutes;
116 int32 TotalDroppedFrames = NumberOfTimecodesToDrop * (TotalMinutes - (int32)
FMath::RoundToZero(TotalMinutes / 10.0
));
117 int32 TotalFrames = (SafeHours * NumberOfFramesInHour) + (SafeMinutes * NumberOfFramesInMinute) + (SafeSeconds * NumberOfFramesInSecond)
118 + SafeFrames - TotalDroppedFrames;
120 return FFrameNumber(TotalFrames);
124 int32 TotalFrames = (SafeHours *NumberOfFramesInHour) + (SafeMinutes * NumberOfFramesInMinute) + (SafeSeconds * NumberOfFramesInSecond) + SafeFrames;
125 return FFrameNumber(TotalFrames);
130
131
132
133
134
135
136
137
138
139
142 const int32 NumberOfFramesInSecond = FMath::CeilToInt((
float)InFrameRate.AsDecimal());
143 const int32 NumberOfFramesInMinute = NumberOfFramesInSecond * 60;
144 const int32 NumberOfFramesInHour = NumberOfFramesInMinute * 60;
146 if (NumberOfFramesInSecond <= 0)
164 const int32 NumberOfTimecodesToDrop = NumberOfFramesInSecond <= 30 ? 2 : 4;
167 const int32 NumTrueFramesPerTenMinutes = FMath::FloorToInt((
float)((60 * 10) * InFrameRate.AsDecimal()));
170 const int32 NumTimesSkippedDroppingFrames = FMath::Abs(InFrameNumber.Value) / NumTrueFramesPerTenMinutes;
173 const int32 NumFramesSkippedTotal = NumTimesSkippedDroppingFrames * 9 * NumberOfTimecodesToDrop;
175 int32 OffsetFrame = FMath::Abs(InFrameNumber.Value);
176 int FrameInTrueFrames = OffsetFrame % NumTrueFramesPerTenMinutes;
179 if (FrameInTrueFrames < NumberOfTimecodesToDrop)
181 OffsetFrame += NumFramesSkippedTotal;
187 const uint32 NumTrueFramesPerMinute = (uint32)FMath::FloorToInt(60 * (
float)InFrameRate.AsDecimal());
190 int32 CurrentMinuteOfTen = (FrameInTrueFrames - NumberOfTimecodesToDrop) / NumTrueFramesPerMinute;
191 int NumAddedFrames = NumFramesSkippedTotal + (NumberOfTimecodesToDrop * CurrentMinuteOfTen);
192 OffsetFrame += NumAddedFrames;
196 OffsetFrame *= FMath::Sign(InFrameNumber.Value);
202 int32 Frames = OffsetFrame % NumberOfFramesInSecond;
212 int32 Frames = InFrameNumber
.Value % NumberOfFramesInSecond;
219
220
221
222
223
224
231
232
241
242
243
244
245
246
247
248
249
250
251
258
259
260
261
262
263
264
289
290
291
292
295 const FString NTSC_30_DF =
"29.97df";
296 const FString NTSC_60_DF =
"59.94df";
298 return (InRateString
== NTSC_30_DF || InRateString
== NTSC_60_DF);
302
303
304
305
310 const TCHAR* NegativeSign =
TEXT(
"- ");
311 const TCHAR* PositiveSign =
TEXT(
"+ ");
312 const TCHAR* SignText =
TEXT(
"");
313 if (bHasNegativeComponent)
315 SignText = NegativeSign;
317 else if (bForceSignDisplay)
319 SignText = PositiveSign;
324 return FString::Printf(
TEXT(
"%s%02d:%02d:%02d;%02d"), SignText, FMath::Abs(Hours), FMath::Abs(Minutes), FMath::Abs(Seconds), FMath::Abs(Frames));
328 return FString::Printf(
TEXT(
"%s%02d:%02d:%02d:%02d"), SignText, FMath::Abs(Hours), FMath::Abs(Minutes), FMath::Abs(Seconds), FMath::Abs(Frames));
UE_NODISCARD FORCEINLINE bool operator==(const FString &Rhs) const
friend bool operator!=(const FFrameRate &A, const FFrameRate &B)
friend bool operator==(const FFrameRate &A, const FFrameRate &B)
double AsInterval() const
static UE_NODISCARD FORCEINLINE double RoundToZero(double F)
static UE_NODISCARD FORCEINLINE bool IsNearlyEqual(double A, double B, double ErrorTolerance=UE_DOUBLE_SMALL_NUMBER)
static FTimecode FromTimespan(const FTimespan &InTimespan, const FFrameRate &InFrameRate, bool InbRollover)
FTimecode(double InSeconds, const FFrameRate &InFrameRate, bool InbRollover)
static FTimecode FromFrameNumber(const FFrameNumber &InFrameNumber, const FFrameRate &InFrameRate)
static bool IsDropFormatTimecodeSupported(const FFrameRate &InFrameRate)
FString ToString(bool bForceSignDisplay=false) const
FFrameNumber ToFrameNumber(const FFrameRate &InFrameRate) const
static bool UseDropFormatTimecode(const FFrameRate &InFrameRate)
friend bool operator!=(const FTimecode &A, const FTimecode &B)
friend bool operator==(const FTimecode &A, const FTimecode &B)
static bool UseDropFormatTimecodeByDefaultWhenSupported()
FTimecode(int32 InHours, int32 InMinutes, int32 InSeconds, int32 InFrames, bool InbDropFrame)
static FTimecode FromTimespan(const FTimespan &InTimespan, const FFrameRate &InFrameRate, bool InbDropFrame, bool InbRollover)
static FTimecode FromFrameNumber(const FFrameNumber &InFrameNumber, const FFrameRate &InFrameRate, bool InbDropFrame)
FTimecode(double InSeconds, const FFrameRate &InFrameRate, bool InbDropFrame, bool InbRollover)
FTimespan ToTimespan(const FFrameRate &InFrameRate) const
static bool IsValidDropFormatTimecodeRate(const FString &InRateString)
double GetTotalSeconds() const
static FTimespan FromSeconds(double Seconds)