mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
avb: more work
Handle properties. Fix format negotiation. Wait in underrun.
This commit is contained in:
parent
537a38355a
commit
552a0056b5
4 changed files with 193 additions and 74 deletions
|
|
@ -45,6 +45,13 @@
|
||||||
|
|
||||||
static void reset_props(struct props *props)
|
static void reset_props(struct props *props)
|
||||||
{
|
{
|
||||||
|
snprintf(props->ifname, sizeof(props->ifname), "%s", DEFAULT_IFNAME);
|
||||||
|
parse_addr(props->addr, DEFAULT_ADDR);
|
||||||
|
props->prio = DEFAULT_PRIO;
|
||||||
|
parse_streamid(&props->streamid, DEFAULT_STREAMID);
|
||||||
|
props->mtt = DEFAULT_MTT;
|
||||||
|
props->t_uncertainty = DEFAULT_TU;
|
||||||
|
props->frames_per_pdu = DEFAULT_FRAMES_PER_PDU;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_node_info(struct state *this, bool full)
|
static void emit_node_info(struct state *this, bool full)
|
||||||
|
|
@ -123,74 +130,10 @@ static int impl_node_enum_params(void *object, int seq,
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case SPA_PARAM_PropInfo:
|
case SPA_PARAM_PropInfo:
|
||||||
{
|
{
|
||||||
struct props *p = &this->props;
|
|
||||||
|
|
||||||
switch (result.index) {
|
switch (result.index) {
|
||||||
case 0:
|
|
||||||
param = spa_pod_builder_add_object(&b,
|
|
||||||
SPA_TYPE_OBJECT_PropInfo, id,
|
|
||||||
SPA_PROP_INFO_name, SPA_POD_String("avb.ifname"),
|
|
||||||
SPA_PROP_INFO_description, SPA_POD_String("The AVB interface name"),
|
|
||||||
SPA_PROP_INFO_type, SPA_POD_Stringn(p->ifname, sizeof(p->ifname)),
|
|
||||||
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
param = spa_pod_builder_add_object(&b,
|
|
||||||
SPA_TYPE_OBJECT_PropInfo, id,
|
|
||||||
SPA_PROP_INFO_name, SPA_POD_String("avb.macaddr"),
|
|
||||||
SPA_PROP_INFO_description, SPA_POD_String("The AVB MAC address"),
|
|
||||||
SPA_PROP_INFO_type, SPA_POD_Stringn(p->addr, sizeof(p->addr)),
|
|
||||||
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
param = spa_pod_builder_add_object(&b,
|
|
||||||
SPA_TYPE_OBJECT_PropInfo, id,
|
|
||||||
SPA_PROP_INFO_name, SPA_POD_String("avb.prio"),
|
|
||||||
SPA_PROP_INFO_description, SPA_POD_String("The AVB stream priority"),
|
|
||||||
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->prio, 0, INT32_MAX),
|
|
||||||
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
param = spa_pod_builder_add_object(&b,
|
|
||||||
SPA_TYPE_OBJECT_PropInfo, id,
|
|
||||||
SPA_PROP_INFO_name, SPA_POD_String("avb.streamid"),
|
|
||||||
SPA_PROP_INFO_description, SPA_POD_String("The AVB stream id"),
|
|
||||||
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Long(p->streamid, 0LL, UINT64_MAX),
|
|
||||||
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
param = spa_pod_builder_add_object(&b,
|
|
||||||
SPA_TYPE_OBJECT_PropInfo, id,
|
|
||||||
SPA_PROP_INFO_name, SPA_POD_String("avb.mtt"),
|
|
||||||
SPA_PROP_INFO_description, SPA_POD_String("The AVB mtt"),
|
|
||||||
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->mtt, 0, INT32_MAX),
|
|
||||||
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
param = spa_pod_builder_add_object(&b,
|
|
||||||
SPA_TYPE_OBJECT_PropInfo, id,
|
|
||||||
SPA_PROP_INFO_name, SPA_POD_String("avb.time-uncertainty"),
|
|
||||||
SPA_PROP_INFO_description, SPA_POD_String("The AVB time uncertainty"),
|
|
||||||
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->t_uncertainty, 0, INT32_MAX),
|
|
||||||
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
param = spa_pod_builder_add_object(&b,
|
|
||||||
SPA_TYPE_OBJECT_PropInfo, id,
|
|
||||||
SPA_PROP_INFO_name, SPA_POD_String("avb.frames-per-pdu"),
|
|
||||||
SPA_PROP_INFO_description, SPA_POD_String("The AVB frames per packet"),
|
|
||||||
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->frames_per_pdu, 0, INT32_MAX),
|
|
||||||
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
param = spa_pod_builder_add_object(&b,
|
|
||||||
SPA_TYPE_OBJECT_PropInfo, id,
|
|
||||||
SPA_PROP_INFO_name, SPA_POD_String("avb.ptime-tolerance"),
|
|
||||||
SPA_PROP_INFO_description, SPA_POD_String("The AVB packet tolerance"),
|
|
||||||
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->ptime_tolerance, 0, INT32_MAX),
|
|
||||||
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
|
param = spa_avb_enum_propinfo(this, result.index, &b);
|
||||||
|
if (param == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -588,6 +531,7 @@ static int port_set_format(void *object, struct port *port,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
spa_log_debug(this->log, "clear format");
|
spa_log_debug(this->log, "clear format");
|
||||||
|
port->have_format = false;
|
||||||
spa_avb_clear_format(this);
|
spa_avb_clear_format(this);
|
||||||
clear_buffers(this, port);
|
clear_buffers(this, port);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -607,6 +551,7 @@ static int port_set_format(void *object, struct port *port,
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
port->current_format = info;
|
port->current_format = info;
|
||||||
|
port->have_format = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS;
|
this->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS;
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@
|
||||||
|
|
||||||
static int avb_set_param(struct state *state, const char *k, const char *s)
|
static int avb_set_param(struct state *state, const char *k, const char *s)
|
||||||
{
|
{
|
||||||
|
struct props *p = &state->props;
|
||||||
int fmt_change = 0;
|
int fmt_change = 0;
|
||||||
if (spa_streq(k, SPA_KEY_AUDIO_CHANNELS)) {
|
if (spa_streq(k, SPA_KEY_AUDIO_CHANNELS)) {
|
||||||
state->default_channels = atoi(s);
|
state->default_channels = atoi(s);
|
||||||
|
|
@ -64,6 +65,22 @@ static int avb_set_param(struct state *state, const char *k, const char *s)
|
||||||
state->n_allowed_rates = spa_avb_parse_rates(state->allowed_rates,
|
state->n_allowed_rates = spa_avb_parse_rates(state->allowed_rates,
|
||||||
MAX_RATES, s, strlen(s));
|
MAX_RATES, s, strlen(s));
|
||||||
fmt_change++;
|
fmt_change++;
|
||||||
|
} else if (spa_streq(k, "avb.ifname")) {
|
||||||
|
snprintf(p->ifname, sizeof(p->ifname), "%s", s);
|
||||||
|
} else if (spa_streq(k, "avb.macaddr")) {
|
||||||
|
parse_addr(p->addr, s);
|
||||||
|
} else if (spa_streq(k, "avb.prio")) {
|
||||||
|
p->prio = atoi(s);
|
||||||
|
} else if (spa_streq(k, "avb.streamid")) {
|
||||||
|
parse_streamid(&p->streamid, s);
|
||||||
|
} else if (spa_streq(k, "avb.mtt")) {
|
||||||
|
p->mtt = atoi(s);
|
||||||
|
} else if (spa_streq(k, "avb.time-uncertainty")) {
|
||||||
|
p->t_uncertainty = atoi(s);
|
||||||
|
} else if (spa_streq(k, "avb.frames-per-pdu")) {
|
||||||
|
p->frames_per_pdu = atoi(s);
|
||||||
|
} else if (spa_streq(k, "avb.ptime-tolerance")) {
|
||||||
|
p->ptime_tolerance = atoi(s);
|
||||||
} else if (spa_streq(k, "latency.internal.rate")) {
|
} else if (spa_streq(k, "latency.internal.rate")) {
|
||||||
state->process_latency.rate = atoi(s);
|
state->process_latency.rate = atoi(s);
|
||||||
} else if (spa_streq(k, "latency.internal.ns")) {
|
} else if (spa_streq(k, "latency.internal.ns")) {
|
||||||
|
|
@ -120,6 +137,8 @@ struct spa_pod *spa_avb_enum_propinfo(struct state *state,
|
||||||
uint32_t idx, struct spa_pod_builder *b)
|
uint32_t idx, struct spa_pod_builder *b)
|
||||||
{
|
{
|
||||||
struct spa_pod *param;
|
struct spa_pod *param;
|
||||||
|
struct props *p = &state->props;
|
||||||
|
char tmp[128];
|
||||||
|
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|
@ -172,6 +191,72 @@ struct spa_pod *spa_avb_enum_propinfo(struct state *state,
|
||||||
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 5:
|
||||||
|
param = spa_pod_builder_add_object(b,
|
||||||
|
SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
|
||||||
|
SPA_PROP_INFO_name, SPA_POD_String("avb.ifname"),
|
||||||
|
SPA_PROP_INFO_description, SPA_POD_String("The AVB interface name"),
|
||||||
|
SPA_PROP_INFO_type, SPA_POD_Stringn(p->ifname, sizeof(p->ifname)),
|
||||||
|
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
format_addr(tmp, sizeof(tmp), p->addr);
|
||||||
|
param = spa_pod_builder_add_object(b,
|
||||||
|
SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
|
||||||
|
SPA_PROP_INFO_name, SPA_POD_String("avb.macaddr"),
|
||||||
|
SPA_PROP_INFO_description, SPA_POD_String("The AVB MAC address"),
|
||||||
|
SPA_PROP_INFO_type, SPA_POD_String(tmp),
|
||||||
|
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
param = spa_pod_builder_add_object(b,
|
||||||
|
SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
|
||||||
|
SPA_PROP_INFO_name, SPA_POD_String("avb.prio"),
|
||||||
|
SPA_PROP_INFO_description, SPA_POD_String("The AVB stream priority"),
|
||||||
|
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->prio, 0, INT32_MAX),
|
||||||
|
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
format_streamid(tmp, sizeof(tmp), p->streamid);
|
||||||
|
param = spa_pod_builder_add_object(b,
|
||||||
|
SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
|
||||||
|
SPA_PROP_INFO_name, SPA_POD_String("avb.streamid"),
|
||||||
|
SPA_PROP_INFO_description, SPA_POD_String("The AVB stream id"),
|
||||||
|
SPA_PROP_INFO_type, SPA_POD_String(tmp),
|
||||||
|
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
param = spa_pod_builder_add_object(b,
|
||||||
|
SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
|
||||||
|
SPA_PROP_INFO_name, SPA_POD_String("avb.mtt"),
|
||||||
|
SPA_PROP_INFO_description, SPA_POD_String("The AVB mtt"),
|
||||||
|
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->mtt, 0, INT32_MAX),
|
||||||
|
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
param = spa_pod_builder_add_object(b,
|
||||||
|
SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
|
||||||
|
SPA_PROP_INFO_name, SPA_POD_String("avb.time-uncertainty"),
|
||||||
|
SPA_PROP_INFO_description, SPA_POD_String("The AVB time uncertainty"),
|
||||||
|
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->t_uncertainty, 0, INT32_MAX),
|
||||||
|
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
param = spa_pod_builder_add_object(b,
|
||||||
|
SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
|
||||||
|
SPA_PROP_INFO_name, SPA_POD_String("avb.frames-per-pdu"),
|
||||||
|
SPA_PROP_INFO_description, SPA_POD_String("The AVB frames per packet"),
|
||||||
|
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->frames_per_pdu, 0, INT32_MAX),
|
||||||
|
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
param = spa_pod_builder_add_object(b,
|
||||||
|
SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
|
||||||
|
SPA_PROP_INFO_name, SPA_POD_String("avb.ptime-tolerance"),
|
||||||
|
SPA_PROP_INFO_description, SPA_POD_String("The AVB packet tolerance"),
|
||||||
|
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->ptime_tolerance, 0, INT32_MAX),
|
||||||
|
SPA_PROP_INFO_params, SPA_POD_Bool(true));
|
||||||
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
param = spa_pod_builder_add_object(b,
|
param = spa_pod_builder_add_object(b,
|
||||||
SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
|
SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
|
||||||
|
|
@ -206,6 +291,7 @@ struct spa_pod *spa_avb_enum_propinfo(struct state *state,
|
||||||
|
|
||||||
int spa_avb_add_prop_params(struct state *state, struct spa_pod_builder *b)
|
int spa_avb_add_prop_params(struct state *state, struct spa_pod_builder *b)
|
||||||
{
|
{
|
||||||
|
struct props *p = &state->props;
|
||||||
struct spa_pod_frame f[1];
|
struct spa_pod_frame f[1];
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
|
|
@ -232,6 +318,28 @@ int spa_avb_add_prop_params(struct state *state, struct spa_pod_builder *b)
|
||||||
spa_pod_builder_string(b, SPA_KEY_AUDIO_ALLOWED_RATES);
|
spa_pod_builder_string(b, SPA_KEY_AUDIO_ALLOWED_RATES);
|
||||||
spa_pod_builder_string(b, buf);
|
spa_pod_builder_string(b, buf);
|
||||||
|
|
||||||
|
spa_pod_builder_string(b, "avb.ifname");
|
||||||
|
spa_pod_builder_string(b, p->ifname);
|
||||||
|
|
||||||
|
format_addr(buf, sizeof(buf), p->addr);
|
||||||
|
spa_pod_builder_string(b, "avb.macadr");
|
||||||
|
spa_pod_builder_string(b, buf);
|
||||||
|
|
||||||
|
spa_pod_builder_string(b, "avb.prio");
|
||||||
|
spa_pod_builder_int(b, p->prio);
|
||||||
|
|
||||||
|
format_streamid(buf, sizeof(buf), p->streamid);
|
||||||
|
spa_pod_builder_string(b, "avb.streamid");
|
||||||
|
spa_pod_builder_string(b, buf);
|
||||||
|
spa_pod_builder_string(b, "avb.mtt");
|
||||||
|
spa_pod_builder_int(b, p->mtt);
|
||||||
|
spa_pod_builder_string(b, "avb.time-uncertainty");
|
||||||
|
spa_pod_builder_int(b, p->t_uncertainty);
|
||||||
|
spa_pod_builder_string(b, "avb.frames-per-pdu");
|
||||||
|
spa_pod_builder_int(b, p->frames_per_pdu);
|
||||||
|
spa_pod_builder_string(b, "avb.ptime-tolerance");
|
||||||
|
spa_pod_builder_int(b, p->ptime_tolerance);
|
||||||
|
|
||||||
spa_pod_builder_string(b, "latency.internal.rate");
|
spa_pod_builder_string(b, "latency.internal.rate");
|
||||||
spa_pod_builder_int(b, state->process_latency.rate);
|
spa_pod_builder_int(b, state->process_latency.rate);
|
||||||
|
|
||||||
|
|
@ -456,7 +564,7 @@ static int setup_socket(struct state *state)
|
||||||
snprintf(req.ifr_name, sizeof(req.ifr_name), "%s", p->ifname);
|
snprintf(req.ifr_name, sizeof(req.ifr_name), "%s", p->ifname);
|
||||||
res = ioctl(fd, SIOCGIFINDEX, &req);
|
res = ioctl(fd, SIOCGIFINDEX, &req);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
spa_log_error(state->log, "SIOCGIFINDEX failed: %m");
|
spa_log_error(state->log, "SIOCGIFINDEX %s failed: %m", p->ifname);
|
||||||
res = -errno;
|
res = -errno;
|
||||||
goto error_close;
|
goto error_close;
|
||||||
}
|
}
|
||||||
|
|
@ -473,7 +581,7 @@ static int setup_socket(struct state *state)
|
||||||
res = setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &p->prio,
|
res = setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &p->prio,
|
||||||
sizeof(p->prio));
|
sizeof(p->prio));
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
spa_log_error(state->log, "setsockopt(SO_PRIORITY) failed: %m");
|
spa_log_error(state->log, "setsockopt(SO_PRIORITY %d) failed: %m", p->prio);
|
||||||
res = -errno;
|
res = -errno;
|
||||||
goto error_close;
|
goto error_close;
|
||||||
}
|
}
|
||||||
|
|
@ -505,7 +613,7 @@ static int setup_socket(struct state *state)
|
||||||
res = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
|
res = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
|
||||||
&mreq, sizeof(struct packet_mreq));
|
&mreq, sizeof(struct packet_mreq));
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
spa_log_error(state->log, "setsockopt(ADD_MEMBERSHIP failed: %m");
|
spa_log_error(state->log, "setsockopt(ADD_MEMBERSHIP) failed: %m");
|
||||||
res = -errno;
|
res = -errno;
|
||||||
goto error_close;
|
goto error_close;
|
||||||
}
|
}
|
||||||
|
|
@ -589,6 +697,7 @@ int spa_avb_set_format(struct state *state, struct spa_audio_info *fmt, uint32_t
|
||||||
state->format = fmt->info.raw.format;
|
state->format = fmt->info.raw.format;
|
||||||
state->rate = fmt->info.raw.rate;
|
state->rate = fmt->info.raw.rate;
|
||||||
state->channels = fmt->info.raw.channels;
|
state->channels = fmt->info.raw.channels;
|
||||||
|
state->blocks = 1;
|
||||||
state->stride = state->channels * frame_size(state->format);
|
state->stride = state->channels * frame_size(state->format);
|
||||||
|
|
||||||
if ((res = setup_socket(state)) < 0)
|
if ((res = setup_socket(state)) < 0)
|
||||||
|
|
@ -785,6 +894,7 @@ static int handle_play(struct state *state, uint64_t current_time)
|
||||||
avail = spa_ringbuffer_get_read_index(&state->ring, &index);
|
avail = spa_ringbuffer_get_read_index(&state->ring, &index);
|
||||||
if (avail < (int32_t) state->duration) {
|
if (avail < (int32_t) state->duration) {
|
||||||
spa_log_warn(state->log, "underrun %d", avail);
|
spa_log_warn(state->log, "underrun %d", avail);
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdu_count = state->duration / p->frames_per_pdu;
|
pdu_count = state->duration / p->frames_per_pdu;
|
||||||
|
|
@ -817,6 +927,7 @@ static int handle_play(struct state *state, uint64_t current_time)
|
||||||
}
|
}
|
||||||
spa_ringbuffer_read_update(&state->ring, index);
|
spa_ringbuffer_read_update(&state->ring, index);
|
||||||
|
|
||||||
|
done:
|
||||||
spa_node_call_ready(&state->callbacks, SPA_STATUS_NEED_DATA);
|
spa_node_call_ready(&state->callbacks, SPA_STATUS_NEED_DATA);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,14 @@ extern "C" {
|
||||||
|
|
||||||
#define MAX_RATES 16
|
#define MAX_RATES 16
|
||||||
|
|
||||||
|
#define DEFAULT_IFNAME "eth0"
|
||||||
|
#define DEFAULT_ADDR "01:AA:AA:AA:AA:AA"
|
||||||
|
#define DEFAULT_PRIO 0
|
||||||
|
#define DEFAULT_STREAMID "AA:BB:CC:DD:EE:FF:0000"
|
||||||
|
#define DEFAULT_MTT 5000000
|
||||||
|
#define DEFAULT_TU 1000000
|
||||||
|
#define DEFAULT_FRAMES_PER_PDU 8
|
||||||
|
|
||||||
#define DEFAULT_PERIOD 1024u
|
#define DEFAULT_PERIOD 1024u
|
||||||
#define DEFAULT_RATE 48000u
|
#define DEFAULT_RATE 48000u
|
||||||
#define DEFAULT_CHANNELS 8u
|
#define DEFAULT_CHANNELS 8u
|
||||||
|
|
@ -74,6 +82,53 @@ struct props {
|
||||||
int ptime_tolerance;
|
int ptime_tolerance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline int parse_addr(unsigned char addr[ETH_ALEN], const char *str)
|
||||||
|
{
|
||||||
|
unsigned char ad[ETH_ALEN];
|
||||||
|
if (sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
||||||
|
&ad[0], &ad[1], &ad[2], &ad[3], &ad[4], &ad[5]) != 6)
|
||||||
|
return -EINVAL;
|
||||||
|
memcpy(addr, ad, sizeof(ad));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static inline char *format_addr(char *str, size_t size, const unsigned char addr[ETH_ALEN])
|
||||||
|
{
|
||||||
|
snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
addr[0], addr[1], addr[2],
|
||||||
|
addr[3], addr[4], addr[5]);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int parse_streamid(uint64_t *streamid, const char *str)
|
||||||
|
{
|
||||||
|
unsigned char addr[6];
|
||||||
|
unsigned short unique_id;
|
||||||
|
if (sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hx",
|
||||||
|
&addr[0], &addr[1], &addr[2], &addr[3],
|
||||||
|
&addr[4], &addr[5], &unique_id) != 7)
|
||||||
|
return -EINVAL;
|
||||||
|
*streamid = (uint64_t) addr[0] << 56 |
|
||||||
|
(uint64_t) addr[1] << 48 |
|
||||||
|
(uint64_t) addr[2] << 40 |
|
||||||
|
(uint64_t) addr[3] << 32 |
|
||||||
|
(uint64_t) addr[4] << 24 |
|
||||||
|
(uint64_t) addr[5] << 16 |
|
||||||
|
unique_id;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static inline char *format_streamid(char *str, size_t size, const uint64_t streamid)
|
||||||
|
{
|
||||||
|
snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x:%04x",
|
||||||
|
(uint8_t)(streamid >> 56),
|
||||||
|
(uint8_t)(streamid >> 48),
|
||||||
|
(uint8_t)(streamid >> 40),
|
||||||
|
(uint8_t)(streamid >> 32),
|
||||||
|
(uint8_t)(streamid >> 24),
|
||||||
|
(uint8_t)(streamid >> 16),
|
||||||
|
(uint16_t)(streamid));
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
#define MAX_BUFFERS 32
|
#define MAX_BUFFERS 32
|
||||||
|
|
||||||
struct buffer {
|
struct buffer {
|
||||||
|
|
|
||||||
|
|
@ -238,11 +238,19 @@ context.objects = [
|
||||||
#}
|
#}
|
||||||
{ factory = adapter
|
{ factory = adapter
|
||||||
args = {
|
args = {
|
||||||
factory.name = avb.pcm.sink
|
factory.name = avb.pcm.sink
|
||||||
node.name = AVB-sink
|
node.name = AVB-sink
|
||||||
node.description = "AVB Sink"
|
node.description = "AVB Sink"
|
||||||
media.class = "Audio/Sink"
|
media.class = "Audio/Sink"
|
||||||
audio.channels = 8
|
audio.channels = 8
|
||||||
|
avb.ifname = "enp3s0"
|
||||||
|
#avb.macaddr = "01:AA:AA:AA:AA:AA"
|
||||||
|
#avb.prio = 0
|
||||||
|
#avb.streamid = "AA:BB:CC:DD:EE:FF:0000"
|
||||||
|
#avb.mtt = 50000000
|
||||||
|
#avb.time-uncertainty = 1000000
|
||||||
|
#avb.frames-per-pdu = 8
|
||||||
|
#avb.ptime-tolerance = 100000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue