mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
stream: add pw_stream_get_nsec() to get current time
Make a method to get the current time to compare agains the pw_time-now field. This is currently CLOCK_MONOTONIC but make this into a method so that we can more easily change it later.
This commit is contained in:
parent
b3c7dda96a
commit
4c75d4f660
15 changed files with 52 additions and 55 deletions
|
|
@ -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;
|
snd_pcm_pipewire_t *pw = io->private_data;
|
||||||
uintptr_t seq1, seq2;
|
uintptr_t seq1, seq2;
|
||||||
int64_t elapsed = 0, delay, now, avail;
|
int64_t elapsed = 0, delay, now, avail;
|
||||||
struct timespec ts;
|
|
||||||
int64_t diff;
|
int64_t diff;
|
||||||
|
|
||||||
do {
|
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 ||
|
if (now != 0 && (io->state == SND_PCM_STATE_RUNNING ||
|
||||||
io->state == SND_PCM_STATE_DRAINING)) {
|
io->state == SND_PCM_STATE_DRAINING)) {
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
diff = pw_stream_get_nsec(pw->stream) - now;
|
||||||
diff = SPA_TIMESPEC_TO_NSEC(&ts) - now;
|
|
||||||
elapsed = (io->rate * diff) / SPA_NSEC_PER_SEC;
|
elapsed = (io->rate * diff) / SPA_NSEC_PER_SEC;
|
||||||
|
|
||||||
if (io->stream == SND_PCM_STREAM_PLAYBACK)
|
if (io->stream == SND_PCM_STREAM_PLAYBACK)
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,6 @@ struct object {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct impl {
|
struct impl {
|
||||||
struct timespec now;
|
|
||||||
|
|
||||||
struct pw_main_loop *loop;
|
struct pw_main_loop *loop;
|
||||||
struct pw_context *context;
|
struct pw_context *context;
|
||||||
|
|
||||||
|
|
@ -353,8 +351,6 @@ int main(int argc, char *argv[])
|
||||||
impl.loop = pw_main_loop_new(NULL);
|
impl.loop = pw_main_loop_new(NULL);
|
||||||
impl.context = pw_context_new(pw_main_loop_get_loop(impl.loop), NULL, 0);
|
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);
|
spa_list_init(&impl.device_list);
|
||||||
|
|
||||||
impl.core = pw_context_connect(impl.context, NULL, 0);
|
impl.core = pw_context_connect(impl.context, NULL, 0);
|
||||||
|
|
|
||||||
|
|
@ -90,9 +90,7 @@ static void on_process(void *userdata)
|
||||||
|
|
||||||
if ((h = spa_buffer_find_meta_data(buf, SPA_META_Header, sizeof(*h)))) {
|
if ((h = spa_buffer_find_meta_data(buf, SPA_META_Header, sizeof(*h)))) {
|
||||||
#if 0
|
#if 0
|
||||||
struct timespec now;
|
h->pts = pw_stream_get_nsec(data->stream));
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
|
||||||
h->pts = SPA_TIMESPEC_TO_NSEC(&now);
|
|
||||||
#else
|
#else
|
||||||
h->pts = -1;
|
h->pts = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -164,9 +164,7 @@ static void on_process(void *userdata)
|
||||||
|
|
||||||
if ((h = spa_buffer_find_meta_data(buf, SPA_META_Header, sizeof(*h)))) {
|
if ((h = spa_buffer_find_meta_data(buf, SPA_META_Header, sizeof(*h)))) {
|
||||||
#if 0
|
#if 0
|
||||||
struct timespec now;
|
h->pts = pw_stream_get_nsec(data->stream);
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
|
||||||
h->pts = SPA_TIMESPEC_TO_NSEC(&now);
|
|
||||||
#else
|
#else
|
||||||
h->pts = -1;
|
h->pts = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -94,9 +94,7 @@ static void on_process(void *userdata)
|
||||||
|
|
||||||
if ((h = spa_buffer_find_meta_data(buf, SPA_META_Header, sizeof(*h)))) {
|
if ((h = spa_buffer_find_meta_data(buf, SPA_META_Header, sizeof(*h)))) {
|
||||||
#if 0
|
#if 0
|
||||||
struct timespec now;
|
h->pts = pw_stream_get_nsec(data->stream);
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
|
||||||
h->pts = SPA_TIMESPEC_TO_NSEC(&now);
|
|
||||||
#else
|
#else
|
||||||
h->pts = -1;
|
h->pts = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -90,9 +90,7 @@ static void on_process(void *userdata)
|
||||||
|
|
||||||
if ((h = spa_buffer_find_meta_data(buf, SPA_META_Header, sizeof(*h)))) {
|
if ((h = spa_buffer_find_meta_data(buf, SPA_META_Header, sizeof(*h)))) {
|
||||||
#if 0
|
#if 0
|
||||||
struct timespec now;
|
h->pts = pw_stream_get_nsec(data->stream);
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
|
||||||
h->pts = SPA_TIMESPEC_TO_NSEC(&now);
|
|
||||||
#else
|
#else
|
||||||
h->pts = -1;
|
h->pts = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -31,27 +31,26 @@ gst_pipewire_clock_get_internal_time (GstClock * clock)
|
||||||
{
|
{
|
||||||
GstPipeWireClock *pclock = (GstPipeWireClock *) clock;
|
GstPipeWireClock *pclock = (GstPipeWireClock *) clock;
|
||||||
GstClockTime result;
|
GstClockTime result;
|
||||||
struct timespec ts;
|
uint64_t now;
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
now = pw_stream_get_nsec(pclock->stream);
|
||||||
#if 0
|
#if 0
|
||||||
struct pw_time t;
|
struct pw_time t;
|
||||||
if (pclock->stream == NULL ||
|
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)
|
t.rate.denom == 0)
|
||||||
return pclock->last_time;
|
return pclock->last_time;
|
||||||
|
|
||||||
result = gst_util_uint64_scale_int (t.ticks, GST_SECOND * t.rate.num, t.rate.denom);
|
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;
|
result += pclock->time_offset;
|
||||||
pclock->last_time = result;
|
pclock->last_time = result;
|
||||||
|
|
||||||
GST_DEBUG ("%"PRId64", %d/%d %"PRId64" %"PRId64,
|
GST_DEBUG ("%"PRId64", %d/%d %"PRId64" %"PRId64" %"PRId64,
|
||||||
t.ticks, t.rate.num, t.rate.denom, t.now, result);
|
t.ticks, t.rate.num, t.rate.denom, t.now, result, now);
|
||||||
#else
|
#else
|
||||||
result = SPA_TIMESPEC_TO_NSEC(&ts);
|
result = now + pclock->time_offset;
|
||||||
result += pclock->time_offset;
|
|
||||||
pclock->last_time = result;
|
pclock->last_time = result;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -679,13 +679,6 @@ static int create_filters(struct impl *impl)
|
||||||
return res;
|
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)
|
static void *ffado_process_thread(void *arg)
|
||||||
{
|
{
|
||||||
struct impl *impl = arg;
|
struct impl *impl = arg;
|
||||||
|
|
@ -696,7 +689,7 @@ static void *ffado_process_thread(void *arg)
|
||||||
ffado_wait_response response;
|
ffado_wait_response response;
|
||||||
|
|
||||||
response = ffado_streaming_wait(impl->dev);
|
response = ffado_streaming_wait(impl->dev);
|
||||||
nsec = get_time_ns();
|
nsec = pw_filter_get_nsec(impl->source.filter);
|
||||||
|
|
||||||
switch (response) {
|
switch (response) {
|
||||||
case ffado_wait_ok:
|
case ffado_wait_ok:
|
||||||
|
|
|
||||||
|
|
@ -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
|
static void
|
||||||
on_data_io(void *data, int fd, uint32_t mask)
|
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)
|
if (nframes == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nsec = get_time_ns();
|
nsec = pw_filter_get_nsec(impl->source.filter);
|
||||||
|
|
||||||
if (!impl->done) {
|
if (!impl->done) {
|
||||||
impl->pw_xrun++;
|
impl->pw_xrun++;
|
||||||
|
|
|
||||||
|
|
@ -298,11 +298,16 @@ static void clear_sdp_info(struct sdp_info *info)
|
||||||
spa_zero(*info);
|
spa_zero(*info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void session_touch(struct session *sess)
|
static uint64_t get_time_nsec(struct impl *impl)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &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)
|
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 impl *impl = data;
|
||||||
struct session *sess, *tmp;
|
struct session *sess, *tmp;
|
||||||
struct timespec ts;
|
|
||||||
uint64_t timestamp, interval;
|
uint64_t timestamp, interval;
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
timestamp = get_time_nsec(impl);
|
||||||
timestamp = SPA_TIMESPEC_TO_NSEC(&ts);
|
|
||||||
interval = impl->cleanup_interval * SPA_NSEC_PER_SEC;
|
interval = impl->cleanup_interval * SPA_NSEC_PER_SEC;
|
||||||
|
|
||||||
spa_list_for_each_safe(sess, tmp, &impl->sessions, link) {
|
spa_list_for_each_safe(sess, tmp, &impl->sessions, link) {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
static double get_time(struct impl *impl)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
uint64_t now;
|
||||||
struct spa_io_position *pos;
|
struct spa_io_position *pos;
|
||||||
double t;
|
double t;
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
now = pw_stream_get_nsec(impl->stream);
|
||||||
if ((pos = impl->io_position) != NULL) {
|
if ((pos = impl->io_position) != NULL) {
|
||||||
t = pos->clock.position / (double) pos->clock.rate.denom;
|
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 {
|
} else {
|
||||||
t = SPA_TIMESPEC_TO_NSEC(&ts);
|
t = now;
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1993,6 +1993,14 @@ int pw_filter_get_time(struct pw_filter *filter, struct pw_time *time)
|
||||||
return 0;
|
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
|
SPA_EXPORT
|
||||||
struct pw_buffer *pw_filter_dequeue_buffer(void *port_data)
|
struct pw_buffer *pw_filter_dequeue_buffer(void *port_data)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -215,6 +215,10 @@ pw_filter_update_params(struct pw_filter *filter, /**< a \ref pw_filter */
|
||||||
SPA_DEPRECATED
|
SPA_DEPRECATED
|
||||||
int pw_filter_get_time(struct pw_filter *filter, struct pw_time *time);
|
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
|
/** Get a buffer that can be filled for output ports or consumed
|
||||||
* for input ports. */
|
* for input ports. */
|
||||||
struct pw_buffer *pw_filter_dequeue_buffer(void *port_data);
|
struct pw_buffer *pw_filter_dequeue_buffer(void *port_data);
|
||||||
|
|
|
||||||
|
|
@ -2387,6 +2387,14 @@ int pw_stream_get_time_n(struct pw_stream *stream, struct pw_time *time, size_t
|
||||||
return 0;
|
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
|
static int
|
||||||
do_trigger_deprecated(struct spa_loop *loop,
|
do_trigger_deprecated(struct spa_loop *loop,
|
||||||
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
|
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
|
||||||
|
|
|
||||||
|
|
@ -229,9 +229,8 @@ struct pw_stream_control {
|
||||||
* to the current time like this:
|
* to the current time like this:
|
||||||
*
|
*
|
||||||
*\code{.c}
|
*\code{.c}
|
||||||
* struct timespec ts;
|
* uint64_t now = pw_stream_get_nsec(stream);
|
||||||
* clock_gettime(CLOCK_MONOTONIC, &ts);
|
* int64_t diff = now - pw_time.now;
|
||||||
* int64_t diff = SPA_TIMESPEC_TO_NSEC(&ts) - pw_time.now;
|
|
||||||
* int64_t elapsed = (pw_time.rate.denom * diff) / (pw_time.rate.num * SPA_NSEC_PER_SEC);
|
* int64_t elapsed = (pw_time.rate.denom * diff) / (pw_time.rate.num * SPA_NSEC_PER_SEC);
|
||||||
*\endcode
|
*\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 */
|
/** Query the time on the stream */
|
||||||
int pw_stream_get_time_n(struct pw_stream *stream, struct pw_time *time, size_t size);
|
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,
|
/** 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. */
|
* use pw_stream_get_time_n() to get the fields added since 0.3.50. */
|
||||||
SPA_DEPRECATED
|
SPA_DEPRECATED
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue