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// Copy these c++20 literals from the chrono header file
22#if __cplusplus <= 201703L
23namespace std::chrono // NOLINT(cert-dcl58-cpp)
24{
25 using days = duration<CHRONO_TYPE, ratio<86400>>;
26 using weeks = duration<CHRONO_TYPE, ratio<604800>>;
27 using months = duration<CHRONO_TYPE, ratio<2629746>>;
28 using years = duration<CHRONO_TYPE, ratio<31556952>>;
29}
30#endif // C++20
31
32
33//
34// Set up some additional data types for use by MythTV.
35//
36
37// There are a number of places that hold/manipulate time in the form
38// of a floating point number. Create unique types for these.
39using floatsecs = std::chrono::duration<double>;
40using floatmsecs = std::chrono::duration<double, std::milli>;
41using floatusecs = std::chrono::duration<double, std::micro>;
42
43// There are a handful of places that hold a time value in units of
44// AV_TIME_BASE. Create a unique type for this.
45#ifdef AV_TIME_BASE
46using av_duration = std::chrono::duration<int64_t,std::ratio<1,AV_TIME_BASE>>;
47#endif
48
49// Define namespaces for the presentation timestamp and a literal
50// suffix, and set up to parse the literal suffix.
51namespace mpeg
52{
53 namespace chrono
54 {
55 using pts = std::chrono::duration<CHRONO_TYPE, std::ratio<1, 90000>>;
56 }
57 namespace chrono_literals
58 {
59 constexpr mpeg::chrono::pts operator ""_pts(unsigned long long v) {
60 return mpeg::chrono::pts(v); }
61 }
62}
63using namespace mpeg::chrono_literals;
64
65// Set up types to easily reference the system clock.
66using SystemClock = std::chrono::system_clock;
67using SystemTime = std::chrono::time_point<SystemClock>;
68
69
70//
71// Functions for converting existing data types to std::chrono.
72//
73
78template <typename T>
79typename std::enable_if_t<std::is_floating_point_v<T>, std::chrono::seconds>
81{
82 return std::chrono::seconds(static_cast<int64_t>(value));
83}
84
89template <typename T>
90typename std::enable_if_t<std::is_floating_point_v<T>, std::chrono::milliseconds>
92{
93 return std::chrono::milliseconds(static_cast<int64_t>(value));
94}
95
100template <typename T>
101typename std::enable_if_t<std::is_floating_point_v<T>, std::chrono::microseconds>
103{
104 return std::chrono::microseconds(static_cast<int64_t>(value));
105}
106
108static constexpr
109std::chrono::milliseconds millisecondsFromParts (int hours, int minutes = 0,
110 int seconds = 0, int milliseconds = 0)
111{
112 return std::chrono::hours(hours)
113 + std::chrono::minutes(minutes)
114 + std::chrono::seconds(seconds)
115 + std::chrono::milliseconds(milliseconds);
116}
117
125template <typename T>
126constexpr T durationFromTimeval (timeval t)
127{
128 std::chrono::microseconds value = std::chrono::seconds(t.tv_sec) +
129 std::chrono::microseconds(t.tv_usec);
130 if constexpr (std::is_same_v<T,std::chrono::microseconds>)
131 return value;
132 return duration_cast<T>(value);
133}
134
142template <typename T>
143constexpr T durationFromTimevalDelta (timeval a, timeval b)
144{
145 auto usec_a = durationFromTimeval<std::chrono::microseconds>(a);
146 auto usec_b = durationFromTimeval<std::chrono::microseconds>(b);
147 if constexpr (std::is_same_v<T,std::chrono::microseconds>)
148 return usec_a - usec_b;
149 return duration_cast<T>(usec_a - usec_b);
150}
151
159template <typename T>
160constexpr T durationFromTimespec (struct timespec time)
161{
162 std::chrono::nanoseconds nsec = std::chrono::seconds(time.tv_sec)
163 + std::chrono::nanoseconds(time.tv_nsec);
164 if constexpr (std::is_same_v<T,std::chrono::nanoseconds>)
165 return nsec;
166 return duration_cast<T>(nsec);
167}
168
169
170//
171// Get current time as std::chrono duration
172//
173
182template <typename T>
183T nowAsDuration (bool adjustForTZ = false)
184{
185 struct timeval now {};
186 struct timezone tz {};
187 gettimeofday(&now, &tz);
188
189 auto usecs = durationFromTimeval<std::chrono::microseconds>(now);
190 if (adjustForTZ)
191 usecs -= std::chrono::minutes(tz.tz_minuteswest);
192 if constexpr (std::is_same_v<T,std::chrono::microseconds>)
193 return usecs;
194 return duration_cast<T>(usecs);
195}
196
198template <typename T>
199static constexpr T chronomult(T duration, double f)
200{
201 return T(std::llround(duration.count() * f));
202}
204template <typename T>
205static constexpr T chronodivide(T duration, double f)
206{
207 return T(std::llround(duration.count() / f));
208}
209
210#endif // MYTHCHRONO_H
std::enable_if_t< std::is_floating_point_v< T >, std::chrono::milliseconds > millisecondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
Definition: mythchrono.h:91
constexpr T durationFromTimevalDelta(timeval a, timeval b)
Compute delta between timevals and convert to a duration.
Definition: mythchrono.h:143
constexpr T durationFromTimespec(struct timespec time)
Convert a timespec to a duration.
Definition: mythchrono.h:160
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:199
std::enable_if_t< std::is_floating_point_v< T >, std::chrono::seconds > secondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
Definition: mythchrono.h:80
constexpr T durationFromTimeval(timeval t)
Convert a timeval to a duration.
Definition: mythchrono.h:126
std::enable_if_t< std::is_floating_point_v< T >, std::chrono::microseconds > microsecondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
Definition: mythchrono.h:102
std::chrono::system_clock SystemClock
Definition: mythchrono.h:66
T nowAsDuration(bool adjustForTZ=false)
Get the currenttime as a duration.
Definition: mythchrono.h:183
std::chrono::duration< double, std::micro > floatusecs
Definition: mythchrono.h:41
static constexpr T chronodivide(T duration, double f)
Divide a duration by a float, returning a duration.
Definition: mythchrono.h:205
std::chrono::duration< double > floatsecs
Definition: mythchrono.h:39
std::chrono::duration< double, std::milli > floatmsecs
Definition: mythchrono.h:40
std::chrono::time_point< SystemClock > SystemTime
Definition: mythchrono.h:67
Q_DECLARE_METATYPE(std::chrono::seconds)
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:109
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
Definition: mythchrono.h:55
duration< CHRONO_TYPE, ratio< 2629746 > > months
Definition: mythchrono.h:27
duration< CHRONO_TYPE, ratio< 604800 > > weeks
Definition: mythchrono.h:26
duration< CHRONO_TYPE, ratio< 31556952 > > years
Definition: mythchrono.h:28
duration< CHRONO_TYPE, ratio< 86400 > > days
Definition: mythchrono.h:25