diff --git a/pipewire-alsa/alsa-plugins/pcm_pipewire.c b/pipewire-alsa/alsa-plugins/pcm_pipewire.c index 106c8a62e..b9797191c 100644 --- a/pipewire-alsa/alsa-plugins/pcm_pipewire.c +++ b/pipewire-alsa/alsa-plugins/pcm_pipewire.c @@ -200,7 +200,6 @@ static int snd_pcm_pipewire_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delay snd_pcm_pipewire_t *pw = io->private_data; uintptr_t seq1, seq2; int64_t elapsed = 0, delay, now, avail; - struct timespec ts; int64_t diff; do { @@ -218,8 +217,7 @@ static int snd_pcm_pipewire_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delay if (now != 0 && (io->state == SND_PCM_STATE_RUNNING || io->state == SND_PCM_STATE_DRAINING)) { - clock_gettime(CLOCK_MONOTONIC, &ts); - diff = SPA_TIMESPEC_TO_NSEC(&ts) - now; + diff = pw_stream_get_nsec(pw->stream) - now; elapsed = (io->rate * diff) / SPA_NSEC_PER_SEC; if (io->stream == SND_PCM_STREAM_PLAYBACK) diff --git a/src/examples/bluez-session.c b/src/examples/bluez-session.c index 888f6f656..81f9926a6 100644 --- a/src/examples/bluez-session.c +++ b/src/examples/bluez-session.c @@ -58,8 +58,6 @@ struct object { }; struct impl { - struct timespec now; - struct pw_main_loop *loop; struct pw_context *context; @@ -353,8 +351,6 @@ int main(int argc, char *argv[]) impl.loop = pw_main_loop_new(NULL); impl.context = pw_context_new(pw_main_loop_get_loop(impl.loop), NULL, 0); - clock_gettime(CLOCK_MONOTONIC, &impl.now); - spa_list_init(&impl.device_list); impl.core = pw_context_connect(impl.context, NULL, 0); diff --git a/src/examples/video-src-alloc.c b/src/examples/video-src-alloc.c index cb12a0de7..2b8e6f0a1 100644 --- a/src/examples/video-src-alloc.c +++ b/src/examples/video-src-alloc.c @@ -90,9 +90,7 @@ static void on_process(void *userdata) if ((h = spa_buffer_find_meta_data(buf, SPA_META_Header, sizeof(*h)))) { #if 0 - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - h->pts = SPA_TIMESPEC_TO_NSEC(&now); + h->pts = pw_stream_get_nsec(data->stream)); #else h->pts = -1; #endif diff --git a/src/examples/video-src-fixate.c b/src/examples/video-src-fixate.c index 1a0fe4bbd..a465a0bc7 100644 --- a/src/examples/video-src-fixate.c +++ b/src/examples/video-src-fixate.c @@ -164,9 +164,7 @@ static void on_process(void *userdata) if ((h = spa_buffer_find_meta_data(buf, SPA_META_Header, sizeof(*h)))) { #if 0 - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - h->pts = SPA_TIMESPEC_TO_NSEC(&now); + h->pts = pw_stream_get_nsec(data->stream); #else h->pts = -1; #endif diff --git a/src/examples/video-src-reneg.c b/src/examples/video-src-reneg.c index faaea76c1..212932213 100644 --- a/src/examples/video-src-reneg.c +++ b/src/examples/video-src-reneg.c @@ -94,9 +94,7 @@ static void on_process(void *userdata) if ((h = spa_buffer_find_meta_data(buf, SPA_META_Header, sizeof(*h)))) { #if 0 - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - h->pts = SPA_TIMESPEC_TO_NSEC(&now); + h->pts = pw_stream_get_nsec(data->stream); #else h->pts = -1; #endif diff --git a/src/examples/video-src.c b/src/examples/video-src.c index b1f8f3d0b..ef266a7af 100644 --- a/src/examples/video-src.c +++ b/src/examples/video-src.c @@ -90,9 +90,7 @@ static void on_process(void *userdata) if ((h = spa_buffer_find_meta_data(buf, SPA_META_Header, sizeof(*h)))) { #if 0 - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - h->pts = SPA_TIMESPEC_TO_NSEC(&now); + h->pts = pw_stream_get_nsec(data->stream); #else h->pts = -1; #endif diff --git a/src/gst/gstpipewireclock.c b/src/gst/gstpipewireclock.c index 0b024a651..d8e6da6a0 100644 --- a/src/gst/gstpipewireclock.c +++ b/src/gst/gstpipewireclock.c @@ -31,27 +31,26 @@ gst_pipewire_clock_get_internal_time (GstClock * clock) { GstPipeWireClock *pclock = (GstPipeWireClock *) clock; GstClockTime result; - struct timespec ts; + uint64_t now; - clock_gettime(CLOCK_MONOTONIC, &ts); + now = pw_stream_get_nsec(pclock->stream); #if 0 struct pw_time t; if (pclock->stream == NULL || - pw_stream_get_time (pclock->stream, &t) < 0 || + pw_stream_get_time_n (pclock->stream, &t, sizeof(t)) < 0 || t.rate.denom == 0) return pclock->last_time; result = gst_util_uint64_scale_int (t.ticks, GST_SECOND * t.rate.num, t.rate.denom); - result += SPA_TIMESPEC_TO_NSEC(&ts) - t.now; + result += now - t.now; result += pclock->time_offset; pclock->last_time = result; - GST_DEBUG ("%"PRId64", %d/%d %"PRId64" %"PRId64, - t.ticks, t.rate.num, t.rate.denom, t.now, result); + GST_DEBUG ("%"PRId64", %d/%d %"PRId64" %"PRId64" %"PRId64, + t.ticks, t.rate.num, t.rate.denom, t.now, result, now); #else - result = SPA_TIMESPEC_TO_NSEC(&ts); - result += pclock->time_offset; + result = now + pclock->time_offset; pclock->last_time = result; #endif diff --git a/src/modules/module-ffado-driver.c b/src/modules/module-ffado-driver.c index dc024d99f..5adcaf3f7 100644 --- a/src/modules/module-ffado-driver.c +++ b/src/modules/module-ffado-driver.c @@ -679,13 +679,6 @@ static int create_filters(struct impl *impl) return res; } -static inline uint64_t get_time_ns(void) -{ - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return SPA_TIMESPEC_TO_NSEC(&ts); -} - static void *ffado_process_thread(void *arg) { struct impl *impl = arg; @@ -696,7 +689,7 @@ static void *ffado_process_thread(void *arg) ffado_wait_response response; response = ffado_streaming_wait(impl->dev); - nsec = get_time_ns(); + nsec = pw_filter_get_nsec(impl->source.filter); switch (response) { case ffado_wait_ok: diff --git a/src/modules/module-netjack2-driver.c b/src/modules/module-netjack2-driver.c index 4753cc091..d70333b03 100644 --- a/src/modules/module-netjack2-driver.c +++ b/src/modules/module-netjack2-driver.c @@ -607,13 +607,6 @@ static int create_filters(struct impl *impl) } -static inline uint64_t get_time_ns(void) -{ - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return SPA_TIMESPEC_TO_NSEC(&ts); -} - static void on_data_io(void *data, int fd, uint32_t mask) { @@ -633,7 +626,7 @@ on_data_io(void *data, int fd, uint32_t mask) if (nframes == 0) return; - nsec = get_time_ns(); + nsec = pw_filter_get_nsec(impl->source.filter); if (!impl->done) { impl->pw_xrun++; diff --git a/src/modules/module-rtp-sap.c b/src/modules/module-rtp-sap.c index 545e1af9c..005303c31 100644 --- a/src/modules/module-rtp-sap.c +++ b/src/modules/module-rtp-sap.c @@ -298,11 +298,16 @@ static void clear_sdp_info(struct sdp_info *info) spa_zero(*info); } -static void session_touch(struct session *sess) +static uint64_t get_time_nsec(struct impl *impl) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - sess->timestamp = SPA_TIMESPEC_TO_NSEC(&ts); + return SPA_TIMESPEC_TO_NSEC(&ts); +} + +static void session_touch(struct session *sess) +{ + sess->timestamp = get_time_nsec(sess->impl); } static void session_free(struct session *sess) @@ -611,11 +616,9 @@ static void on_timer_event(void *data, uint64_t expirations) { struct impl *impl = data; struct session *sess, *tmp; - struct timespec ts; uint64_t timestamp, interval; - clock_gettime(CLOCK_MONOTONIC, &ts); - timestamp = SPA_TIMESPEC_TO_NSEC(&ts); + timestamp = get_time_nsec(impl); interval = impl->cleanup_interval * SPA_NSEC_PER_SEC; spa_list_for_each_safe(sess, tmp, &impl->sessions, link) { diff --git a/src/modules/module-rtp/midi.c b/src/modules/module-rtp/midi.c index d2ae3ede0..0122985f4 100644 --- a/src/modules/module-rtp/midi.c +++ b/src/modules/module-rtp/midi.c @@ -137,16 +137,16 @@ static int parse_journal(struct impl *impl, uint8_t *packet, uint16_t seq, uint3 static double get_time(struct impl *impl) { - struct timespec ts; + uint64_t now; struct spa_io_position *pos; double t; - clock_gettime(CLOCK_MONOTONIC, &ts); + now = pw_stream_get_nsec(impl->stream); if ((pos = impl->io_position) != NULL) { t = pos->clock.position / (double) pos->clock.rate.denom; - t += (SPA_TIMESPEC_TO_NSEC(&ts) - pos->clock.nsec) / (double)SPA_NSEC_PER_SEC; + t += (now - pos->clock.nsec) / (double)SPA_NSEC_PER_SEC; } else { - t = SPA_TIMESPEC_TO_NSEC(&ts); + t = now; } return t; } diff --git a/src/pipewire/filter.c b/src/pipewire/filter.c index 0264bf654..409766313 100644 --- a/src/pipewire/filter.c +++ b/src/pipewire/filter.c @@ -1993,6 +1993,14 @@ int pw_filter_get_time(struct pw_filter *filter, struct pw_time *time) return 0; } +SPA_EXPORT +uint64_t pw_filter_get_nsec(struct pw_filter *filter) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return SPA_TIMESPEC_TO_NSEC(&ts); +} + SPA_EXPORT struct pw_buffer *pw_filter_dequeue_buffer(void *port_data) { diff --git a/src/pipewire/filter.h b/src/pipewire/filter.h index b0ea4a2ac..3a619e80a 100644 --- a/src/pipewire/filter.h +++ b/src/pipewire/filter.h @@ -215,6 +215,10 @@ pw_filter_update_params(struct pw_filter *filter, /**< a \ref pw_filter */ SPA_DEPRECATED int pw_filter_get_time(struct pw_filter *filter, struct pw_time *time); +/** Get the current time in nanoseconds. This value can be compared with + * the nsec value in the spa_io_position. Since 1.0.4 */ +uint64_t pw_filter_get_nsec(struct pw_filter *filter); + /** Get a buffer that can be filled for output ports or consumed * for input ports. */ struct pw_buffer *pw_filter_dequeue_buffer(void *port_data); diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index fc7b9b958..ed63f0f7c 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -2387,6 +2387,14 @@ int pw_stream_get_time_n(struct pw_stream *stream, struct pw_time *time, size_t return 0; } +SPA_EXPORT +uint64_t pw_stream_get_nsec(struct pw_stream *stream) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return SPA_TIMESPEC_TO_NSEC(&ts); +} + static int do_trigger_deprecated(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data) diff --git a/src/pipewire/stream.h b/src/pipewire/stream.h index dd172d74e..b1524d93b 100644 --- a/src/pipewire/stream.h +++ b/src/pipewire/stream.h @@ -229,9 +229,8 @@ struct pw_stream_control { * to the current time like this: * *\code{.c} - * struct timespec ts; - * clock_gettime(CLOCK_MONOTONIC, &ts); - * int64_t diff = SPA_TIMESPEC_TO_NSEC(&ts) - pw_time.now; + * uint64_t now = pw_stream_get_nsec(stream); + * int64_t diff = now - pw_time.now; * int64_t elapsed = (pw_time.rate.denom * diff) / (pw_time.rate.num * SPA_NSEC_PER_SEC); *\endcode * @@ -497,6 +496,10 @@ int pw_stream_set_control(struct pw_stream *stream, uint32_t id, uint32_t n_valu /** Query the time on the stream */ int pw_stream_get_time_n(struct pw_stream *stream, struct pw_time *time, size_t size); +/** Get the current time in nanoseconds. This value can be compared with + * the pw_time_now value. Since 1.0.4 */ +uint64_t pw_stream_get_nsec(struct pw_stream *stream); + /** Query the time on the stream, deprecated since 0.3.50, * use pw_stream_get_time_n() to get the fields added since 0.3.50. */ SPA_DEPRECATED