mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-16 08:56:45 -05:00
module-rtp: improve properties and some cleanups
This commit is contained in:
parent
c46e021734
commit
7a31278511
4 changed files with 45 additions and 32 deletions
|
|
@ -54,6 +54,7 @@
|
||||||
* - `net.loop = <bool>`: loopback multicast, default false
|
* - `net.loop = <bool>`: loopback multicast, default false
|
||||||
* - `sess.min-ptime = <int>`: minimum packet time in milliseconds, default 2
|
* - `sess.min-ptime = <int>`: minimum packet time in milliseconds, default 2
|
||||||
* - `sess.max-ptime = <int>`: maximum packet time in milliseconds, default 20
|
* - `sess.max-ptime = <int>`: maximum packet time in milliseconds, default 20
|
||||||
|
* - `sess.latency.msec = <int>`: receiver latency in milliseconds, default 100
|
||||||
* - `sess.name = <str>`: a session name
|
* - `sess.name = <str>`: a session name
|
||||||
* - `sess.ts-offset = <int>`: an offset to apply to the timestamp, default -1 = random offset
|
* - `sess.ts-offset = <int>`: an offset to apply to the timestamp, default -1 = random offset
|
||||||
* - `sess.ts-refclk = <string>`: the name of a reference clock
|
* - `sess.ts-refclk = <string>`: the name of a reference clock
|
||||||
|
|
@ -238,8 +239,7 @@ struct impl {
|
||||||
|
|
||||||
char *ifname;
|
char *ifname;
|
||||||
char *session_name;
|
char *session_name;
|
||||||
uint32_t mtu;
|
uint32_t ttl;
|
||||||
bool ttl;
|
|
||||||
bool mcast_loop;
|
bool mcast_loop;
|
||||||
int32_t ts_offset;
|
int32_t ts_offset;
|
||||||
char *ts_refclk;
|
char *ts_refclk;
|
||||||
|
|
@ -451,6 +451,7 @@ static void free_session(struct session *sess)
|
||||||
rtp_stream_destroy(sess->send);
|
rtp_stream_destroy(sess->send);
|
||||||
if (sess->recv)
|
if (sess->recv)
|
||||||
rtp_stream_destroy(sess->recv);
|
rtp_stream_destroy(sess->recv);
|
||||||
|
free(sess->name);
|
||||||
free(sess);
|
free(sess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -500,11 +501,12 @@ static struct session *make_session(struct impl *impl, struct pw_properties *pro
|
||||||
sess->ssrc = pw_rand32();
|
sess->ssrc = pw_rand32();
|
||||||
|
|
||||||
str = pw_properties_get(props, "sess.name");
|
str = pw_properties_get(props, "sess.name");
|
||||||
sess->name = str ? strdup(str) : "unknown";
|
sess->name = str ? strdup(str) : strdup("RTP Session");
|
||||||
|
|
||||||
if (impl->ts_refclk != NULL)
|
if (impl->ts_refclk != NULL)
|
||||||
pw_properties_setf(props, "rtp.sender-ts-offset", "%u", impl->ts_offset);
|
pw_properties_setf(props, "rtp.sender-ts-offset", "%u", impl->ts_offset);
|
||||||
pw_properties_setf(props, "rtp.sender-ssrc", "%u", sess->ssrc);
|
pw_properties_setf(props, "rtp.sender-ssrc", "%u", sess->ssrc);
|
||||||
|
pw_properties_set(props, "rtp.session", sess->name);
|
||||||
|
|
||||||
sess->send = rtp_stream_new(impl->core,
|
sess->send = rtp_stream_new(impl->core,
|
||||||
PW_DIRECTION_INPUT, pw_properties_copy(props),
|
PW_DIRECTION_INPUT, pw_properties_copy(props),
|
||||||
|
|
@ -1111,6 +1113,9 @@ static struct service *make_service(struct impl *impl, const struct service_info
|
||||||
} else if (spa_streq(key, "ts-refclk")) {
|
} else if (spa_streq(key, "ts-refclk")) {
|
||||||
pw_properties_set(props,
|
pw_properties_set(props,
|
||||||
"sess.ts-refclk", value);
|
"sess.ts-refclk", value);
|
||||||
|
if (spa_streq(value, impl->ts_refclk))
|
||||||
|
pw_properties_set(props,
|
||||||
|
"sess.ts-direct", "true");
|
||||||
} else if (spa_streq(key, "ts-offset")) {
|
} else if (spa_streq(key, "ts-offset")) {
|
||||||
uint32_t v;
|
uint32_t v;
|
||||||
if (spa_atou32(value, &v, 0))
|
if (spa_atou32(value, &v, 0))
|
||||||
|
|
@ -1464,7 +1469,14 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
||||||
copy_props(impl, props, PW_KEY_NODE_CHANNELNAMES);
|
copy_props(impl, props, PW_KEY_NODE_CHANNELNAMES);
|
||||||
copy_props(impl, props, PW_KEY_MEDIA_NAME);
|
copy_props(impl, props, PW_KEY_MEDIA_NAME);
|
||||||
copy_props(impl, props, PW_KEY_MEDIA_CLASS);
|
copy_props(impl, props, PW_KEY_MEDIA_CLASS);
|
||||||
|
copy_props(impl, props, "net.mtu");
|
||||||
copy_props(impl, props, "rtp.media");
|
copy_props(impl, props, "rtp.media");
|
||||||
|
copy_props(impl, props, "sess.min-ptime");
|
||||||
|
copy_props(impl, props, "sess.max-ptime");
|
||||||
|
copy_props(impl, props, "sess.latency.msec");
|
||||||
|
|
||||||
|
impl->ttl = pw_properties_get_uint32(props, "net.ttl", DEFAULT_TTL);
|
||||||
|
impl->mcast_loop = pw_properties_get_bool(props, "net.loop", DEFAULT_LOOP);
|
||||||
|
|
||||||
if ((str = pw_properties_get(stream_props, "rtp.media")) == NULL) {
|
if ((str = pw_properties_get(stream_props, "rtp.media")) == NULL) {
|
||||||
str = "midi";
|
str = "midi";
|
||||||
|
|
@ -1497,10 +1509,6 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl->mtu = pw_properties_get_uint32(props, "net.mtu", DEFAULT_MTU);
|
|
||||||
impl->ttl = pw_properties_get_uint32(props, "net.ttl", DEFAULT_TTL);
|
|
||||||
impl->mcast_loop = pw_properties_get_bool(props, "net.loop", DEFAULT_LOOP);
|
|
||||||
|
|
||||||
impl->ts_offset = pw_properties_get_int64(props,
|
impl->ts_offset = pw_properties_get_int64(props,
|
||||||
"sess.ts-offset", pw_rand32());
|
"sess.ts-offset", pw_rand32());
|
||||||
str = pw_properties_get(props, "sess.ts-refclk");
|
str = pw_properties_get(props, "sess.ts-refclk");
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ static void process_audio_playback(void *data)
|
||||||
pw_stream_queue_buffer(impl->stream, buf);
|
pw_stream_queue_buffer(impl->stream, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void receive_rtp_audio(struct impl *impl, uint8_t *buffer, ssize_t len)
|
static int receive_rtp_audio(struct impl *impl, uint8_t *buffer, ssize_t len)
|
||||||
{
|
{
|
||||||
struct rtp_header *hdr;
|
struct rtp_header *hdr;
|
||||||
ssize_t hlen, plen;
|
ssize_t hlen, plen;
|
||||||
|
|
@ -110,7 +110,6 @@ static void receive_rtp_audio(struct impl *impl, uint8_t *buffer, ssize_t len)
|
||||||
if (hdr->v != 2)
|
if (hdr->v != 2)
|
||||||
goto invalid_version;
|
goto invalid_version;
|
||||||
|
|
||||||
|
|
||||||
hlen = 12 + hdr->cc * 4;
|
hlen = 12 + hdr->cc * 4;
|
||||||
if (hlen > len)
|
if (hlen > len)
|
||||||
goto invalid_len;
|
goto invalid_len;
|
||||||
|
|
@ -175,22 +174,22 @@ static void receive_rtp_audio(struct impl *impl, uint8_t *buffer, ssize_t len)
|
||||||
write += samples;
|
write += samples;
|
||||||
spa_ringbuffer_write_update(&impl->ring, write);
|
spa_ringbuffer_write_update(&impl->ring, write);
|
||||||
}
|
}
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
short_packet:
|
short_packet:
|
||||||
pw_log_warn("short packet received");
|
pw_log_warn("short packet received");
|
||||||
return;
|
return -EINVAL;
|
||||||
invalid_version:
|
invalid_version:
|
||||||
pw_log_warn("invalid RTP version");
|
pw_log_warn("invalid RTP version");
|
||||||
spa_debug_mem(0, buffer, len);
|
spa_debug_mem(0, buffer, len);
|
||||||
return;
|
return -EPROTO;
|
||||||
invalid_len:
|
invalid_len:
|
||||||
pw_log_warn("invalid RTP length");
|
pw_log_warn("invalid RTP length");
|
||||||
return;
|
return -EINVAL;
|
||||||
unexpected_ssrc:
|
unexpected_ssrc:
|
||||||
pw_log_warn("unexpected SSRC (expected %u != %u)",
|
pw_log_warn("unexpected SSRC (expected %u != %u)",
|
||||||
impl->ssrc, hdr->ssrc);
|
impl->ssrc, hdr->ssrc);
|
||||||
return;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ static double get_time(struct impl *impl)
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void receive_midi(struct impl *impl, uint8_t *packet,
|
static int receive_midi(struct impl *impl, uint8_t *packet,
|
||||||
uint32_t timestamp, uint32_t payload_offset, uint32_t plen)
|
uint32_t timestamp, uint32_t payload_offset, uint32_t plen)
|
||||||
{
|
{
|
||||||
uint32_t write;
|
uint32_t write;
|
||||||
|
|
@ -207,7 +207,7 @@ static void receive_midi(struct impl *impl, uint8_t *packet,
|
||||||
filled = spa_ringbuffer_get_write_index(&impl->ring, &write);
|
filled = spa_ringbuffer_get_write_index(&impl->ring, &write);
|
||||||
if (filled > (int32_t)BUFFER_SIZE2) {
|
if (filled > (int32_t)BUFFER_SIZE2) {
|
||||||
pw_log_warn("overflow");
|
pw_log_warn("overflow");
|
||||||
return;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr = (struct rtp_midi_header *)&packet[offs++];
|
hdr = (struct rtp_midi_header *)&packet[offs++];
|
||||||
|
|
@ -219,7 +219,7 @@ static void receive_midi(struct impl *impl, uint8_t *packet,
|
||||||
end = len + offs;
|
end = len + offs;
|
||||||
if (end > plen) {
|
if (end > plen) {
|
||||||
pw_log_warn("invalid packet %d > %d", end, plen);
|
pw_log_warn("invalid packet %d > %d", end, plen);
|
||||||
return;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = SPA_PTROFF(impl->buffer, write & BUFFER_MASK2, void);
|
ptr = SPA_PTROFF(impl->buffer, write & BUFFER_MASK2, void);
|
||||||
|
|
@ -258,9 +258,10 @@ static void receive_midi(struct impl *impl, uint8_t *packet,
|
||||||
|
|
||||||
write += b.state.offset;
|
write += b.state.offset;
|
||||||
spa_ringbuffer_write_update(&impl->ring, write);
|
spa_ringbuffer_write_update(&impl->ring, write);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void receive_rtp_midi(struct impl *impl, uint8_t *buffer, ssize_t len)
|
static int receive_rtp_midi(struct impl *impl, uint8_t *buffer, ssize_t len)
|
||||||
{
|
{
|
||||||
struct rtp_header *hdr;
|
struct rtp_header *hdr;
|
||||||
ssize_t hlen;
|
ssize_t hlen;
|
||||||
|
|
@ -296,23 +297,22 @@ static void receive_rtp_midi(struct impl *impl, uint8_t *buffer, ssize_t len)
|
||||||
|
|
||||||
impl->receiving = true;
|
impl->receiving = true;
|
||||||
|
|
||||||
receive_midi(impl, buffer, timestamp, hlen, len);
|
return receive_midi(impl, buffer, timestamp, hlen, len);
|
||||||
return;
|
|
||||||
|
|
||||||
short_packet:
|
short_packet:
|
||||||
pw_log_warn("short packet received");
|
pw_log_warn("short packet received");
|
||||||
return;
|
return -EINVAL;
|
||||||
invalid_version:
|
invalid_version:
|
||||||
pw_log_warn("invalid RTP version");
|
pw_log_warn("invalid RTP version");
|
||||||
spa_debug_mem(0, buffer, len);
|
spa_debug_mem(0, buffer, len);
|
||||||
return;
|
return -EPROTO;
|
||||||
invalid_len:
|
invalid_len:
|
||||||
pw_log_warn("invalid RTP length");
|
pw_log_warn("invalid RTP length");
|
||||||
return;
|
return -EINVAL;
|
||||||
unexpected_ssrc:
|
unexpected_ssrc:
|
||||||
pw_log_warn("unexpected SSRC (expected %u != %u)",
|
pw_log_warn("unexpected SSRC (expected %u != %u)",
|
||||||
impl->ssrc, hdr->ssrc);
|
impl->ssrc, hdr->ssrc);
|
||||||
return;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_event(uint8_t *p, uint32_t value, void *ev, uint32_t size)
|
static int write_event(uint8_t *p, uint32_t value, void *ev, uint32_t size)
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ struct impl {
|
||||||
unsigned receiving:1;
|
unsigned receiving:1;
|
||||||
unsigned first:1;
|
unsigned first:1;
|
||||||
|
|
||||||
void (*receive_rtp)(struct impl *impl, uint8_t *buffer, ssize_t len);
|
int (*receive_rtp)(struct impl *impl, uint8_t *buffer, ssize_t len);
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "module-rtp/audio.c"
|
#include "module-rtp/audio.c"
|
||||||
|
|
@ -343,21 +343,24 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core,
|
||||||
if (pw_properties_get(props, PW_KEY_NODE_NETWORK) == NULL)
|
if (pw_properties_get(props, PW_KEY_NODE_NETWORK) == NULL)
|
||||||
pw_properties_set(props, PW_KEY_NODE_NETWORK, "true");
|
pw_properties_set(props, PW_KEY_NODE_NETWORK, "true");
|
||||||
|
|
||||||
|
impl->direct_timestamp = pw_properties_get_bool(props, "sess.ts-direct", false);
|
||||||
|
|
||||||
if (direction == PW_DIRECTION_INPUT) {
|
if (direction == PW_DIRECTION_INPUT) {
|
||||||
impl->ssrc = pw_properties_get_uint32(props, "rtp.sender-ssrc", pw_rand32());
|
impl->ssrc = pw_properties_get_uint32(props, "rtp.sender-ssrc", pw_rand32());
|
||||||
impl->ts_offset = pw_properties_get_uint32(props, "rtp.sender-ts-offset", pw_rand32());
|
impl->ts_offset = pw_properties_get_uint32(props, "rtp.sender-ts-offset", pw_rand32());
|
||||||
} else {
|
} else {
|
||||||
impl->ssrc = pw_properties_get_uint32(props, "rtp.receiver-ssrc", pw_rand32());
|
impl->have_ssrc = pw_properties_fetch_uint32(props, "rtp.receiver-ssrc", &impl->ssrc);
|
||||||
impl->ts_offset = pw_properties_get_uint32(props, "rtp.receiver-ts-offset", pw_rand32());
|
if (!pw_properties_fetch_uint32(props, "rtp.receiver-ts-offset", &impl->ts_offset))
|
||||||
|
impl->direct_timestamp = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl->payload = pw_properties_get_uint32(props, "rtp.payload", impl->payload);
|
impl->payload = pw_properties_get_uint32(props, "rtp.payload", impl->payload);
|
||||||
impl->mtu = pw_properties_get_uint32(props, "rtp.mtu", DEFAULT_MTU);
|
impl->mtu = pw_properties_get_uint32(props, "net.mtu", DEFAULT_MTU);
|
||||||
|
|
||||||
str = pw_properties_get(props, "rtp.min-ptime");
|
str = pw_properties_get(props, "sess.min-ptime");
|
||||||
if (!spa_atof(str, &min_ptime))
|
if (!spa_atof(str, &min_ptime))
|
||||||
min_ptime = DEFAULT_MIN_PTIME;
|
min_ptime = DEFAULT_MIN_PTIME;
|
||||||
str = pw_properties_get(props, "rtp.max-ptime");
|
str = pw_properties_get(props, "sess.max-ptime");
|
||||||
if (!spa_atof(str, &max_ptime))
|
if (!spa_atof(str, &max_ptime))
|
||||||
max_ptime = DEFAULT_MAX_PTIME;
|
max_ptime = DEFAULT_MAX_PTIME;
|
||||||
|
|
||||||
|
|
@ -376,6 +379,10 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core,
|
||||||
pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%d/%d",
|
pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%d/%d",
|
||||||
impl->target_buffer / 2, impl->rate);
|
impl->target_buffer / 2, impl->rate);
|
||||||
|
|
||||||
|
pw_properties_setf(props, "net.mtu", "%u", impl->mtu);
|
||||||
|
pw_properties_setf(props, "rtp.ptime", "%u",
|
||||||
|
impl->psamples * 1000 / impl->rate);
|
||||||
|
|
||||||
spa_dll_init(&impl->dll);
|
spa_dll_init(&impl->dll);
|
||||||
spa_dll_set_bw(&impl->dll, SPA_DLL_BW_MIN, 128, impl->rate);
|
spa_dll_set_bw(&impl->dll, SPA_DLL_BW_MIN, 128, impl->rate);
|
||||||
impl->corr = 1.0;
|
impl->corr = 1.0;
|
||||||
|
|
@ -462,6 +469,5 @@ void rtp_stream_destroy(struct rtp_stream *s)
|
||||||
int rtp_stream_receive_packet(struct rtp_stream *s, uint8_t *buffer, size_t len)
|
int rtp_stream_receive_packet(struct rtp_stream *s, uint8_t *buffer, size_t len)
|
||||||
{
|
{
|
||||||
struct impl *impl = (struct impl*)s;
|
struct impl *impl = (struct impl*)s;
|
||||||
impl->receive_rtp(impl, buffer, len);
|
return impl->receive_rtp(impl, buffer, len);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue