We need to adapt to communication latencies between us and the next server. Do this the simplest way possible by increasing the minimum latency whenever we've hit an underflow/overflow. Signed-off-by: Pierre Ossman <ossman at cendio.se> --- src/modules/module-tunnel-sink-new.c | 16 ++++++++++++++++ src/modules/module-tunnel-source-new.c | 15 +++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/modules/module-tunnel-sink-new.c b/src/modules/module-tunnel-sink-new.c index ebaa7f3..78c01cc 100644 --- a/src/modules/module-tunnel-sink-new.c +++ b/src/modules/module-tunnel-sink-new.c @@ -62,6 +62,7 @@ PA_MODULE_USAGE( /* FIXME: Default latency to use until we have proper rewind support. * Probably best to keep this in sync with DEFAULT_FIXED_LATENCY. */ #define DEFAULT_LATENCY_USEC (250*PA_USEC_PER_MSEC) +#define LATENCY_INC_MAX_STEP_USEC (10*PA_USEC_PER_MSEC) #define TUNNEL_THREAD_FAILED_MAINLOOP 1 static void stream_state_cb(pa_stream *stream, void *userdata); @@ -307,7 +308,22 @@ static void stream_moved_callback(pa_stream *stream, void *userdata) { /* called when the server experiences an underrun of our buffer */ static void stream_underflow_callback(pa_stream *stream, void *userdata) { + pa_usec_t old_min_latency, new_min_latency; + struct userdata *u = userdata; + pa_assert(u); + pa_log_info("Server signalled buffer underrun."); + + old_min_latency = u->sink->thread_info.min_latency; + new_min_latency = PA_MIN(old_min_latency * 2, old_min_latency + LATENCY_INC_MAX_STEP_USEC); + new_min_latency = PA_MIN(new_min_latency, u->sink->thread_info.max_latency); + + if (old_min_latency != new_min_latency) { + pa_log_info("Increasing minimal latency to %0.2f ms", + (double) new_min_latency / PA_USEC_PER_MSEC); + + pa_sink_set_latency_range_within_thread(u->sink, new_min_latency, u->sink->thread_info.max_latency); + } } /* called when the server experiences an overrun of our buffer */ diff --git a/src/modules/module-tunnel-source-new.c b/src/modules/module-tunnel-source-new.c index e46dda2..99149c3 100644 --- a/src/modules/module-tunnel-source-new.c +++ b/src/modules/module-tunnel-source-new.c @@ -59,6 +59,7 @@ PA_MODULE_USAGE( "cookie=<cookie file path>" ); +#define LATENCY_INC_MAX_STEP_USEC (10*PA_USEC_PER_MSEC) #define TUNNEL_THREAD_FAILED_MAINLOOP 1 static void stream_state_cb(pa_stream *stream, void *userdata); @@ -176,6 +177,7 @@ static void read_new_samples(struct userdata *u) { pa_memblock_unref_fixed(memchunk.memblock); } else { size_t bytes_to_generate = nbytes; + pa_usec_t old_min_latency, new_min_latency; /* we have a hole. generate silence */ memchunk = u->source->silence; @@ -190,6 +192,19 @@ static void read_new_samples(struct userdata *u) { } pa_memblock_unref(memchunk.memblock); + + /* there is no overflow callback so we're just going to have + * to assume that a hole means an overflow occured */ + old_min_latency = u->source->thread_info.min_latency; + new_min_latency = PA_MIN(old_min_latency * 2, old_min_latency + LATENCY_INC_MAX_STEP_USEC); + new_min_latency = PA_MIN(new_min_latency, u->source->thread_info.max_latency); + + if (old_min_latency != new_min_latency) { + pa_log_info("Increasing minimal latency to %0.2f ms", + (double) new_min_latency / PA_USEC_PER_MSEC); + + pa_source_set_latency_range_within_thread(u->source, new_min_latency, u->source->thread_info.max_latency); + } } pa_stream_drop(u->stream); -- 2.5.5