modules: add ratelimit to xrun warnings in jack-tunnel

Take the current cycle times early and in all cases. We can use this to
get the current frame time for debugging purposes instead of the more
heavy jack_frame_time().

Rate limit the xrun warnings.
This commit is contained in:
Wim Taymans 2024-11-06 12:26:40 +01:00
parent 68877dcee7
commit ae0dd9195a

View file

@ -19,6 +19,7 @@
#include <spa/utils/result.h> #include <spa/utils/result.h>
#include <spa/utils/string.h> #include <spa/utils/string.h>
#include <spa/utils/json.h> #include <spa/utils/json.h>
#include <spa/utils/ratelimit.h>
#include <spa/debug/types.h> #include <spa/debug/types.h>
#include <spa/pod/builder.h> #include <spa/pod/builder.h>
#include <spa/param/audio/format-utils.h> #include <spa/param/audio/format-utils.h>
@ -185,6 +186,8 @@ struct impl {
struct spa_hook core_proxy_listener; struct spa_hook core_proxy_listener;
struct spa_hook core_listener; struct spa_hook core_listener;
struct spa_ratelimit rate_limit;
struct spa_io_position *position; struct spa_io_position *position;
struct stream source; struct stream source;
@ -193,7 +196,7 @@ struct impl {
uint32_t samplerate; uint32_t samplerate;
jack_client_t *client; jack_client_t *client;
jack_nframes_t frame_time; jack_nframes_t current_frames;
uint32_t pw_xrun; uint32_t pw_xrun;
uint32_t jack_xrun; uint32_t jack_xrun;
@ -366,7 +369,7 @@ static void sink_process(void *d, struct spa_io_position *position)
else else
do_volume(dst, src, &s->volume, i, n_samples); do_volume(dst, src, &s->volume, i, n_samples);
} }
pw_log_trace_fp("done %u %u", impl->frame_time, n_samples); pw_log_trace_fp("done %u %u", impl->current_frames, n_samples);
if (impl->mode & MODE_SINK) { if (impl->mode & MODE_SINK) {
impl->done = true; impl->done = true;
jack.cycle_signal(impl->client, 0); jack.cycle_signal(impl->client, 0);
@ -380,7 +383,7 @@ static void source_process(void *d, struct spa_io_position *position)
uint32_t i, n_samples = position->clock.duration; uint32_t i, n_samples = position->clock.duration;
if (impl->mode == MODE_SOURCE && !impl->triggered) { if (impl->mode == MODE_SOURCE && !impl->triggered) {
pw_log_trace_fp("done %u", impl->frame_time); pw_log_trace_fp("done %u", impl->current_frames);
impl->done = true; impl->done = true;
jack.cycle_signal(impl->client, 0); jack.cycle_signal(impl->client, 0);
return; return;
@ -698,35 +701,40 @@ static void *jack_process_thread(void *arg)
jack_nframes_t nframes; jack_nframes_t nframes;
while (true) { while (true) {
jack_nframes_t current_frames;
jack_time_t current_usecs;
jack_time_t next_usecs;
float period_usecs;
nframes = jack.cycle_wait (impl->client); nframes = jack.cycle_wait (impl->client);
jack.get_cycle_times(impl->client,
&current_frames, &current_usecs,
&next_usecs, &period_usecs);
impl->current_frames = current_frames;
source_running = impl->source.running; source_running = impl->source.running;
sink_running = impl->sink.running; sink_running = impl->sink.running;
impl->frame_time = jack.frame_time(impl->client);
pw_log_trace_fp("process %d %u %u %p %d", nframes, source_running, pw_log_trace_fp("process %d %u %u %p %d", nframes, source_running,
sink_running, impl->position, impl->frame_time); sink_running, impl->position, current_frames);
if (impl->new_xrun) { if (impl->new_xrun) {
pw_log_warn("Xrun JACK:%u PipeWire:%u", impl->jack_xrun, impl->pw_xrun); int suppressed;
if ((suppressed = spa_ratelimit_test(&impl->rate_limit, current_usecs)) >= 0) {
pw_log_warn("Xrun: current_frames:%u JACK:%u PipeWire:%u (%d suppressed)",
current_frames, impl->jack_xrun, impl->pw_xrun, suppressed);
}
impl->new_xrun = false; impl->new_xrun = false;
} }
if (impl->position) { if (impl->position) {
struct spa_io_clock *c = &impl->position->clock; struct spa_io_clock *c = &impl->position->clock;
jack_nframes_t current_frames;
jack_time_t current_usecs;
jack_time_t next_usecs;
float period_usecs;
jack_position_t pos; jack_position_t pos;
uint64_t t1, t2, t3; uint64_t t1, t2, t3;
int64_t d1; int64_t d1;
jack.get_cycle_times(impl->client,
&current_frames, &current_usecs,
&next_usecs, &period_usecs);
/* convert from JACK (likely MONOTONIC_RAW) to MONOTONIC */ /* convert from JACK (likely MONOTONIC_RAW) to MONOTONIC */
t1 = get_time_nsec(impl) / 1000; t1 = get_time_nsec(impl) / 1000;
t2 = jack.get_time(); t2 = jack.get_time();
@ -1062,6 +1070,9 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
impl->main_loop = pw_context_get_main_loop(context); impl->main_loop = pw_context_get_main_loop(context);
impl->system = impl->main_loop->system; impl->system = impl->main_loop->system;
impl->rate_limit.interval = 2 * SPA_USEC_PER_SEC;
impl->rate_limit.burst = 1;
impl->source.impl = impl; impl->source.impl = impl;
impl->source.direction = PW_DIRECTION_OUTPUT; impl->source.direction = PW_DIRECTION_OUTPUT;
impl->sink.impl = impl; impl->sink.impl = impl;