mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
jack-tunnel: convert JACK time to MONOTONIC
JACK current_msec can be in MONOTONIC_RAW or MONOTONIC, depending on how JACK was compiled (but it's likely MONOTONIC_RAW). PipeWire requires the nsec field to be in MONOTONIC so take some time snapshots from both clocks and apply a translation. Also make sure we only get the nsec time from streams that exist. See #3886
This commit is contained in:
parent
f4e391dd41
commit
f2f60ee0ec
4 changed files with 50 additions and 2 deletions
|
|
@ -679,6 +679,18 @@ static int create_filters(struct impl *impl)
|
|||
return res;
|
||||
}
|
||||
|
||||
static inline uint64_t get_time_nsec(struct impl *impl)
|
||||
{
|
||||
uint64_t nsec;
|
||||
if (impl->sink.filter)
|
||||
nsec = pw_filter_get_nsec(impl->sink.filter);
|
||||
else if (impl->source.filter)
|
||||
nsec = pw_filter_get_nsec(impl->source.filter);
|
||||
else
|
||||
nsec = 0;
|
||||
return nsec;
|
||||
}
|
||||
|
||||
static void *ffado_process_thread(void *arg)
|
||||
{
|
||||
struct impl *impl = arg;
|
||||
|
|
@ -689,7 +701,7 @@ static void *ffado_process_thread(void *arg)
|
|||
ffado_wait_response response;
|
||||
|
||||
response = ffado_streaming_wait(impl->dev);
|
||||
nsec = pw_filter_get_nsec(impl->source.filter);
|
||||
nsec = get_time_nsec(impl);
|
||||
|
||||
switch (response) {
|
||||
case ffado_wait_ok:
|
||||
|
|
|
|||
|
|
@ -664,6 +664,18 @@ static int create_filters(struct impl *impl)
|
|||
return res;
|
||||
}
|
||||
|
||||
static inline uint64_t get_time_nsec(struct impl *impl)
|
||||
{
|
||||
uint64_t nsec;
|
||||
if (impl->sink.filter)
|
||||
nsec = pw_filter_get_nsec(impl->sink.filter);
|
||||
else if (impl->source.filter)
|
||||
nsec = pw_filter_get_nsec(impl->source.filter);
|
||||
else
|
||||
nsec = 0;
|
||||
return nsec;
|
||||
}
|
||||
|
||||
static void *jack_process_thread(void *arg)
|
||||
{
|
||||
struct impl *impl = arg;
|
||||
|
|
@ -693,11 +705,22 @@ static void *jack_process_thread(void *arg)
|
|||
jack_time_t next_usecs;
|
||||
float period_usecs;
|
||||
jack_position_t pos;
|
||||
uint64_t t1, t2, t3;
|
||||
int64_t d1;
|
||||
|
||||
jack.get_cycle_times(impl->client,
|
||||
¤t_frames, ¤t_usecs,
|
||||
&next_usecs, &period_usecs);
|
||||
|
||||
/* convert from JACK (likely MONOTONIC_RAW) to MONOTONIC */
|
||||
t1 = get_time_nsec(impl) / 1000;
|
||||
t2 = jack.get_time();
|
||||
t3 = get_time_nsec(impl) / 1000;
|
||||
d1 = t1 + (t3 - t1) / 2 - t2;
|
||||
|
||||
current_usecs += d1;
|
||||
next_usecs += d1;
|
||||
|
||||
c->nsec = current_usecs * SPA_NSEC_PER_USEC;
|
||||
c->rate = SPA_FRACTION(1, impl->samplerate);
|
||||
c->position = current_frames;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ struct weakjack {
|
|||
jack_nframes_t (*cycle_wait) (jack_client_t* client);
|
||||
void (*cycle_signal) (jack_client_t* client, int status);
|
||||
|
||||
jack_time_t (*get_time) (void);
|
||||
jack_nframes_t (*frame_time) (const jack_client_t *);
|
||||
int (*get_cycle_times) (const jack_client_t *client,
|
||||
jack_nframes_t *current_frames,
|
||||
|
|
@ -111,6 +112,7 @@ static inline int weakjack_load_by_path(struct weakjack *jack, const char *path)
|
|||
spa_zero(*jack);
|
||||
LOAD_SYM(cycle_wait);
|
||||
LOAD_SYM(cycle_signal);
|
||||
LOAD_SYM(get_time);
|
||||
LOAD_SYM(frame_time);
|
||||
LOAD_SYM(get_cycle_times);
|
||||
LOAD_SYM(transport_query);
|
||||
|
|
|
|||
|
|
@ -607,6 +607,17 @@ static int create_filters(struct impl *impl)
|
|||
return res;
|
||||
}
|
||||
|
||||
static inline uint64_t get_time_nsec(struct impl *impl)
|
||||
{
|
||||
uint64_t nsec;
|
||||
if (impl->sink.filter)
|
||||
nsec = pw_filter_get_nsec(impl->sink.filter);
|
||||
else if (impl->source.filter)
|
||||
nsec = pw_filter_get_nsec(impl->source.filter);
|
||||
else
|
||||
nsec = 0;
|
||||
return nsec;
|
||||
}
|
||||
|
||||
static void
|
||||
on_data_io(void *data, int fd, uint32_t mask)
|
||||
|
|
@ -627,7 +638,7 @@ on_data_io(void *data, int fd, uint32_t mask)
|
|||
if (nframes == 0)
|
||||
return;
|
||||
|
||||
nsec = pw_filter_get_nsec(impl->source.filter);
|
||||
nsec = get_time_nsec(impl);
|
||||
|
||||
if (!impl->done) {
|
||||
impl->pw_xrun++;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue