MythTV master
mythchrono.h
Go to the documentation of this file.
1#ifndef MYTHCHRONO_H
2#define MYTHCHRONO_H
3
4#include <cmath>
5#include <sys/time.h> // For gettimeofday
6#include <QMetaType>
7
8
9// Include the std::chrono definitions, and set up to parse the
10// std::chrono literal suffixes.
11#include <chrono>
12using std::chrono::duration_cast;
13using namespace std::chrono_literals;
14Q_DECLARE_METATYPE(std::chrono::seconds);
15Q_DECLARE_METATYPE(std::chrono::milliseconds);
16Q_DECLARE_METATYPE(std::chrono::microseconds);
17
18// Grab the underlying std::chrono::duration data type for future use.
19using CHRONO_TYPE = std::chrono::seconds::rep;
20
21
22//
23// Set up some additional data types for use by MythTV.
24//
25
26// There are a number of places that hold/manipulate time in the form
27// of a floating point number. Create unique types for these.
28using floatsecs = std::chrono::duration<double>;
29using floatmsecs = std::chrono::duration<double, std::milli>;
30using floatusecs = std::chrono::duration<double, std::micro>;
31
32// There are a handful of places that hold a time value in units of
33// AV_TIME_BASE. Create a unique type for this.
34#ifdef AV_TIME_BASE
35using av_duration = std::chrono::duration<int64_t,std::ratio<1,AV_TIME_BASE>>;
36#endif
37
38// Define namespaces for the presentation timestamp and a literal
39// suffix, and set up to parse the literal suffix.
40namespace mpeg
41{
42 namespace chrono
43 {
44 using pts = std::chrono::duration<CHRONO_TYPE, std::ratio<1, 90000>>;
45 }
46 namespace chrono_literals
47 {
48 constexpr mpeg::chrono::pts operator ""_pts(unsigned long long v) {
49 return mpeg::chrono::pts(v); }
50 }
51}
52using namespace mpeg::chrono_literals;
53
54// Set up types to easily reference the system clock.
55using SystemClock = std::chrono::system_clock;
56using SystemTime = std::chrono::time_point<SystemClock>;
57
58
59//
60// Functions for converting existing data types to std::chrono.
61//
62
67template <typename T>
68std::chrono::seconds secondsFromFloat (T value)
69requires (std::is_floating_point_v<T>)
70{
71 return std::chrono::seconds(static_cast<int64_t>(value));
72}
73
78template <typename T>
79std::chrono::milliseconds millisecondsFromFloat (T value)
80requires (std::is_floating_point_v<T>)
81{
82 return std::chrono::milliseconds(static_cast<int64_t>(value));
83}
84
89template <typename T>
90std::chrono::microseconds
92requires (std::is_floating_point_v<T>)
93{
94 return std::chrono::microseconds(static_cast<int64_t>(value));
95}
96
98static constexpr
99std::chrono::milliseconds millisecondsFromParts (int hours, int minutes = 0,
100 int seconds = 0, int milliseconds = 0)
101{
102 return std::chrono::hours(hours)
103 + std::chrono::minutes(minutes)
104 + std::chrono::seconds(seconds)
105 + std::chrono::milliseconds(milliseconds);
106}
107
115template <typename T>
116constexpr T durationFromTimeval (timeval t)
117{
118 std::chrono::microseconds value = std::chrono::seconds(t.tv_sec) +
119 std::chrono::microseconds(t.tv_usec);
120 if constexpr (std::is_same_v<T,std::chrono::microseconds>)
121 return value;
122 return duration_cast<T>(value);
123}
124
132template <typename T>
133constexpr T durationFromTimevalDelta (timeval a, timeval b)
134{
135 auto usec_a = durationFromTimeval<std::chrono::microseconds>(a);
136 auto usec_b = durationFromTimeval<std::chrono::microseconds>(b);
137 if constexpr (std::is_same_v<T,std::chrono::microseconds>)
138 return usec_a - usec_b;
139 return duration_cast<T>(usec_a - usec_b);
140}
141
149template <typename T>
150constexpr T durationFromTimespec (struct timespec time)
151{
152 std::chrono::nanoseconds nsec = std::chrono::seconds(time.tv_sec)
153 + std::chrono::nanoseconds(time.tv_nsec);
154 if constexpr (std::is_same_v<T,std::chrono::nanoseconds>)
155 return nsec;
156 return duration_cast<T>(nsec);
157}
158
159
160//
161// Get current time as std::chrono duration
162//
163
172template <typename T>
173T nowAsDuration (bool adjustForTZ = false)
174{
175 struct timeval now {};
176 struct timezone tz {};
177 gettimeofday(&now, &tz);
178
179 auto usecs = durationFromTimeval<std::chrono::microseconds>(now);
180 if (adjustForTZ)
181 usecs -= std::chrono::minutes(tz.tz_minuteswest);
182 if constexpr (std::is_same_v<T,std::chrono::microseconds>)
183 return usecs;
184 return duration_cast<T>(usecs);
185}
186
188template <typename T>
189static constexpr T chronomult(T duration, double f)
190{
191 return T(std::llround(duration.count() * f));
192}
194template <typename T>
195static constexpr T chronodivide(T duration, double f)
196{
197 return T(std::llround(duration.count() / f));
198}
199
200#endif // MYTHCHRONO_H
constexpr T durationFromTimevalDelta(timeval a, timeval b)
Compute delta between timevals and convert to a duration.
Definition: mythchrono.h:133
constexpr T durationFromTimespec(struct timespec time)
Convert a timespec to a duration.
Definition: mythchrono.h:150
std::chrono::seconds::rep CHRONO_TYPE
Definition: mythchrono.h:19
static constexpr T chronomult(T duration, double f)
Multiply a duration by a float, returning a duration.
Definition: mythchrono.h:189
std::chrono::microseconds microsecondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
Definition: mythchrono.h:91
constexpr T durationFromTimeval(timeval t)
Convert a timeval to a duration.
Definition: mythchrono.h:116
std::chrono::system_clock SystemClock
Definition: mythchrono.h:55
T nowAsDuration(bool adjustForTZ=false)
Get the currenttime as a duration.
Definition: mythchrono.h:173
std::chrono::seconds secondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
Definition: mythchrono.h:68
std::chrono::duration< double, std::micro > floatusecs
Definition: mythchrono.h:30
static constexpr T chronodivide(T duration, double f)
Divide a duration by a float, returning a duration.
Definition: mythchrono.h:195
std::chrono::duration< double > floatsecs
Definition: mythchrono.h:28
std::chrono::duration< double, std::milli > floatmsecs
Definition: mythchrono.h:29
std::chrono::time_point< SystemClock > SystemTime
Definition: mythchrono.h:56
Q_DECLARE_METATYPE(std::chrono::seconds)
std::chrono::milliseconds millisecondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
Definition: mythchrono.h:79
static constexpr std::chrono::milliseconds millisecondsFromParts(int hours, int minutes=0, int seconds=0, int milliseconds=0)
Build a duration from separate minutes, seconds, etc.
Definition: mythchrono.h:99
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
Definition: mythchrono.h:44