module-rtp: improve SSRC, seq and timestamp randomness

This commit is contained in:
Wim Taymans 2023-02-22 11:54:27 +01:00
parent eca9bbf73b
commit 56d2e1e880
3 changed files with 33 additions and 14 deletions

View file

@ -647,7 +647,9 @@ static struct session *session_new_announce(struct impl *impl, struct node *node
sess->announce = true; sess->announce = true;
sdp->hash = rand(); if ((res = pw_getrandom(&sdp->hash, sizeof(sdp->hash), 0)) < 0)
return NULL;
sdp->ntp = (uint32_t) time(NULL) + 2208988800U; sdp->ntp = (uint32_t) time(NULL) + 2208988800U;
sess->props = props; sess->props = props;

View file

@ -361,7 +361,8 @@ static void stream_audio_process(struct impl *impl)
} }
} }
if (!impl->sync) { if (!impl->sync) {
pw_log_info("sync to timestamp %u ts_offset:%u", timestamp, impl->ts_offset); pw_log_info("sync to timestamp:%u seq:%u ts_offset:%u SSRC:%u",
timestamp, impl->seq, impl->ts_offset, impl->ssrc);
impl->ring.readindex = impl->ring.writeindex = timestamp; impl->ring.readindex = impl->ring.writeindex = timestamp;
memset(impl->buffer, 0, BUFFER_SIZE); memset(impl->buffer, 0, BUFFER_SIZE);
impl->sync = true; impl->sync = true;
@ -533,7 +534,8 @@ static void stream_midi_process(void *data)
goto done; goto done;
if (!impl->sync) { if (!impl->sync) {
pw_log_info("sync to timestamp %u", timestamp); pw_log_info("sync to timestamp:%u seq:%u ts_offset:%u SSRC:%u",
timestamp, impl->seq, impl->ts_offset, impl->ssrc);
impl->sync = true; impl->sync = true;
if (impl->apple_midi) if (impl->apple_midi)
send_cmd(impl); send_cmd(impl);
@ -890,6 +892,16 @@ static void copy_props(struct impl *impl, struct pw_properties *props, const cha
} }
} }
static uint32_t make_random(void)
{
int res;
uint32_t val;
do {
res = pw_getrandom(&val, sizeof(val), 0);
} while ((res == -1) && (errno == EINTR));
return val;
}
SPA_EXPORT SPA_EXPORT
int pipewire__module_init(struct pw_impl_module *module, const char *args) int pipewire__module_init(struct pw_impl_module *module, const char *args)
{ {
@ -1008,8 +1020,8 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
break; break;
} }
impl->payload = 127; impl->payload = 127;
impl->seq = rand(); impl->seq = make_random();
impl->ssrc = rand(); impl->ssrc = make_random();
str = pw_properties_get(props, "local.ifname"); str = pw_properties_get(props, "local.ifname");
impl->ifname = str ? strdup(str) : NULL; impl->ifname = str ? strdup(str) : NULL;
@ -1021,7 +1033,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
goto out; goto out;
} }
impl->dst_port = DEFAULT_PORT + ((uint32_t) (rand() % 512) << 1); impl->dst_port = DEFAULT_PORT + ((uint32_t) (make_random() % 512) << 1);
impl->dst_port = pw_properties_get_uint32(props, "destination.port", impl->dst_port); impl->dst_port = pw_properties_get_uint32(props, "destination.port", impl->dst_port);
if ((str = pw_properties_get(props, "destination.ip")) == NULL) if ((str = pw_properties_get(props, "destination.ip")) == NULL)
str = DEFAULT_DESTINATION_IP; str = DEFAULT_DESTINATION_IP;
@ -1036,7 +1048,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
impl->dscp = pw_properties_get_uint32(props, "net.dscp", DEFAULT_DSCP); impl->dscp = pw_properties_get_uint32(props, "net.dscp", DEFAULT_DSCP);
ts_offset = pw_properties_get_int64(props, "sess.ts-offset", DEFAULT_TS_OFFSET); ts_offset = pw_properties_get_int64(props, "sess.ts-offset", DEFAULT_TS_OFFSET);
impl->ts_offset = ts_offset < 0 ? rand() : ts_offset; impl->ts_offset = ts_offset < 0 ? make_random() : ts_offset;
str = pw_properties_get(props, "sess.ts-refclk"); str = pw_properties_get(props, "sess.ts-refclk");
impl->ts_refclk = str ? strdup(str) : NULL; impl->ts_refclk = str ? strdup(str) : NULL;

View file

@ -330,8 +330,10 @@ static void receive_audio(struct impl *impl, uint8_t *packet,
write = timestamp + impl->target_buffer; write = timestamp + impl->target_buffer;
if (!impl->have_sync) { if (!impl->have_sync) {
pw_log_info("sync to timestamp %u direct:%d ts_offset:%u", pw_log_info("sync to timestamp:%u seq:%u ts_offset:%u SSRC:%u direct:%d",
write, impl->direct_timestamp, impl->ts_offset); write, impl->expected_seq-1, impl->ts_offset, impl->expected_ssrc,
impl->direct_timestamp);
/* we read from timestamp, keeping target_buffer of data /* we read from timestamp, keeping target_buffer of data
* in the ringbuffer. */ * in the ringbuffer. */
impl->ring.readindex = timestamp; impl->ring.readindex = timestamp;
@ -509,8 +511,9 @@ static void receive_midi(struct impl *impl, uint8_t *packet,
/* in direct timestamp we attach the RTP timestamp directly on the /* in direct timestamp we attach the RTP timestamp directly on the
* midi events and render them in the corresponding cycle */ * midi events and render them in the corresponding cycle */
if (!impl->have_sync) { if (!impl->have_sync) {
pw_log_info("sync to timestamp %u/ direct:%d", timestamp, pw_log_info("sync to timestamp:%u seq:%u ts_offset:%u SSRC:%u direct:%d",
impl->direct_timestamp); timestamp, impl->expected_seq-1, impl->ts_offset, impl->expected_ssrc,
impl->direct_timestamp);
impl->have_sync = true; impl->have_sync = true;
} }
} else { } else {
@ -534,8 +537,9 @@ static void receive_midi(struct impl *impl, uint8_t *packet,
impl->corr = 1.0; impl->corr = 1.0;
spa_dll_set_bw(&impl->dll, SPA_DLL_BW_MIN, 256, impl->rate); spa_dll_set_bw(&impl->dll, SPA_DLL_BW_MIN, 256, impl->rate);
pw_log_info("sync to timestamp %u/%f direct:%d", timestamp, t, pw_log_info("sync to timestamp:%u seq:%u ts_offset:%u SSRC:%u direct:%d",
impl->direct_timestamp); timestamp, impl->expected_seq-1, impl->ts_offset, impl->expected_ssrc,
impl->direct_timestamp);
impl->have_sync = true; impl->have_sync = true;
impl->ring.readindex = impl->ring.writeindex; impl->ring.readindex = impl->ring.writeindex;
} else { } else {
@ -670,7 +674,8 @@ on_rtp_io(void *data, int fd, uint32_t mask)
seq = ntohs(hdr->sequence_number); seq = ntohs(hdr->sequence_number);
if (impl->have_seq && impl->expected_seq != seq) { if (impl->have_seq && impl->expected_seq != seq) {
pw_log_info("unexpected seq (%d != %d)", seq, impl->expected_seq); pw_log_info("unexpected seq (%d != %d) SSRC:%u",
seq, impl->expected_seq, hdr->ssrc);
impl->have_sync = false; impl->have_sync = false;
} }
impl->expected_seq = seq + 1; impl->expected_seq = seq + 1;