VLC 4.0.0-dev
Loading...
Searching...
No Matches
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#include <vlc_config.h>
35#include <vlc_common.h>
36
37/**
38 * High precision date or time interval
39 *
40 * Store a high precision date or time interval. The maximum precision is the
41 * microsecond, and a 64 bits integer is used to avoid overflows (maximum
42 * time interval is then 292271 years, which should be long enough for any
43 * video). Dates are stored as microseconds since a common date (usually the
44 * epoch). Note that date and time intervals can be manipulated using regular
45 * arithmetic operators, and that no special functions are required.
46 */
47typedef int64_t vlc_tick_t;
49#define VLC_TICK_MIN INT64_MIN
50#define VLC_TICK_MAX INT64_MAX
52/*
53 * vlc_tick_t <> seconds (sec) conversions
54 */
55#define VLC_TICK_FROM_SEC(sec) (CLOCK_FREQ * (sec))
56#define SEC_FROM_VLC_TICK(vtk) ((vtk) / CLOCK_FREQ)
58#ifdef __cplusplus
59#include <type_traits>
60
61template <typename T>
62static inline auto vlc_tick_from_sec(T sec)
63 -> typename std::enable_if<std::is_integral<T>::value, vlc_tick_t>::type
64{
65 return CLOCK_FREQ * sec;
66}
67
68/* seconds in floating point */
69static inline vlc_tick_t vlc_tick_from_sec(double secf)
70{
71 return (vlc_tick_t)(CLOCK_FREQ * secf); /* TODO use llround ? */
72}
73#else /* !__cplusplus */
74static inline vlc_tick_t vlc_tick_from_seci(int64_t sec)
76 return CLOCK_FREQ * sec;
77}
78/* seconds in floating point */
79static inline vlc_tick_t vlc_tick_from_secf(double secf)
81 return (vlc_tick_t)(CLOCK_FREQ * secf); /* TODO use llround ? */
82}
83
84#define vlc_tick_from_sec(sec) _Generic((sec), \
85 double: vlc_tick_from_secf(sec), \
86 float: vlc_tick_from_secf(sec), \
87 default: vlc_tick_from_seci(sec) )
88#endif /* !__cplusplus */
89
90/* seconds in floating point from vlc_tick_t */
91static inline double secf_from_vlc_tick(vlc_tick_t vtk)
93 return (double)vtk / (double)CLOCK_FREQ;
94}
95
96static inline vlc_tick_t vlc_tick_rate_duration(float frame_rate)
98 return (vlc_tick_t)(CLOCK_FREQ / frame_rate);
99}
100
101/*
102 * samples<>vlc_tick_t
103 */
104static inline vlc_tick_t vlc_tick_from_samples(int64_t samples, unsigned samp_rate)
106 return CLOCK_FREQ * samples / samp_rate;
107}
108static inline int64_t samples_from_vlc_tick(vlc_tick_t t, unsigned samp_rate)
110 return t * samp_rate / CLOCK_FREQ;
111}
112
113
114static inline vlc_tick_t vlc_tick_from_frac(uint64_t num, uint64_t den)
116 lldiv_t d = lldiv (num, den);
117 return vlc_tick_from_sec( d.quot ) + vlc_tick_from_samples(d.rem, den);
118}
119
120
121/*
122 * vlc_tick_t <> milliseconds (ms) conversions
123 */
124#if (CLOCK_FREQ % 1000) == 0
125#define VLC_TICK_FROM_MS(ms) ((CLOCK_FREQ / INT64_C(1000)) * (ms))
126#define MS_FROM_VLC_TICK(vtk) ((vtk) / (CLOCK_FREQ / INT64_C(1000)))
127#elif (1000 % CLOCK_FREQ) == 0
128#define VLC_TICK_FROM_MS(ms) ((ms) / (INT64_C(1000) / CLOCK_FREQ))
129#define MS_FROM_VLC_TICK(vtk) ((vtk) * (INT64_C(1000) / CLOCK_FREQ))
130#else /* rounded overflowing conversion */
131#define VLC_TICK_FROM_MS(ms) (CLOCK_FREQ * (ms) / 1000)
132#define MS_FROM_VLC_TICK(vtk) ((vtk) * 1000 / CLOCK_FREQ)
133#endif /* CLOCK_FREQ / 1000 */
134
135
136/*
137 * vlc_tick_t <> microseconds (us) conversions
138 */
139#if (CLOCK_FREQ % 1000000) == 0
140#define VLC_TICK_FROM_US(us) ((CLOCK_FREQ / INT64_C(1000000)) * (us))
141#define US_FROM_VLC_TICK(vtk) ((vtk) / (CLOCK_FREQ / INT64_C(1000000)))
142#elif (1000000 % CLOCK_FREQ) == 0
143#define VLC_TICK_FROM_US(us) ((us) / (INT64_C(1000000) / CLOCK_FREQ))
144#define US_FROM_VLC_TICK(vtk) ((vtk) * (INT64_C(1000000) / CLOCK_FREQ))
145#else /* rounded overflowing conversion */
146#define VLC_TICK_FROM_US(us) (CLOCK_FREQ * (us) / INT64_C(1000000))
147#define US_FROM_VLC_TICK(vtk) ((vtk) * INT64_C(1000000) / CLOCK_FREQ)
148#endif /* CLOCK_FREQ / 1000000 */
149
150
151/*
152 * vlc_tick_t <> nanoseconds (ns) conversions
153 */
154#if (CLOCK_FREQ % 1000000000) == 0
155#define VLC_TICK_FROM_NS(ns) ((ns) * (CLOCK_FREQ / (INT64_C(1000000000))))
156#define NS_FROM_VLC_TICK(vtk) ((vtk) / (CLOCK_FREQ / (INT64_C(1000000000))))
157#elif (1000000000 % CLOCK_FREQ) == 0
158#define VLC_TICK_FROM_NS(ns) ((ns) / (INT64_C(1000000000) / CLOCK_FREQ))
159#define NS_FROM_VLC_TICK(vtk) ((vtk) * (INT64_C(1000000000) / CLOCK_FREQ))
160#else /* rounded overflowing conversion */
161#define VLC_TICK_FROM_NS(ns) (CLOCK_FREQ * (ns) / INT64_C(1000000000))
162#define NS_FROM_VLC_TICK(vtk) ((vtk) * INT64_C(1000000000) / CLOCK_FREQ)
163#endif /* CLOCK_FREQ / 1000000000 */
164
165
166/*
167 * msftime_t is a time with 100ns resolutions, typically used by Microsoft
168 */
169typedef int64_t msftime_t;
171#define MSFTIME_FROM_SEC(sec) (INT64_C(10000000) * (sec)) /* seconds in msftime_t */
172#define MSFTIME_FROM_MS(sec) (INT64_C(10000) * (sec)) /* milliseconds in msftime_t */
174#if (CLOCK_FREQ % 10000000) == 0
175#define VLC_TICK_FROM_MSFTIME(msft) ((msft) * (CLOCK_FREQ / INT64_C(10000000))
176#define MSFTIME_FROM_VLC_TICK(vtk) ((vtk) / (CLOCK_FREQ / INT64_C(10000000))
177#elif (10000000 % CLOCK_FREQ) == 0
178#define VLC_TICK_FROM_MSFTIME(msft) ((msft) / (INT64_C(10000000) / CLOCK_FREQ))
179#define MSFTIME_FROM_VLC_TICK(vtk) ((vtk) * (INT64_C(10000000) / CLOCK_FREQ))
180#else /* rounded overflowing conversion */
181#define VLC_TICK_FROM_MSFTIME(msft) (CLOCK_FREQ * (msft) / INT64_C(10000000))
182#define MSFTIME_FROM_VLC_TICK(vtk) ((vtk) * INT64_C(10000000) / CLOCK_FREQ)
183#endif /* CLOCK_FREQ / 10000000 */
184
185#define vlc_tick_from_timeval(tv) \
186 (vlc_tick_from_sec( (tv)->tv_sec ) + VLC_TICK_FROM_US( (tv)->tv_usec ))
187
188#define vlc_tick_from_timespec(tv) \
189 (vlc_tick_from_sec( (tv)->tv_sec ) + VLC_TICK_FROM_NS( (tv)->tv_nsec ))
190
191/**
192 * Converts a VLC tick to a POSIX time specification.
193 *
194 * \param ts [out] storage space for the time specification
195 * \param tick VLC tick
196 * \return @c ts
197 */
198VLC_API struct timespec *vlc_tick_to_timespec(struct timespec *restrict ts,
199 vlc_tick_t tick);
200
201/*****************************************************************************
202 * MSTRTIME_MAX_SIZE: maximum possible size of vlc_tick_to_str
203 *****************************************************************************
204 * This values is the maximal possible size of the string returned by the
205 * vlc_tick_to_str() function, including '-' and the final '\0'. It should be
206 * used to allocate the buffer.
207 *****************************************************************************/
208#define MSTRTIME_MAX_SIZE 22
210/*****************************************************************************
211 * Prototypes
212 *****************************************************************************/
213
214/**
215 * Convert seconds to a time in the format h:mm:ss.
216 *
217 * This function is provided for any interface function which need to print a
218 * time string in the format h:mm:ss
219 * date.
220 * \param ticks the time to be converted
221 * \param psz_buffer should be a buffer at least MSTRTIME_MAX_SIZE characters
222 * \return psz_buffer is returned so this can be used as printf parameter.
223 */
224VLC_API char * vlc_tick_to_str( char *psz_buffer, vlc_tick_t ticks );
225
226/**
227 * \defgroup date Timestamps, error-free
228 * These functions support generating timestamps without long term rounding
229 * errors due to sample rate conversions.
230 * \ingroup input
231 * @{
232 */
233/**
234 * Timestamps without long-term rounding errors
235 */
236struct date_t
241 uint32_t i_remainder;
243
244/**
245 * Initializes a date_t.
246 *
247 * \param date date to initialize [OUT]
248 * \param num divider (sample rate) numerator
249 * \param den divider (sample rate) denominator
250 */
251VLC_API void date_Init(date_t *restrict date, uint32_t num, uint32_t den);
253/**
254 * Changes the rate of a date_t.
255 *
256 * \param date date to change
257 * \param num divider (sample rate) numerator
258 * \param den divider (sample rate) denominator
259 */
260VLC_API void date_Change(date_t *restrict date, uint32_t num, uint32_t den);
262/**
263 * Sets the exact timestamp of a date_t.
264 *
265 * \param date date to set the timestamp into
266 * \param value date value
267 */
268static inline void date_Set(date_t *restrict date, vlc_tick_t value)
270 date->date = value;
271 date->i_remainder = 0;
272}
273
274/**
275 * Gets the current timestamp from a date_t.
276 *
277 * \param date date to fetch the timestamp from
278 * \return date value
279 */
280VLC_USED static inline vlc_tick_t date_Get(const date_t *restrict date)
282 return date->date;
283}
284
285/**
286 * Increments a date.
287 *
288 * Moves the date_t timestamp forward by a given number of samples.
289 *
290 * \param date date to move forward
291 * \param count number of samples
292 * \return timestamp value after incrementing
293 */
294VLC_API vlc_tick_t date_Increment(date_t *restrict date, uint32_t count);
296/**
297 * Decrements a date.
298 *
299 * Moves the date_t timestamp backward by a given number of samples.
300 *
301 * \param date date to move backward
302 * \param count number of samples
303 * \return date value
304 */
305VLC_API vlc_tick_t date_Decrement(date_t *restrict date, uint32_t count);
307/** @} */
308
309/**
310 * Gets the current wallclock time as 64-bit NTP timestamp.
311 *
312 * \return NTP 64-bits timestamp in host byte order
313 */
314VLC_API uint64_t vlc_ntp_time( void );
315#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:269
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:281
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:238
uint32_t i_divider_num
Definition vlc_tick.h:240
uint32_t i_remainder
Definition vlc_tick.h:242
vlc_tick_t date
Definition vlc_tick.h:239
uint32_t i_divider_den
Definition vlc_tick.h:241
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:532
This file is a collection of common definitions and types.
This file defines of values used in interface, vout, aout and vlc core functions.
#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:97
int64_t vlc_tick_t
High precision date or time interval.
Definition vlc_tick.h:48
static vlc_tick_t vlc_tick_from_secf(double secf)
Definition vlc_tick.h:80
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:115
static int64_t samples_from_vlc_tick(vlc_tick_t t, unsigned samp_rate)
Definition vlc_tick.h:109
#define vlc_tick_from_sec(sec)
Definition vlc_tick.h:85
static double secf_from_vlc_tick(vlc_tick_t vtk)
Definition vlc_tick.h:92
static vlc_tick_t vlc_tick_from_samples(int64_t samples, unsigned samp_rate)
Definition vlc_tick.h:105
int64_t msftime_t
Definition vlc_tick.h:170
static vlc_tick_t vlc_tick_from_seci(int64_t sec)
Definition vlc_tick.h:75
uint64_t vlc_ntp_time(void)
Gets the current wallclock time as 64-bit NTP timestamp.
Definition mtime.c:131