mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-17 04:45:47 +00:00
systemclock: Use clock_nanosleep for higher accuracy
The various wait implementation have a latency ranging from 50 to 500+ microseconds. While this is not a major issue when dealing with a low number of waits per second (for ex: video), it does introduce a non-negligeable jitter for synchronization of higher packet rate systems. The `clock_nanosleep` syscall does offer a lower-latency waiting system but is unfortunately blocking, so we don't want to use it in all scenarios nor for too long. This patch makes GstSystemClock use clock_nanosleep (if available) as such: * Any wait below 500us uses it * Any wait below 2ms will first use the regular waiting system and then clock_nanosleep # modified: gst/gstsystemclock.c Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/688>
This commit is contained in:
parent
b6df564251
commit
17feeb1bd6
2 changed files with 30 additions and 5 deletions
|
@ -961,11 +961,34 @@ gst_system_clock_id_wait_jitter_unlocked (GstClock * clock,
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
gboolean waitret;
|
gboolean waitret;
|
||||||
|
|
||||||
/* now wait on the entry, it either times out or the cond is signalled.
|
#ifdef HAVE_CLOCK_NANOSLEEP
|
||||||
* The status of the entry is BUSY only around the wait. */
|
if (diff <= 500 * GST_USECOND) {
|
||||||
waitret =
|
/* In order to provide more accurate wait, we will use BLOCKING
|
||||||
GST_SYSTEM_CLOCK_ENTRY_WAIT_UNTIL ((GstClockEntryImpl *) entry,
|
clock_nanosleep for any deadlines at or below 500us */
|
||||||
mono_ts * 1000 + diff);
|
struct timespec end;
|
||||||
|
GST_TIME_TO_TIMESPEC (entryt, end);
|
||||||
|
GST_SYSTEM_CLOCK_ENTRY_UNLOCK ((GstClockEntryImpl *) entry);
|
||||||
|
waitret =
|
||||||
|
clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &end, NULL) == 0;
|
||||||
|
GST_SYSTEM_CLOCK_ENTRY_LOCK ((GstClockEntryImpl *) entry);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (diff < 2 * GST_MSECOND) {
|
||||||
|
/* For any deadline within 2ms, we first use the regular non-blocking
|
||||||
|
wait by reducing the diff accordingly */
|
||||||
|
diff -= 500 * GST_USECOND;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* now wait on the entry, it either times out or the cond is signalled.
|
||||||
|
* The status of the entry is BUSY only around the wait. */
|
||||||
|
waitret =
|
||||||
|
GST_SYSTEM_CLOCK_ENTRY_WAIT_UNTIL ((GstClockEntryImpl *) entry,
|
||||||
|
mono_ts * 1000 + diff);
|
||||||
|
|
||||||
|
#ifdef HAVE_CLOCK_NANOSLEEP
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* get the new status, mark as DONE. We do this so that the unschedule
|
/* get the new status, mark as DONE. We do this so that the unschedule
|
||||||
* function knows when we left the poll and doesn't need to wakeup the
|
* function knows when we left the poll and doesn't need to wakeup the
|
||||||
|
@ -1004,6 +1027,7 @@ gst_system_clock_id_wait_jitter_unlocked (GstClock * clock,
|
||||||
|
|
||||||
/* reschedule if gst_cond_wait_until returned early or we have to reschedule after
|
/* reschedule if gst_cond_wait_until returned early or we have to reschedule after
|
||||||
* an unlock*/
|
* an unlock*/
|
||||||
|
mono_ts = g_get_monotonic_time ();
|
||||||
now = gst_clock_get_time (clock);
|
now = gst_clock_get_time (clock);
|
||||||
diff = GST_CLOCK_DIFF (now, entryt);
|
diff = GST_CLOCK_DIFF (now, entryt);
|
||||||
|
|
||||||
|
|
|
@ -236,6 +236,7 @@ check_functions = [
|
||||||
'pselect',
|
'pselect',
|
||||||
'getpagesize',
|
'getpagesize',
|
||||||
'clock_gettime',
|
'clock_gettime',
|
||||||
|
'clock_nanosleep',
|
||||||
'strnlen',
|
'strnlen',
|
||||||
# These are needed by libcheck
|
# These are needed by libcheck
|
||||||
'getline',
|
'getline',
|
||||||
|
|
Loading…
Reference in a new issue