module-rtp: improve properties and some cleanups

This commit is contained in:
Wim Taymans 2023-03-02 17:18:43 +01:00
parent c46e021734
commit 7a31278511
4 changed files with 45 additions and 32 deletions

View file

@ -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");

View file

@ -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

View file

@ -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)

View file

@ -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;
} }