mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
bluez5: add port latency reporting
This commit is contained in:
parent
d8435cd5fd
commit
38bcec9022
6 changed files with 120 additions and 5 deletions
|
|
@ -44,6 +44,7 @@
|
||||||
#include <spa/node/io.h>
|
#include <spa/node/io.h>
|
||||||
#include <spa/node/keys.h>
|
#include <spa/node/keys.h>
|
||||||
#include <spa/param/param.h>
|
#include <spa/param/param.h>
|
||||||
|
#include <spa/param/latency-utils.h>
|
||||||
#include <spa/param/audio/format.h>
|
#include <spa/param/audio/format.h>
|
||||||
#include <spa/param/audio/format-utils.h>
|
#include <spa/param/audio/format-utils.h>
|
||||||
#include <spa/pod/filter.h>
|
#include <spa/pod/filter.h>
|
||||||
|
|
@ -82,12 +83,14 @@ struct port {
|
||||||
uint64_t info_all;
|
uint64_t info_all;
|
||||||
struct spa_port_info info;
|
struct spa_port_info info;
|
||||||
struct spa_io_buffers *io;
|
struct spa_io_buffers *io;
|
||||||
|
struct spa_latency_info latency;
|
||||||
#define IDX_EnumFormat 0
|
#define IDX_EnumFormat 0
|
||||||
#define IDX_Meta 1
|
#define IDX_Meta 1
|
||||||
#define IDX_IO 2
|
#define IDX_IO 2
|
||||||
#define IDX_Format 3
|
#define IDX_Format 3
|
||||||
#define IDX_Buffers 4
|
#define IDX_Buffers 4
|
||||||
#define N_PORT_PARAMS 5
|
#define IDX_Latency 5
|
||||||
|
#define N_PORT_PARAMS 6
|
||||||
struct spa_param_info params[N_PORT_PARAMS];
|
struct spa_param_info params[N_PORT_PARAMS];
|
||||||
|
|
||||||
struct buffer buffers[MAX_BUFFERS];
|
struct buffer buffers[MAX_BUFFERS];
|
||||||
|
|
@ -336,6 +339,27 @@ static int impl_node_set_io(void *object, uint32_t id, void *data, size_t size)
|
||||||
|
|
||||||
static void emit_node_info(struct impl *this, bool full);
|
static void emit_node_info(struct impl *this, bool full);
|
||||||
|
|
||||||
|
static void emit_port_info(struct impl *this, struct port *port, bool full);
|
||||||
|
|
||||||
|
static void set_latency(struct impl *this, bool emit_latency)
|
||||||
|
{
|
||||||
|
struct port *port = &this->port;
|
||||||
|
int64_t delay;
|
||||||
|
|
||||||
|
if (this->transport == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
delay = spa_bt_transport_get_delay_nsec(this->transport);
|
||||||
|
delay += SPA_CLAMP(this->props.latency_offset, -delay, INT64_MAX / 2);
|
||||||
|
port->latency.min_ns = port->latency.max_ns = delay;
|
||||||
|
|
||||||
|
if (emit_latency) {
|
||||||
|
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||||
|
port->params[IDX_Latency].flags ^= SPA_PARAM_INFO_SERIAL;
|
||||||
|
emit_port_info(this, port, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int apply_props(struct impl *this, const struct spa_pod *param)
|
static int apply_props(struct impl *this, const struct spa_pod *param)
|
||||||
{
|
{
|
||||||
struct props new_props = this->props;
|
struct props new_props = this->props;
|
||||||
|
|
@ -353,6 +377,10 @@ static int apply_props(struct impl *this, const struct spa_pod *param)
|
||||||
|
|
||||||
changed = (memcmp(&new_props, &this->props, sizeof(struct props)) != 0);
|
changed = (memcmp(&new_props, &this->props, sizeof(struct props)) != 0);
|
||||||
this->props = new_props;
|
this->props = new_props;
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
set_latency(this, true);
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1065,6 +1093,16 @@ impl_node_port_enum_params(void *object, int seq,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SPA_PARAM_Latency:
|
||||||
|
switch (result.index) {
|
||||||
|
case 0:
|
||||||
|
param = spa_latency_build(&b, id, &port->latency);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
@ -1142,6 +1180,7 @@ static int port_set_format(struct impl *this, struct port *port,
|
||||||
port->info.rate = SPA_FRACTION(1, port->current_format.info.raw.rate);
|
port->info.rate = SPA_FRACTION(1, port->current_format.info.raw.rate);
|
||||||
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
||||||
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||||
|
port->params[IDX_Latency].flags ^= SPA_PARAM_INFO_SERIAL;
|
||||||
} else {
|
} else {
|
||||||
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||||
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||||
|
|
@ -1303,6 +1342,13 @@ static const struct spa_node_methods impl_node = {
|
||||||
.process = impl_node_process,
|
.process = impl_node_process,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void transport_delay_changed(void *data)
|
||||||
|
{
|
||||||
|
struct impl *this = data;
|
||||||
|
spa_log_debug(this->log, "transport %p delay changed", this->transport);
|
||||||
|
set_latency(this, true);
|
||||||
|
}
|
||||||
|
|
||||||
static int do_transport_destroy(struct spa_loop *loop,
|
static int do_transport_destroy(struct spa_loop *loop,
|
||||||
bool async,
|
bool async,
|
||||||
uint32_t seq,
|
uint32_t seq,
|
||||||
|
|
@ -1324,7 +1370,8 @@ static void transport_destroy(void *data)
|
||||||
|
|
||||||
static const struct spa_bt_transport_events transport_events = {
|
static const struct spa_bt_transport_events transport_events = {
|
||||||
SPA_VERSION_BT_TRANSPORT_EVENTS,
|
SPA_VERSION_BT_TRANSPORT_EVENTS,
|
||||||
.destroy = transport_destroy,
|
.delay_changed = transport_delay_changed,
|
||||||
|
.destroy = transport_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
|
static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
|
||||||
|
|
@ -1427,8 +1474,15 @@ impl_init(const struct spa_handle_factory *factory,
|
||||||
port->params[IDX_IO] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
port->params[IDX_IO] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||||
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||||
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||||
|
port->params[IDX_Latency] = SPA_PARAM_INFO(SPA_PARAM_Latency, SPA_PARAM_INFO_READWRITE);
|
||||||
port->info.params = port->params;
|
port->info.params = port->params;
|
||||||
port->info.n_params = N_PORT_PARAMS;
|
port->info.n_params = N_PORT_PARAMS;
|
||||||
|
|
||||||
|
port->latency = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT);
|
||||||
|
port->latency.min_quantum = 1.0f;
|
||||||
|
port->latency.max_quantum = 1.0f;
|
||||||
|
set_latency(this, false);
|
||||||
|
|
||||||
spa_list_init(&port->ready);
|
spa_list_init(&port->ready);
|
||||||
|
|
||||||
if (info && (str = spa_dict_lookup(info, SPA_KEY_API_BLUEZ5_TRANSPORT)))
|
if (info && (str = spa_dict_lookup(info, SPA_KEY_API_BLUEZ5_TRANSPORT)))
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@
|
||||||
#include <spa/node/io.h>
|
#include <spa/node/io.h>
|
||||||
#include <spa/node/keys.h>
|
#include <spa/node/keys.h>
|
||||||
#include <spa/param/param.h>
|
#include <spa/param/param.h>
|
||||||
|
#include <spa/param/latency-utils.h>
|
||||||
#include <spa/param/audio/format.h>
|
#include <spa/param/audio/format.h>
|
||||||
#include <spa/param/audio/format-utils.h>
|
#include <spa/param/audio/format-utils.h>
|
||||||
#include <spa/pod/filter.h>
|
#include <spa/pod/filter.h>
|
||||||
|
|
@ -79,12 +80,14 @@ struct port {
|
||||||
uint64_t info_all;
|
uint64_t info_all;
|
||||||
struct spa_port_info info;
|
struct spa_port_info info;
|
||||||
struct spa_io_buffers *io;
|
struct spa_io_buffers *io;
|
||||||
|
struct spa_latency_info latency;
|
||||||
#define IDX_EnumFormat 0
|
#define IDX_EnumFormat 0
|
||||||
#define IDX_Meta 1
|
#define IDX_Meta 1
|
||||||
#define IDX_IO 2
|
#define IDX_IO 2
|
||||||
#define IDX_Format 3
|
#define IDX_Format 3
|
||||||
#define IDX_Buffers 4
|
#define IDX_Buffers 4
|
||||||
#define N_PORT_PARAMS 5
|
#define IDX_Latency 5
|
||||||
|
#define N_PORT_PARAMS 6
|
||||||
struct spa_param_info params[N_PORT_PARAMS];
|
struct spa_param_info params[N_PORT_PARAMS];
|
||||||
|
|
||||||
struct buffer buffers[MAX_BUFFERS];
|
struct buffer buffers[MAX_BUFFERS];
|
||||||
|
|
@ -950,6 +953,16 @@ impl_node_port_enum_params(void *object, int seq,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SPA_PARAM_Latency:
|
||||||
|
switch (result.index) {
|
||||||
|
case 0:
|
||||||
|
param = spa_latency_build(&b, id, &port->latency);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
@ -1030,6 +1043,7 @@ static int port_set_format(struct impl *this, struct port *port,
|
||||||
port->info.rate = SPA_FRACTION(1, port->current_format.info.raw.rate);
|
port->info.rate = SPA_FRACTION(1, port->current_format.info.raw.rate);
|
||||||
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
||||||
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||||
|
port->params[IDX_Latency].flags ^= SPA_PARAM_INFO_SERIAL;
|
||||||
} else {
|
} else {
|
||||||
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||||
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||||
|
|
@ -1343,9 +1357,14 @@ impl_init(const struct spa_handle_factory *factory,
|
||||||
port->params[IDX_IO] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
port->params[IDX_IO] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||||
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||||
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||||
|
port->params[IDX_Latency] = SPA_PARAM_INFO(SPA_PARAM_Latency, SPA_PARAM_INFO_READWRITE);
|
||||||
port->info.params = port->params;
|
port->info.params = port->params;
|
||||||
port->info.n_params = N_PORT_PARAMS;
|
port->info.n_params = N_PORT_PARAMS;
|
||||||
|
|
||||||
|
port->latency = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT);
|
||||||
|
port->latency.min_quantum = 1.0f;
|
||||||
|
port->latency.max_quantum = 1.0f;
|
||||||
|
|
||||||
/* Init the buffer lists */
|
/* Init the buffer lists */
|
||||||
spa_list_init(&port->ready);
|
spa_list_init(&port->ready);
|
||||||
spa_list_init(&port->free);
|
spa_list_init(&port->free);
|
||||||
|
|
|
||||||
|
|
@ -1909,6 +1909,7 @@ static int transport_update_props(struct spa_bt_transport *transport,
|
||||||
spa_log_debug(monitor->log, "transport %p: %s=%02x", transport, key, value);
|
spa_log_debug(monitor->log, "transport %p: %s=%02x", transport, key, value);
|
||||||
|
|
||||||
transport->delay = value;
|
transport->delay = value;
|
||||||
|
spa_bt_transport_emit_delay_changed(transport);
|
||||||
}
|
}
|
||||||
next:
|
next:
|
||||||
dbus_message_iter_next(props_iter);
|
dbus_message_iter_next(props_iter);
|
||||||
|
|
|
||||||
|
|
@ -488,6 +488,7 @@ struct spa_bt_transport_events {
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
|
||||||
void (*destroy) (void *data);
|
void (*destroy) (void *data);
|
||||||
|
void (*delay_changed) (void *data);
|
||||||
void (*state_changed) (void *data, enum spa_bt_transport_state old,
|
void (*state_changed) (void *data, enum spa_bt_transport_state old,
|
||||||
enum spa_bt_transport_state state);
|
enum spa_bt_transport_state state);
|
||||||
void (*volume_changed) (void *data);
|
void (*volume_changed) (void *data);
|
||||||
|
|
@ -568,6 +569,7 @@ int spa_bt_transport_ensure_sco_io(struct spa_bt_transport *t, struct spa_loop *
|
||||||
struct spa_bt_transport_events, \
|
struct spa_bt_transport_events, \
|
||||||
m, v, ##__VA_ARGS__)
|
m, v, ##__VA_ARGS__)
|
||||||
#define spa_bt_transport_emit_destroy(t) spa_bt_transport_emit(t, destroy, 0)
|
#define spa_bt_transport_emit_destroy(t) spa_bt_transport_emit(t, destroy, 0)
|
||||||
|
#define spa_bt_transport_emit_delay_changed(t) spa_bt_transport_emit(t, delay_changed, 0)
|
||||||
#define spa_bt_transport_emit_state_changed(t,...) spa_bt_transport_emit(t, state_changed, 0, __VA_ARGS__)
|
#define spa_bt_transport_emit_state_changed(t,...) spa_bt_transport_emit(t, state_changed, 0, __VA_ARGS__)
|
||||||
#define spa_bt_transport_emit_volume_changed(t) spa_bt_transport_emit(t, volume_changed, 0)
|
#define spa_bt_transport_emit_volume_changed(t) spa_bt_transport_emit(t, volume_changed, 0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
#include <spa/node/io.h>
|
#include <spa/node/io.h>
|
||||||
#include <spa/node/keys.h>
|
#include <spa/node/keys.h>
|
||||||
#include <spa/param/param.h>
|
#include <spa/param/param.h>
|
||||||
|
#include <spa/param/latency-utils.h>
|
||||||
#include <spa/param/audio/format.h>
|
#include <spa/param/audio/format.h>
|
||||||
#include <spa/param/audio/format-utils.h>
|
#include <spa/param/audio/format-utils.h>
|
||||||
#include <spa/pod/filter.h>
|
#include <spa/pod/filter.h>
|
||||||
|
|
@ -75,12 +76,14 @@ struct port {
|
||||||
struct spa_port_info info;
|
struct spa_port_info info;
|
||||||
struct spa_io_buffers *io;
|
struct spa_io_buffers *io;
|
||||||
struct spa_io_rate_match *rate_match;
|
struct spa_io_rate_match *rate_match;
|
||||||
|
struct spa_latency_info latency;
|
||||||
#define IDX_EnumFormat 0
|
#define IDX_EnumFormat 0
|
||||||
#define IDX_Meta 1
|
#define IDX_Meta 1
|
||||||
#define IDX_IO 2
|
#define IDX_IO 2
|
||||||
#define IDX_Format 3
|
#define IDX_Format 3
|
||||||
#define IDX_Buffers 4
|
#define IDX_Buffers 4
|
||||||
#define N_PORT_PARAMS 5
|
#define IDX_Latency 5
|
||||||
|
#define N_PORT_PARAMS 6
|
||||||
struct spa_param_info params[N_PORT_PARAMS];
|
struct spa_param_info params[N_PORT_PARAMS];
|
||||||
|
|
||||||
struct buffer buffers[MAX_BUFFERS];
|
struct buffer buffers[MAX_BUFFERS];
|
||||||
|
|
@ -896,6 +899,16 @@ impl_node_port_enum_params(void *object, int seq,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SPA_PARAM_Latency:
|
||||||
|
switch (result.index) {
|
||||||
|
case 0:
|
||||||
|
param = spa_latency_build(&b, id, &port->latency);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
@ -957,6 +970,7 @@ static int port_set_format(struct impl *this, struct port *port,
|
||||||
port->info.rate = SPA_FRACTION(1, port->current_format.info.raw.rate);
|
port->info.rate = SPA_FRACTION(1, port->current_format.info.raw.rate);
|
||||||
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
||||||
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||||
|
port->params[IDX_Latency].flags ^= SPA_PARAM_INFO_SERIAL;
|
||||||
} else {
|
} else {
|
||||||
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||||
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||||
|
|
@ -1237,8 +1251,14 @@ impl_init(const struct spa_handle_factory *factory,
|
||||||
port->params[IDX_IO] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
port->params[IDX_IO] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||||
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||||
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||||
|
port->params[IDX_Latency] = SPA_PARAM_INFO(SPA_PARAM_Latency, SPA_PARAM_INFO_READWRITE);
|
||||||
port->info.params = port->params;
|
port->info.params = port->params;
|
||||||
port->info.n_params = N_PORT_PARAMS;
|
port->info.n_params = N_PORT_PARAMS;
|
||||||
|
|
||||||
|
port->latency = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT);
|
||||||
|
port->latency.min_quantum = 1.0f;
|
||||||
|
port->latency.max_quantum = 1.0f;
|
||||||
|
|
||||||
spa_list_init(&port->ready);
|
spa_list_init(&port->ready);
|
||||||
|
|
||||||
if (info && (str = spa_dict_lookup(info, SPA_KEY_API_BLUEZ5_TRANSPORT)))
|
if (info && (str = spa_dict_lookup(info, SPA_KEY_API_BLUEZ5_TRANSPORT)))
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@
|
||||||
#include <spa/node/io.h>
|
#include <spa/node/io.h>
|
||||||
#include <spa/node/keys.h>
|
#include <spa/node/keys.h>
|
||||||
#include <spa/param/param.h>
|
#include <spa/param/param.h>
|
||||||
|
#include <spa/param/latency-utils.h>
|
||||||
#include <spa/param/audio/format.h>
|
#include <spa/param/audio/format.h>
|
||||||
#include <spa/param/audio/format-utils.h>
|
#include <spa/param/audio/format-utils.h>
|
||||||
#include <spa/pod/filter.h>
|
#include <spa/pod/filter.h>
|
||||||
|
|
@ -77,12 +78,14 @@ struct port {
|
||||||
struct spa_port_info info;
|
struct spa_port_info info;
|
||||||
struct spa_io_buffers *io;
|
struct spa_io_buffers *io;
|
||||||
struct spa_io_rate_match *rate_match;
|
struct spa_io_rate_match *rate_match;
|
||||||
|
struct spa_latency_info latency;
|
||||||
#define IDX_EnumFormat 0
|
#define IDX_EnumFormat 0
|
||||||
#define IDX_Meta 1
|
#define IDX_Meta 1
|
||||||
#define IDX_IO 2
|
#define IDX_IO 2
|
||||||
#define IDX_Format 3
|
#define IDX_Format 3
|
||||||
#define IDX_Buffers 4
|
#define IDX_Buffers 4
|
||||||
#define N_PORT_PARAMS 5
|
#define IDX_Latency 5
|
||||||
|
#define N_PORT_PARAMS 6
|
||||||
struct spa_param_info params[N_PORT_PARAMS];
|
struct spa_param_info params[N_PORT_PARAMS];
|
||||||
|
|
||||||
struct buffer buffers[MAX_BUFFERS];
|
struct buffer buffers[MAX_BUFFERS];
|
||||||
|
|
@ -929,6 +932,16 @@ impl_node_port_enum_params(void *object, int seq,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SPA_PARAM_Latency:
|
||||||
|
switch (result.index) {
|
||||||
|
case 0:
|
||||||
|
param = spa_latency_build(&b, id, &port->latency);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
@ -992,6 +1005,7 @@ static int port_set_format(struct impl *this, struct port *port,
|
||||||
port->info.rate = SPA_FRACTION(1, port->current_format.info.raw.rate);
|
port->info.rate = SPA_FRACTION(1, port->current_format.info.raw.rate);
|
||||||
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
||||||
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||||
|
port->params[IDX_Latency].flags ^= SPA_PARAM_INFO_SERIAL;
|
||||||
} else {
|
} else {
|
||||||
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||||
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||||
|
|
@ -1299,9 +1313,14 @@ impl_init(const struct spa_handle_factory *factory,
|
||||||
port->params[IDX_IO] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
port->params[IDX_IO] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||||
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||||
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||||
|
port->params[IDX_Latency] = SPA_PARAM_INFO(SPA_PARAM_Latency, SPA_PARAM_INFO_READWRITE);
|
||||||
port->info.params = port->params;
|
port->info.params = port->params;
|
||||||
port->info.n_params = N_PORT_PARAMS;
|
port->info.n_params = N_PORT_PARAMS;
|
||||||
|
|
||||||
|
port->latency = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT);
|
||||||
|
port->latency.min_quantum = 1.0f;
|
||||||
|
port->latency.max_quantum = 1.0f;
|
||||||
|
|
||||||
/* Init the buffer lists */
|
/* Init the buffer lists */
|
||||||
spa_list_init(&port->ready);
|
spa_list_init(&port->ready);
|
||||||
spa_list_init(&port->free);
|
spa_list_init(&port->free);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue