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
* - `sess.min-ptime = <int>`: minimum packet time in milliseconds, default 2
* - `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.ts-offset = <int>`: an offset to apply to the timestamp, default -1 = random offset
* - `sess.ts-refclk = <string>`: the name of a reference clock
@ -238,8 +239,7 @@ struct impl {
char *ifname;
char *session_name;
uint32_t mtu;
bool ttl;
uint32_t ttl;
bool mcast_loop;
int32_t ts_offset;
char *ts_refclk;
@ -451,6 +451,7 @@ static void free_session(struct session *sess)
rtp_stream_destroy(sess->send);
if (sess->recv)
rtp_stream_destroy(sess->recv);
free(sess->name);
free(sess);
}
@ -500,11 +501,12 @@ static struct session *make_session(struct impl *impl, struct pw_properties *pro
sess->ssrc = pw_rand32();
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)
pw_properties_setf(props, "rtp.sender-ts-offset", "%u", impl->ts_offset);
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,
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")) {
pw_properties_set(props,
"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")) {
uint32_t v;
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_MEDIA_NAME);
copy_props(impl, props, PW_KEY_MEDIA_CLASS);
copy_props(impl, props, "net.mtu");
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) {
str = "midi";
@ -1497,10 +1509,6 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
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,
"sess.ts-offset", pw_rand32());
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);
}
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;
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)
goto invalid_version;
hlen = 12 + hdr->cc * 4;
if (hlen > len)
goto invalid_len;
@ -175,22 +174,22 @@ static void receive_rtp_audio(struct impl *impl, uint8_t *buffer, ssize_t len)
write += samples;
spa_ringbuffer_write_update(&impl->ring, write);
}
return;
return 0;
short_packet:
pw_log_warn("short packet received");
return;
return -EINVAL;
invalid_version:
pw_log_warn("invalid RTP version");
spa_debug_mem(0, buffer, len);
return;
return -EPROTO;
invalid_len:
pw_log_warn("invalid RTP length");
return;
return -EINVAL;
unexpected_ssrc:
pw_log_warn("unexpected SSRC (expected %u != %u)",
impl->ssrc, hdr->ssrc);
return;
return -EINVAL;
}
static inline void

View file

@ -143,7 +143,7 @@ static double get_time(struct impl *impl)
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 write;
@ -207,7 +207,7 @@ static void receive_midi(struct impl *impl, uint8_t *packet,
filled = spa_ringbuffer_get_write_index(&impl->ring, &write);
if (filled > (int32_t)BUFFER_SIZE2) {
pw_log_warn("overflow");
return;
return -ENOSPC;
}
hdr = (struct rtp_midi_header *)&packet[offs++];
@ -219,7 +219,7 @@ static void receive_midi(struct impl *impl, uint8_t *packet,
end = len + offs;
if (end > plen) {
pw_log_warn("invalid packet %d > %d", end, plen);
return;
return -EINVAL;
}
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;
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;
ssize_t hlen;
@ -296,23 +297,22 @@ static void receive_rtp_midi(struct impl *impl, uint8_t *buffer, ssize_t len)
impl->receiving = true;
receive_midi(impl, buffer, timestamp, hlen, len);
return;
return receive_midi(impl, buffer, timestamp, hlen, len);
short_packet:
pw_log_warn("short packet received");
return;
return -EINVAL;
invalid_version:
pw_log_warn("invalid RTP version");
spa_debug_mem(0, buffer, len);
return;
return -EPROTO;
invalid_len:
pw_log_warn("invalid RTP length");
return;
return -EINVAL;
unexpected_ssrc:
pw_log_warn("unexpected SSRC (expected %u != %u)",
impl->ssrc, hdr->ssrc);
return;
return -EINVAL;
}
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 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"
@ -343,21 +343,24 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core,
if (pw_properties_get(props, PW_KEY_NODE_NETWORK) == NULL)
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) {
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());
} else {
impl->ssrc = pw_properties_get_uint32(props, "rtp.receiver-ssrc", pw_rand32());
impl->ts_offset = pw_properties_get_uint32(props, "rtp.receiver-ts-offset", pw_rand32());
impl->have_ssrc = pw_properties_fetch_uint32(props, "rtp.receiver-ssrc", &impl->ssrc);
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->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))
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))
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",
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_set_bw(&impl->dll, SPA_DLL_BW_MIN, 128, impl->rate);
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)
{
struct impl *impl = (struct impl*)s;
impl->receive_rtp(impl, buffer, len);
return 0;
return impl->receive_rtp(impl, buffer, len);
}