mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-17 08:56:49 -05:00
alsa: keep track of input and output latency
track and report both input and output latency.
This commit is contained in:
parent
ed9560fb03
commit
8cf5927e95
5 changed files with 49 additions and 13 deletions
|
|
@ -44,7 +44,7 @@ struct spa_latency_info {
|
||||||
uint64_t max_ns;
|
uint64_t max_ns;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SPA_LATENCY_INFO(dir) (struct spa_latency_info) { .direction = (dir) }
|
#define SPA_LATENCY_INFO(dir,...) (struct spa_latency_info) { .direction = (dir), ## __VA_ARGS__ }
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
spa_latency_info_compare(const struct spa_latency_info *a, struct spa_latency_info *b)
|
spa_latency_info_compare(const struct spa_latency_info *a, struct spa_latency_info *b)
|
||||||
|
|
|
||||||
|
|
@ -459,7 +459,10 @@ impl_node_port_enum_params(void *object, int seq,
|
||||||
case SPA_PARAM_Latency:
|
case SPA_PARAM_Latency:
|
||||||
switch (result.index) {
|
switch (result.index) {
|
||||||
case 0:
|
case 0:
|
||||||
param = spa_latency_build(&b, id, &this->latency);
|
param = spa_latency_build(&b, id, &this->latency[SPA_DIRECTION_INPUT]);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
param = spa_latency_build(&b, id, &this->latency[SPA_DIRECTION_OUTPUT]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -564,8 +567,19 @@ impl_node_port_set_param(void *object,
|
||||||
res = port_set_format(this, direction, port_id, flags, param);
|
res = port_set_format(this, direction, port_id, flags, param);
|
||||||
break;
|
break;
|
||||||
case SPA_PARAM_Latency:
|
case SPA_PARAM_Latency:
|
||||||
res = 0;
|
{
|
||||||
|
struct spa_latency_info info;
|
||||||
|
if ((res = spa_latency_parse(param, &info)) < 0)
|
||||||
|
return res;
|
||||||
|
if (direction == info.direction)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
this->latency[info.direction] = info;
|
||||||
|
this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||||
|
this->port_params[IDX_Latency].flags ^= SPA_PARAM_INFO_SERIAL;
|
||||||
|
emit_port_info(this, false);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
res = -ENOENT;
|
res = -ENOENT;
|
||||||
break;
|
break;
|
||||||
|
|
@ -779,9 +793,12 @@ impl_init(const struct spa_handle_factory *factory,
|
||||||
spa_hook_list_init(&this->hooks);
|
spa_hook_list_init(&this->hooks);
|
||||||
|
|
||||||
this->stream = SND_PCM_STREAM_PLAYBACK;
|
this->stream = SND_PCM_STREAM_PLAYBACK;
|
||||||
this->latency = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT);
|
this->port_direction = SPA_DIRECTION_INPUT;
|
||||||
this->latency.min_quantum = 1.0f;
|
this->latency[this->port_direction] = SPA_LATENCY_INFO(
|
||||||
this->latency.max_quantum = 1.0f;
|
this->port_direction,
|
||||||
|
.min_quantum = 1.0f,
|
||||||
|
.max_quantum = 1.0f);
|
||||||
|
this->latency[SPA_DIRECTION_OUTPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT);
|
||||||
|
|
||||||
this->info_all = SPA_NODE_CHANGE_MASK_FLAGS |
|
this->info_all = SPA_NODE_CHANGE_MASK_FLAGS |
|
||||||
SPA_NODE_CHANGE_MASK_PROPS |
|
SPA_NODE_CHANGE_MASK_PROPS |
|
||||||
|
|
|
||||||
|
|
@ -457,7 +457,10 @@ impl_node_port_enum_params(void *object, int seq,
|
||||||
case SPA_PARAM_Latency:
|
case SPA_PARAM_Latency:
|
||||||
switch (result.index) {
|
switch (result.index) {
|
||||||
case 0:
|
case 0:
|
||||||
param = spa_latency_build(&b, id, &this->latency);
|
param = spa_latency_build(&b, id, &this->latency[SPA_DIRECTION_INPUT]);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
param = spa_latency_build(&b, id, &this->latency[SPA_DIRECTION_OUTPUT]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -561,8 +564,19 @@ impl_node_port_set_param(void *object,
|
||||||
res = port_set_format(this, direction, port_id, flags, param);
|
res = port_set_format(this, direction, port_id, flags, param);
|
||||||
break;
|
break;
|
||||||
case SPA_PARAM_Latency:
|
case SPA_PARAM_Latency:
|
||||||
res = 0;
|
{
|
||||||
|
struct spa_latency_info info;
|
||||||
|
if ((res = spa_latency_parse(param, &info)) < 0)
|
||||||
|
return res;
|
||||||
|
if (direction == info.direction)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
this->latency[info.direction] = info;
|
||||||
|
this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||||
|
this->port_params[IDX_Latency].flags ^= SPA_PARAM_INFO_SERIAL;
|
||||||
|
emit_port_info(this, false);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
res = -ENOENT;
|
res = -ENOENT;
|
||||||
break;
|
break;
|
||||||
|
|
@ -792,9 +806,12 @@ impl_init(const struct spa_handle_factory *factory,
|
||||||
|
|
||||||
spa_hook_list_init(&this->hooks);
|
spa_hook_list_init(&this->hooks);
|
||||||
this->stream = SND_PCM_STREAM_CAPTURE;
|
this->stream = SND_PCM_STREAM_CAPTURE;
|
||||||
this->latency = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT);
|
this->port_direction = SPA_DIRECTION_OUTPUT;
|
||||||
this->latency.min_quantum = 1.0f;
|
this->latency[this->port_direction] = SPA_LATENCY_INFO(
|
||||||
this->latency.max_quantum = 1.0f;
|
this->port_direction,
|
||||||
|
.min_quantum = 1.0f,
|
||||||
|
.max_quantum = 1.0f);
|
||||||
|
this->latency[SPA_DIRECTION_INPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT);
|
||||||
|
|
||||||
this->info_all = SPA_NODE_CHANGE_MASK_FLAGS |
|
this->info_all = SPA_NODE_CHANGE_MASK_FLAGS |
|
||||||
SPA_NODE_CHANGE_MASK_PROPS |
|
SPA_NODE_CHANGE_MASK_PROPS |
|
||||||
|
|
|
||||||
|
|
@ -682,7 +682,8 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
|
||||||
state->headroom = SPA_MIN(state->headroom, state->buffer_frames);
|
state->headroom = SPA_MIN(state->headroom, state->buffer_frames);
|
||||||
state->start_delay = state->default_start_delay;
|
state->start_delay = state->default_start_delay;
|
||||||
|
|
||||||
state->latency.min_rate = state->latency.max_rate = state->headroom;
|
state->latency[state->port_direction].min_rate = state->headroom;
|
||||||
|
state->latency[state->port_direction].max_rate = state->headroom;
|
||||||
|
|
||||||
state->period_frames = period_size;
|
state->period_frames = period_size;
|
||||||
periods = state->buffer_frames / state->period_frames;
|
periods = state->buffer_frames / state->period_frames;
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,7 @@ struct state {
|
||||||
#define IDX_Latency 5
|
#define IDX_Latency 5
|
||||||
#define N_PORT_PARAMS 6
|
#define N_PORT_PARAMS 6
|
||||||
struct spa_param_info port_params[N_PORT_PARAMS];
|
struct spa_param_info port_params[N_PORT_PARAMS];
|
||||||
|
enum spa_direction port_direction;
|
||||||
struct spa_io_buffers *io;
|
struct spa_io_buffers *io;
|
||||||
struct spa_io_clock *clock;
|
struct spa_io_clock *clock;
|
||||||
struct spa_io_position *position;
|
struct spa_io_position *position;
|
||||||
|
|
@ -196,7 +197,7 @@ struct state {
|
||||||
struct spa_dll dll;
|
struct spa_dll dll;
|
||||||
double max_error;
|
double max_error;
|
||||||
|
|
||||||
struct spa_latency_info latency;
|
struct spa_latency_info latency[2];
|
||||||
|
|
||||||
snd_use_case_mgr_t *ucm;
|
snd_use_case_mgr_t *ucm;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue