From 3aea95d518b502e60d26f3f8100af2c20a9004ba Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Oct 2008 20:45:03 +0200 Subject: Split latency paramters into "overall" and "immutable" latency --- src/common.c | 127 ++++++++++++++++++++++++++++++++++++++++++----------------- src/common.h | 5 ++- src/driver.h | 4 +- src/dso.c | 20 +++++----- src/null.c | 4 +- src/sydney.h | 9 +++-- 6 files changed, 113 insertions(+), 56 deletions(-) diff --git a/src/common.c b/src/common.c index 5a50f9e..0a7093d 100644 --- a/src/common.c +++ b/src/common.c @@ -50,7 +50,8 @@ */ -#define DEFAULT_LATENCY_USEC (2000000ULL) /* 2s */ +#define DEFAULT_BUFFER_LATENCY_USEC (2000000ULL) /* 2s */ +#define DEFAULT_IMMUTABLE_LATENCY_USEC (500000ULL) /* 500ms */ #define DEFAULT_PROCESS_TIME_USEC (20000ULL) /* 20ms */ static int stream_alloc(sa_stream **_s) { @@ -180,27 +181,50 @@ fail: return ret; } -static int fix_latency(sa_stream *s, size_t *latency_nbytes, size_t *process_time_nbytes) { +static int fix_latency( + sa_stream *s, + size_t *buffer_latency_nbytes, + size_t *immutable_latency_nbytes, + size_t *process_time_nbytes) { sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(latency_nbytes, SA_ERROR_INVALID); + sa_return_val_if_fail(buffer_latency_nbytes, SA_ERROR_INVALID); sa_return_val_if_fail(process_time_nbytes, SA_ERROR_INVALID); - if (*latency_nbytes <= 0) - *latency_nbytes = sa_stream_usec_to_bytes(s, DEFAULT_LATENCY_USEC, 0); + if (*buffer_latency_nbytes <= 0) + *buffer_latency_nbytes = sa_stream_usec_to_bytes(s, DEFAULT_BUFFER_LATENCY_USEC, 0); - if (*process_time_nbytes <= 0) { + if (immutable_latency_nbytes && *immutable_latency_nbytes <= 0) { size_t n, m; - n = sa_stream_frames_to_bytes(s, sa_stream_bytes_to_frames(s, *latency_nbytes, 1)/2); + n = sa_stream_frames_to_bytes(s, sa_stream_bytes_to_frames(s, *buffer_latency_nbytes, 0)/2); + m = sa_stream_usec_to_bytes(s, DEFAULT_IMMUTABLE_LATENCY_USEC, 0); + + *immutable_latency_nbytes = SA_MIN(n, m); + } + + if (*process_time_nbytes <= 0) { + size_t l, n, m; + + l = immutable_latency_nbytes ? *immutable_latency_nbytes : *buffer_latency_nbytes; + + n = sa_stream_frames_to_bytes(s, sa_stream_bytes_to_frames(s, l, 1)/2); m = sa_stream_usec_to_bytes(s, DEFAULT_PROCESS_TIME_USEC, 0); *process_time_nbytes = SA_MIN(n, m); } - sa_return_val_if_fail(*latency_nbytes > 0, SA_ERROR_INVALID); - sa_return_val_if_fail(*process_time_nbytes >= *latency_nbytes, SA_ERROR_INVALID); - sa_return_val_if_fail(sa_stream_frame_aligned(s, (int64_t) *latency_nbytes), SA_ERROR_INVALID); + if (immutable_latency_nbytes) { + sa_return_val_if_fail(*immutable_latency_nbytes > 0, SA_ERROR_INVALID); + sa_return_val_if_fail(*immutable_latency_nbytes <= *buffer_latency_nbytes, SA_ERROR_INVALID); + sa_return_val_if_fail(*process_time_nbytes <= *immutable_latency_nbytes, SA_ERROR_INVALID); + sa_return_val_if_fail(sa_stream_frame_aligned(s, (int64_t) *immutable_latency_nbytes), SA_ERROR_INVALID); + } + + sa_return_val_if_fail(*buffer_latency_nbytes > 0, SA_ERROR_INVALID); + sa_return_val_if_fail(*process_time_nbytes > 0, SA_ERROR_INVALID); + sa_return_val_if_fail(*process_time_nbytes <= *buffer_latency_nbytes, SA_ERROR_INVALID); + sa_return_val_if_fail(sa_stream_frame_aligned(s, (int64_t) *buffer_latency_nbytes), SA_ERROR_INVALID); sa_return_val_if_fail(sa_stream_frame_aligned(s, (int64_t) *process_time_nbytes), SA_ERROR_INVALID); return SA_SUCCESS; @@ -219,11 +243,11 @@ static int stream_open_unlocked(sa_stream *s) { return SA_SUCCESS; if (s->mode & SA_MODE_RDONLY) - if ((ret = fix_latency(s, &s->read_latency, &s->read_process_time)) < 0) + if ((ret = fix_latency(s, &s->read_overall_latency, NULL, &s->read_process_time)) < 0) return ret; if (s->mode & SA_MODE_WRONLY) - if ((ret = fix_latency(s, &s->write_latency, &s->write_process_time)) < 0) + if ((ret = fix_latency(s, &s->write_overall_latency, &s->write_immutable_latency, &s->write_process_time)) < 0) return ret; if ((ret = driver_open(s)) == SA_SUCCESS) @@ -276,22 +300,23 @@ int sa_stream_destroy(sa_stream *s) { return ret; } -int sa_stream_change_write_latency(sa_stream *s, size_t latency_nbytes, size_t process_time_nbytes) { +int sa_stream_change_write_latency(sa_stream *s, size_t overall_latency_nbytes, size_t immutable_latency_nbytes, size_t process_time_nbytes) { int ret; sa_return_val_if_fail(s, SA_ERROR_INVALID); sa_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); - if ((ret = fix_latency(s, &latency_nbytes, &process_time_nbytes)) < 0) + if ((ret = fix_latency(s, &overall_latency_nbytes, &immutable_latency_nbytes, &process_time_nbytes)) < 0) return ret; sa_mutex_lock(s->mutex); sa_return_val_if_fail_unlock(s->state != SA_STATE_DEAD, SA_ERROR_STATE, s->mutex); - ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_write_latency(s, &latency_nbytes, &process_time_nbytes); + ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_write_latency(s, &overall_latency_nbytes, &immutable_latency_nbytes, &process_time_nbytes); if (ret == SA_SUCCESS) { - s->write_latency = latency_nbytes; + s->write_overall_latency = overall_latency_nbytes; + s->write_immutable_latency = immutable_latency_nbytes; s->write_process_time = process_time_nbytes; } @@ -300,22 +325,22 @@ int sa_stream_change_write_latency(sa_stream *s, size_t latency_nbytes, size_t p return ret; } -int sa_stream_change_read_latency(sa_stream *s, size_t latency_nbytes, size_t process_time_nbytes) { +int sa_stream_change_read_latency(sa_stream *s, size_t overall_latency_nbytes, size_t process_time_nbytes) { int ret; sa_return_val_if_fail(s, SA_ERROR_INVALID); sa_return_val_if_fail(s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); - if ((ret = fix_latency(s, &latency_nbytes, &process_time_nbytes)) < 0) + if ((ret = fix_latency(s, &overall_latency_nbytes, NULL, &process_time_nbytes)) < 0) return ret; sa_mutex_lock(s->mutex); sa_return_val_if_fail_unlock(s->state != SA_STATE_DEAD, SA_ERROR_STATE, s->mutex); - ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_read_latency(s, &latency_nbytes, &process_time_nbytes); + ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_read_latency(s, &overall_latency_nbytes, &process_time_nbytes); if (ret == SA_SUCCESS) { - s->read_latency = latency_nbytes; + s->read_overall_latency = overall_latency_nbytes; s->read_process_time = process_time_nbytes; } @@ -748,8 +773,8 @@ int sa_stream_get_codec(sa_stream *s, char **codec) { return SA_SUCCESS; } -int sa_stream_get_write_latency(sa_stream *s, size_t *nbytes) { - size_t latency, process_time; +int sa_stream_get_write_overall_latency(sa_stream *s, size_t *nbytes) { + size_t overall_latency, immutable_latency, process_time; int ret; sa_return_val_if_fail(s, SA_ERROR_INVALID); @@ -758,16 +783,17 @@ int sa_stream_get_write_latency(sa_stream *s, size_t *nbytes) { sa_mutex_lock(s->mutex); - latency = s->write_latency; + overall_latency = s->write_overall_latency; + immutable_latency = s->write_immutable_latency; process_time = s->write_process_time; /* In case the latency is not fixated yet, we calculate what it * would be fixated to */ - if ((ret = fix_latency(s, &latency, &process_time)) < 0) + if ((ret = fix_latency(s, &overall_latency, &immutable_latency, &process_time)) < 0) goto fail; - *nbytes = latency; + *nbytes = overall_latency; ret = SA_SUCCESS; fail: @@ -775,8 +801,8 @@ fail: return ret; } -int sa_stream_get_read_latency(sa_stream *s, size_t *nbytes) { - size_t latency, process_time; +int sa_stream_get_read_overall_latency(sa_stream *s, size_t *nbytes) { + size_t overall_latency, process_time; int ret; sa_return_val_if_fail(s, SA_ERROR_INVALID); @@ -785,16 +811,44 @@ int sa_stream_get_read_latency(sa_stream *s, size_t *nbytes) { sa_mutex_lock(s->mutex); - latency = s->read_latency; + overall_latency = s->read_overall_latency; process_time = s->read_process_time; /* In case the latency is not fixated yet, we calculate what it * would be fixated to */ - if ((ret = fix_latency(s, &latency, &process_time)) < 0) + if ((ret = fix_latency(s, &overall_latency, NULL, &process_time)) < 0) + goto fail; + + *nbytes = overall_latency; + ret = SA_SUCCESS; + +fail: + sa_mutex_unlock(s->mutex); + return ret; +} + +int sa_stream_get_write_immutable_latency(sa_stream *s, size_t *nbytes) { + size_t overall_latency, immutable_latency, process_time; + int ret; + + sa_return_val_if_fail(s, SA_ERROR_INVALID); + sa_return_val_if_fail(nbytes, SA_ERROR_INVALID); + sa_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); + + sa_mutex_lock(s->mutex); + + overall_latency = s->write_overall_latency; + immutable_latency = s->write_immutable_latency; + process_time = s->write_process_time; + + /* In case the latency is not fixated yet, we calculate what it + * would be fixated to */ + + if ((ret = fix_latency(s, &overall_latency, &immutable_latency, &process_time)) < 0) goto fail; - *nbytes = latency; + *nbytes = immutable_latency; ret = SA_SUCCESS; fail: @@ -803,7 +857,7 @@ fail: } int sa_stream_get_write_process_time(sa_stream *s, size_t *nbytes) { - size_t latency, process_time; + size_t overall_latency, immutable_latency, process_time; int ret; sa_return_val_if_fail(s, SA_ERROR_INVALID); @@ -812,13 +866,14 @@ int sa_stream_get_write_process_time(sa_stream *s, size_t *nbytes) { sa_mutex_lock(s->mutex); - latency = s->write_latency; + overall_latency = s->write_overall_latency; + immutable_latency = s->write_immutable_latency; process_time = s->write_process_time; /* In case the latency is not fixated yet, we calculate what it * would be fixated to */ - if ((ret = fix_latency(s, &latency, &process_time)) < 0) + if ((ret = fix_latency(s, &overall_latency, &immutable_latency, &process_time)) < 0) goto fail; *nbytes = process_time; @@ -830,7 +885,7 @@ fail: } int sa_stream_get_read_process_time(sa_stream *s, size_t *nbytes) { - size_t latency, process_time; + size_t overall_latency, process_time; int ret; sa_return_val_if_fail(s, SA_ERROR_INVALID); @@ -839,13 +894,13 @@ int sa_stream_get_read_process_time(sa_stream *s, size_t *nbytes) { sa_mutex_lock(s->mutex); - latency = s->read_latency; + overall_latency = s->read_overall_latency; process_time = s->read_process_time; /* In case the latency is not fixated yet, we calculate what it * would be fixated to */ - if ((ret = fix_latency(s, &latency, &process_time)) < 0) + if ((ret = fix_latency(s, &overall_latency, NULL, &process_time)) < 0) goto fail; *nbytes = process_time; diff --git a/src/common.h b/src/common.h index a89c55f..972bfca 100644 --- a/src/common.h +++ b/src/common.h @@ -49,9 +49,10 @@ struct sa_stream { sa_proplist *props; - size_t read_latency; + size_t read_overall_latency; size_t read_process_time; - size_t write_latency; + size_t write_overall_latency; + size_t write_immutable_latency; size_t write_process_time; sa_xrun_mode_t xrun_mode; diff --git a/src/driver.h b/src/driver.h index c49d534..554635b 100644 --- a/src/driver.h +++ b/src/driver.h @@ -26,8 +26,8 @@ int driver_open(sa_stream *s); int driver_destroy(sa_stream *s); -int driver_change_write_latency(sa_stream *s, size_t *latency, size_t *process_time); -int driver_change_read_latency(sa_stream *s, size_t *latency, size_t *process_time); +int driver_change_write_latency(sa_stream *s, size_t *overall_latency_nbytes, size_t *immutable_latency_nbytes, size_t *process_time); +int driver_change_read_latency(sa_stream *s, size_t *overall_latency_nbytes, size_t *process_time); int driver_change_device(sa_stream *s, const char *device_name); int driver_change_read_volume(sa_stream *s, const int32_t vol[]); diff --git a/src/dso.c b/src/dso.c index 71c8fd7..3e8d585 100644 --- a/src/dso.c +++ b/src/dso.c @@ -39,8 +39,8 @@ struct private_dso { int (*driver_destroy)(sa_stream *s); - int (*driver_change_write_latency)(sa_stream *s, size_t *latency, size_t *process_time); - int (*driver_change_read_latency)(sa_stream *s, size_t *latency, size_t *process_time); + int (*driver_change_write_latency)(sa_stream *s, size_t *overall_latency, size_t *immutable_latency, size_t *process_time); + int (*driver_change_read_latency)(sa_stream *s, size_t *overall_latency, size_t *process_time); int (*driver_change_device)(sa_stream *s, const char *device); int (*driver_change_read_volume)(sa_stream *s, const int32_t vol[]); @@ -274,14 +274,14 @@ int driver_open(sa_stream *s) { if (!(p->driver_open = GET_FUNC_PTR(p->module, driver, "driver_open", int, (sa_stream*))) || !(p->driver_destroy = GET_FUNC_PTR(p->module, driver, "driver_destroy", int, (sa_stream*))) || - !(p->driver_change_write_latency = GET_FUNC_PTR(p->module, driver, "driver_change_write_latency", int, (sa_stream *s, size_t *latency, size_t *process_time))) || - !(p->driver_change_read_latency = GET_FUNC_PTR(p->module, driver, "driver_change_read_latency", int, (sa_stream *s, size_t *latency, size_t *process_time))) || + !(p->driver_change_write_latency = GET_FUNC_PTR(p->module, driver, "driver_change_write_latency", int, (sa_stream *, size_t *, size_t *, size_t *_time))) || + !(p->driver_change_read_latency = GET_FUNC_PTR(p->module, driver, "driver_change_read_latency", int, (sa_stream *, size_t *, size_t *_time))) || !(p->driver_change_device = GET_FUNC_PTR(p->module, driver, "driver_change_device", int, (sa_stream*, const char *))) || - !(p->driver_change_read_volume = GET_FUNC_PTR(p->module, driver, "driver_change_read_volume", int, (sa_stream *s, const int32_t vol[]))) || - !(p->driver_change_write_volume = GET_FUNC_PTR(p->module, driver, "driver_change_write_volume", int, (sa_stream *s, const int32_t vol[]))) || - !(p->driver_change_pcm_rate = GET_FUNC_PTR(p->module, driver, "driver_change_pcm_rate", int, (sa_stream *s, unsigned rate))) || + !(p->driver_change_read_volume = GET_FUNC_PTR(p->module, driver, "driver_change_read_volume", int, (sa_stream *s, const int32_t[]))) || + !(p->driver_change_write_volume = GET_FUNC_PTR(p->module, driver, "driver_change_write_volume", int, (sa_stream *s, const int32_t[]))) || + !(p->driver_change_pcm_rate = GET_FUNC_PTR(p->module, driver, "driver_change_pcm_rate", int, (sa_stream *, unsigned))) || !(p->driver_change_props = GET_FUNC_PTR(p->module, driver, "driver_change_props", int, (sa_stream *, sa_proplist *, sa_proplist *))) || - !(p->driver_get_state = GET_FUNC_PTR(p->module, driver, "driver_get_state", int, (sa_stream *s, sa_state_t *state))) || + !(p->driver_get_state = GET_FUNC_PTR(p->module, driver, "driver_get_state", int, (sa_stream *, sa_state_t *))) || !(p->driver_get_position = GET_FUNC_PTR(p->module, driver, "driver_get_position", int, (sa_stream *s, sa_position_t position, int64_t *pos))) || !(p->driver_wait = GET_FUNC_PTR(p->module, driver, "driver_wait", int, (sa_stream *s))) || !(p->driver_read = GET_FUNC_PTR(p->module, driver, "driver_read", int, (sa_stream *s, void *data, size_t nbytes))) || @@ -336,7 +336,7 @@ int driver_destroy(sa_stream *s) { return ret; } -int driver_change_write_latency(sa_stream *s, size_t *latency, size_t *process_time) { +int driver_change_write_latency(sa_stream *s, size_t *overall_latency, size_t *immutable_latency, size_t *process_time) { struct private_dso *p; sa_return_val_if_fail(s, SA_ERROR_INVALID); @@ -345,7 +345,7 @@ int driver_change_write_latency(sa_stream *s, size_t *latency, size_t *process_t p = PRIVATE_DSO(s); sa_return_val_if_fail(p->driver_change_write_latency, SA_ERROR_STATE); - return p->driver_change_write_latency(s, latency, process_time); + return p->driver_change_write_latency(s, overall_latency, immutable_latency, process_time); } int driver_change_read_latency(sa_stream *s, size_t *latency, size_t *process_time) { diff --git a/src/null.c b/src/null.c index 7948be6..287f96e 100644 --- a/src/null.c +++ b/src/null.c @@ -34,11 +34,11 @@ int driver_destroy(sa_stream *s) { return SA_ERROR_INVALID; } -int driver_change_write_latency(sa_stream *s, size_t *latency, size_t *process_time) { +int driver_change_write_latency(sa_stream *s, size_t *overall_latency, size_t *immutable_latency, size_t *process_time) { return SA_ERROR_INVALID; } -int driver_change_read_latency(sa_stream *s, size_t *latency, size_t *process_time) { +int driver_change_read_latency(sa_stream *s, size_t *overall_latency, size_t *process_time) { return SA_ERROR_INVALID; } diff --git a/src/sydney.h b/src/sydney.h index cdc006c..c718299 100644 --- a/src/sydney.h +++ b/src/sydney.h @@ -544,8 +544,8 @@ int sa_stream_open(sa_stream *s); int sa_stream_destroy(sa_stream *s); /* Buffer params */ -int sa_stream_change_write_latency(sa_stream *s, size_t latency_nbytes, size_t process_time_nbytes); -int sa_stream_change_read_latency(sa_stream *s, size_t latency_nbytes, size_t process_time_nbytes); +int sa_stream_change_write_latency(sa_stream *s, size_t overall_latency_nbytes, size_t immutable_latency_nbytes, size_t process_time_nbytes); +int sa_stream_change_read_latency(sa_stream *s, size_t overall_latency_nbytes, size_t process_time_nbytes); /** Set the mapping between channels and the loudspeakers */ int sa_stream_set_channel_map(sa_stream *s, const sa_channel_t map[], unsigned n); @@ -595,9 +595,10 @@ int sa_stream_get_pcm_format(sa_stream *s, sa_pcm_format_t *format); int sa_stream_get_pcm_rate(sa_stream *s, unsigned *rate); int sa_stream_get_pcm_nchannels(sa_stream *s, unsigned *nchannels); int sa_stream_get_user_data(sa_stream *s, void **value); -int sa_stream_get_write_latency(sa_stream *s, size_t *nbytes); +int sa_stream_get_write_overall_latency(sa_stream *s, size_t *nbytes); +int sa_stream_get_write_immutable_latency(sa_stream *s, size_t *nbytes); int sa_stream_get_write_process_time(sa_stream *s, size_t *nbytes); -int sa_stream_get_read_latency(sa_stream *s, size_t *nbytes); +int sa_stream_get_read_overall_latency(sa_stream *s, size_t *nbytes); int sa_stream_get_read_process_time(sa_stream *s, size_t *nbytes); int sa_stream_get_pcm_channel_map(sa_stream *s, sa_channel_t **map, unsigned *n); int sa_stream_get_xrun_mode(sa_stream *s, sa_xrun_mode_t *mode); -- cgit