VLC 4.0.0-dev
vlc_tick.h
Go to the documentation of this file.
1/*****************************************************************************
2 * vlc_tick.h: high resolution time management functions
3 *****************************************************************************
4 * This header provides portable high precision time management functions,
5 * which should be the only ones used in other segments of the program, since
6 * functions like gettimeofday() and ftime() are not always supported.
7 * Most functions are declared as inline or as macros since they are only
8 * interfaces to system calls and have to be called frequently.
9 *****************************************************************************
10 * Copyright (C) 1996, 1997, 1998, 1999, 2000 VLC authors and VideoLAN
11 *
12 * Authors: Vincent Seguin <seguin@via.ecp.fr>
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU Lesser General Public License as published by
16 * the Free Software Foundation; either version 2.1 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public License
25 * along with this program; if not, write to the Free Software Foundation,
26 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
27 *****************************************************************************/
28
29#ifndef __VLC_MTIME_H
30# define __VLC_MTIME_H 1
31
32struct timespec;
33
34/**
35 * High precision date or time interval
36 *
37 * Store a high precision date or time interval. The maximum precision is the
38 * microsecond, and a 64 bits integer is used to avoid overflows (maximum
39 * time interval is then 292271 years, which should be long enough for any
40 * video). Dates are stored as microseconds since a common date (usually the
41 * epoch). Note that date and time intervals can be manipulated using regular
42 * arithmetic operators, and that no special functions are required.
43 */
44typedef int64_t vlc_tick_t;
46#define VLC_TICK_MIN INT64_MIN
47#define VLC_TICK_MAX INT64_MAX
49/*
50 * vlc_tick_t <> seconds (sec) conversions
51 */
52#define VLC_TICK_FROM_SEC(sec) (CLOCK_FREQ * (sec))
53#define SEC_FROM_VLC_TICK(vtk) ((vtk) / CLOCK_FREQ)
55#ifdef __cplusplus
56#include <type_traits>
57
58template <typename T>
59static inline auto vlc_tick_from_sec(T sec)
60 -> typename std::enable_if<std::is_integral<T>::value, vlc_tick_t>::type
61{
62 return CLOCK_FREQ * sec;
63}
64
65/* seconds in floating point */
66static inline vlc_tick_t vlc_tick_from_sec(double secf)
67{
68 return (vlc_tick_t)(CLOCK_FREQ * secf); /* TODO use llround ? */
69}
70#else /* !__cplusplus */
71static inline vlc_tick_t vlc_tick_from_seci(int64_t sec)
73 return CLOCK_FREQ * sec;
74}
75/* seconds in floating point */
76static inline vlc_tick_t vlc_tick_from_secf(double secf)
78 return (vlc_tick_t)(CLOCK_FREQ * secf); /* TODO use llround ? */
79}
80
81#define vlc_tick_from_sec(sec) _Generic((sec), \
82 double: vlc_tick_from_secf(sec), \
83 float: vlc_tick_from_secf(sec), \
84 default: vlc_tick_from_seci(sec) )
85#endif /* !__cplusplus */
86
87/* seconds in floating point from vlc_tick_t */
88static inline double secf_from_vlc_tick(vlc_tick_t vtk)
90 return (double)vtk / (double)CLOCK_FREQ;
91}
92
93static inline vlc_tick_t vlc_tick_rate_duration(float frame_rate)
95 return (vlc_tick_t)(CLOCK_FREQ / frame_rate);
96}
97
98/*
99 * samples<>vlc_tick_t
100 */
101static inline vlc_tick_t vlc_tick_from_samples(int64_t samples, unsigned samp_rate)
103 return CLOCK_FREQ * samples / samp_rate;
104}
105static inline int64_t samples_from_vlc_tick(vlc_tick_t t, unsigned samp_rate)
107 return t * samp_rate / CLOCK_FREQ;
108}
109
110
111static inline vlc_tick_t vlc_tick_from_frac(uint64_t num, uint64_t den)
113 lldiv_t d = lldiv (num, den);
114 return vlc_tick_from_sec( d.quot ) + vlc_tick_from_samples(d.rem, den);
115}
116
117
118/*
119 * vlc_tick_t <> milliseconds (ms) conversions
120 */
121#if (CLOCK_FREQ % 1000) == 0
122#define VLC_TICK_FROM_MS(ms) ((CLOCK_FREQ / INT64_C(1000)) * (ms))
123#define MS_FROM_VLC_TICK(vtk) ((vtk) / (CLOCK_FREQ / INT64_C(1000)))
124#elif (1000 % CLOCK_FREQ) == 0
125#define VLC_TICK_FROM_MS(ms) ((ms) / (INT64_C(1000) / CLOCK_FREQ))
126#define MS_FROM_VLC_TICK(vtk) ((vtk) * (INT64_C(1000) / CLOCK_FREQ))
127#else /* rounded overflowing conversion */
128#define VLC_TICK_FROM_MS(ms) (CLOCK_FREQ * (ms) / 1000)
129#define MS_FROM_VLC_TICK(vtk) ((vtk) * 1000 / CLOCK_FREQ)
130#endif /* CLOCK_FREQ / 1000 */
131
132
133/*
134 * vlc_tick_t <> microseconds (us) conversions
135 */
136#if (CLOCK_FREQ % 1000000) == 0
137#define VLC_TICK_FROM_US(us) ((CLOCK_FREQ / INT64_C(1000000)) * (us))
138#define US_FROM_VLC_TICK(vtk) ((vtk) / (CLOCK_FREQ / INT64_C(1000000)))
139#elif (1000000 % CLOCK_FREQ) == 0
140#define VLC_TICK_FROM_US(us) ((us) / (INT64_C(1000000) / CLOCK_FREQ))
141#define US_FROM_VLC_TICK(vtk) ((vtk) * (INT64_C(1000000) / CLOCK_FREQ))
142#else /* rounded overflowing conversion */
143#define VLC_TICK_FROM_US(us) (CLOCK_FREQ * (us) / INT64_C(1000000))
144#define US_FROM_VLC_TICK(vtk) ((vtk) * INT64_C(1000000) / CLOCK_FREQ)
145#endif /* CLOCK_FREQ / 1000000 */
146
147
148/*
149 * vlc_tick_t <> nanoseconds (ns) conversions
150 */
151#if (CLOCK_FREQ % 1000000000) == 0
152#define VLC_TICK_FROM_NS(ns) ((ns) * (CLOCK_FREQ / (INT64_C(1000000000))))
153#define NS_FROM_VLC_TICK(vtk) ((vtk) / (CLOCK_FREQ / (INT64_C(1000000000))))
154#elif (1000000000 % CLOCK_FREQ) == 0
155#define VLC_TICK_FROM_NS(ns) ((ns) / (INT64_C(1000000000) / CLOCK_FREQ))
156#define NS_FROM_VLC_TICK(vtk) ((vtk) * (INT64_C(1000000000) / CLOCK_FREQ))
157#else /* rounded overflowing conversion */
158#define VLC_TICK_FROM_NS(ns) (CLOCK_FREQ * (ns) / INT64_C(1000000000))
159#define NS_FROM_VLC_TICK(vtk) ((vtk) * INT64_C(1000000000) / CLOCK_FREQ)
160#endif /* CLOCK_FREQ / 1000000000 */
161
162
163/*
164 * msftime_t is a time with 100ns resolutions, typically used by Microsoft
165 */
166typedef int64_t msftime_t;
168#define MSFTIME_FROM_SEC(sec) (INT64_C(10000000) * (sec)) /* seconds in msftime_t */
169#define MSFTIME_FROM_MS(sec) (INT64_C(10000) * (sec)) /* milliseconds in msftime_t */
171#if (CLOCK_FREQ % 10000000) == 0
172#define VLC_TICK_FROM_MSFTIME(msft) ((msft) * (CLOCK_FREQ / INT64_C(10000000))
173#define MSFTIME_FROM_VLC_TICK(vtk) ((vtk) / (CLOCK_FREQ / INT64_C(10000000))
174#elif (10000000 % CLOCK_FREQ) == 0
175#define VLC_TICK_FROM_MSFTIME(msft) ((msft) / (INT64_C(10000000) / CLOCK_FREQ))
176#define MSFTIME_FROM_VLC_TICK(vtk) ((vtk) * (INT64_C(10000000) / CLOCK_FREQ))
177#else /* rounded overflowing conversion */
178#define VLC_TICK_FROM_MSFTIME(msft) (CLOCK_FREQ * (msft) / INT64_C(10000000))
179#define MSFTIME_FROM_VLC_TICK(vtk) ((vtk) * INT64_C(10000000) / CLOCK_FREQ)
180#endif /* CLOCK_FREQ / 10000000 */
181
182#define vlc_tick_from_timeval(tv) \
183 (vlc_tick_from_sec( (tv)->tv_sec ) + VLC_TICK_FROM_US( (tv)->tv_usec ))
184
185#define vlc_tick_from_timespec(tv) \
186 (vlc_tick_from_sec( (tv)->tv_sec ) + VLC_TICK_FROM_NS( (tv)->tv_nsec ))
187
188/**
189 * Converts a VLC tick to a POSIX time specification.
190 *
191 * \param ts [out] storage space for the time specification
192 * \param tick VLC tick
193 * \return @c ts
194 */
195VLC_API struct timespec *vlc_tick_to_timespec(struct timespec *restrict ts,
196 vlc_tick_t tick);
197
198/*****************************************************************************
199 * MSTRTIME_MAX_SIZE: maximum possible size of vlc_tick_to_str
200 *****************************************************************************
201 * This values is the maximal possible size of the string returned by the
202 * vlc_tick_to_str() function, including '-' and the final '\0'. It should be
203 * used to allocate the buffer.
204 *****************************************************************************/
205#define MSTRTIME_MAX_SIZE 22
207/*****************************************************************************
208 * Prototypes
209 *****************************************************************************/
210
211/**
212 * Convert seconds to a time in the format h:mm:ss.
213 *
214 * This function is provided for any interface function which need to print a
215 * time string in the format h:mm:ss
216 * date.
217 * \param ticks the time to be converted
218 * \param psz_buffer should be a buffer at least MSTRTIME_MAX_SIZE characters
219 * \return psz_buffer is returned so this can be used as printf parameter.
220 */
221VLC_API char * vlc_tick_to_str( char *psz_buffer, vlc_tick_t ticks );
222
223/**
224 * \defgroup date Timestamps, error-free
225 * These functions support generating timestamps without long term rounding
226 * errors due to sample rate conversions.
227 * \ingroup input
228 * @{
229 */
230/**
231 * Timestamps without long-term rounding errors
232 */
233struct date_t
238 uint32_t i_remainder;
240
241/**
242 * Initializes a date_t.
243 *
244 * \param date date to initialize [OUT]
245 * \param num divider (sample rate) numerator
246 * \param den divider (sample rate) denominator
247 */
248VLC_API void date_Init(date_t *restrict date, uint32_t num, uint32_t den);
250/**
251 * Changes the rate of a date_t.
252 *
253 * \param date date to change
254 * \param num divider (sample rate) numerator
255 * \param den divider (sample rate) denominator
256 */
257VLC_API void date_Change(date_t *restrict date, uint32_t num, uint32_t den);
259/**
260 * Sets the exact timestamp of a date_t.
261 *
262 * \param date date to set the timestamp into
263 * \param value date value
264 */
265static inline void date_Set(date_t *restrict date, vlc_tick_t value)
267 date->date = value;
268 date->i_remainder = 0;
269}
270
271/**
272 * Gets the current timestamp from a date_t.
273 *
274 * \param date date to fetch the timestamp from
275 * \return date value
276 */
277VLC_USED static inline vlc_tick_t date_Get(const date_t *restrict date)
279 return date->date;
280}
281
282/**
283 * Increments a date.
284 *
285 * Moves the date_t timestamp forward by a given number of samples.
286 *
287 * \param date date to move forward
288 * \param count number of samples
289 * \return timestamp value after incrementing
290 */
291VLC_API vlc_tick_t date_Increment(date_t *restrict date, uint32_t count);
293/**
294 * Decrements a date.
295 *
296 * Moves the date_t timestamp backward by a given number of samples.
297 *
298 * \param date date to move backward
299 * \param count number of samples
300 * \return date value
301 */
302VLC_API vlc_tick_t date_Decrement(date_t *restrict date, uint32_t count);
304/** @} */
305
306/**
307 * @return NTP 64-bits timestamp in host byte order.
308 */
309VLC_API uint64_t NTPtime64( void );
310#endif /* !__VLC_MTIME_ */
size_t count
Definition: core.c:403
#define VLC_USED
Definition: fourcc_gen.c:32
#define VLC_API
Definition: fourcc_gen.c:31
static void date_Set(date_t *restrict date, vlc_tick_t value)
Sets the exact timestamp of a date_t.
Definition: vlc_tick.h:266
vlc_tick_t date_Increment(date_t *restrict date, uint32_t count)
Increments a date.
void date_Change(date_t *restrict date, uint32_t num, uint32_t den)
Changes the rate of a date_t.
void date_Init(date_t *restrict date, uint32_t num, uint32_t den)
Initializes a date_t.
static vlc_tick_t date_Get(const date_t *restrict date)
Gets the current timestamp from a date_t.
Definition: vlc_tick.h:278
vlc_tick_t date_Decrement(date_t *restrict date, uint32_t count)
Decrements a date.
Timestamps without long-term rounding errors.
Definition: vlc_tick.h:235
uint32_t i_divider_num
Definition: vlc_tick.h:237
uint32_t i_remainder
Definition: vlc_tick.h:239
vlc_tick_t date
Definition: vlc_tick.h:236
uint32_t i_divider_den
Definition: vlc_tick.h:238
Definition: vlc_fixups.h:151
long long rem
Definition: vlc_fixups.h:153
long long quot
Definition: vlc_fixups.h:152
Definition: vlc_fixups.h:529
This file is a collection of common definitions and types.
#define CLOCK_FREQ
Definition: vlc_config.h:47
lldiv_t lldiv(long long, long long)
static vlc_tick_t vlc_tick_rate_duration(float frame_rate)
Definition: vlc_tick.h:94
uint64_t NTPtime64(void)
Definition: mtime.c:131
int64_t vlc_tick_t
High precision date or time interval.
Definition: vlc_tick.h:45
static vlc_tick_t vlc_tick_from_secf(double secf)
Definition: vlc_tick.h:77
char * vlc_tick_to_str(char *psz_buffer, vlc_tick_t ticks)
Convert seconds to a time in the format h:mm:ss.
Definition: mtime.c:42
struct timespec * vlc_tick_to_timespec(struct timespec *restrict ts, vlc_tick_t tick)
Converts a VLC tick to a POSIX time specification.
Definition: mtime.c:148
static vlc_tick_t vlc_tick_from_frac(uint64_t num, uint64_t den)
Definition: vlc_tick.h:112
static int64_t samples_from_vlc_tick(vlc_tick_t t, unsigned samp_rate)
Definition: vlc_tick.h:106
#define vlc_tick_from_sec(sec)
Definition: vlc_tick.h:82
static double secf_from_vlc_tick(vlc_tick_t vtk)
Definition: vlc_tick.h:89
static vlc_tick_t vlc_tick_from_samples(int64_t samples, unsigned samp_rate)
Definition: vlc_tick.h:102
int64_t msftime_t
Definition: vlc_tick.h:167
static vlc_tick_t vlc_tick_from_seci(int64_t sec)
Definition: vlc_tick.h:72