module-rtp: fix direct timestamps

fix some other properties.
This commit is contained in:
Wim Taymans 2023-03-06 10:46:21 +01:00
parent 3b685581a4
commit 8e5b9da177
6 changed files with 46 additions and 16 deletions

View file

@ -648,7 +648,8 @@ static struct session *session_new_announce(struct impl *impl, struct node *node
sdp->ntp = (uint32_t) time(NULL) + 2208988800U;
sess->props = props;
if ((str = pw_properties_get(props, "sess.name")) != NULL)
if ((str = pw_properties_get(props, "sess.name")) == NULL)
str = pw_get_host_name();
sdp->session_name = strdup(str);
if ((str = pw_properties_get(props, "rtp.destination.port")) == NULL)
@ -763,7 +764,7 @@ static int session_load_source(struct session *session, struct pw_properties *pr
return -EINVAL;
}
if ((str = pw_properties_get(props, "rtp.ts-offset")) != NULL)
pw_properties_set(props, "sess.ts-offset", str);
fprintf(f, "\"sess.ts-offset\" = %s, ", str);
fprintf(f, " stream.props = {");
pw_properties_serialize_dict(f, &props->dict, 0);

View file

@ -64,7 +64,7 @@
* - `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
* - `sess.media = <string>`: the media type audio|midi, default audio
* - `sess.media = <string>`: the media type audio|midi, default midi
* - `stream.props = {}`: properties to be passed to the stream
*
* ## General options
@ -487,6 +487,7 @@ static struct session *make_session(struct impl *impl, struct pw_properties *pro
{
struct session *sess;
const char *str;
struct pw_properties *copy;
sess = calloc(1, sizeof(struct session));
if (sess == NULL)
@ -507,15 +508,29 @@ static struct session *make_session(struct impl *impl, struct pw_properties *pro
pw_properties_setf(props, "rtp.sender-ssrc", "%u", sess->ssrc);
pw_properties_set(props, "rtp.session", sess->name);
copy = pw_properties_copy(props);
if (pw_properties_get(props, PW_KEY_MEDIA_CLASS) == NULL) {
const char *media = NULL;
str = pw_properties_get(props, "sess.media");
if (spa_streq(str, "midi"))
media = "Midi";
else if (spa_streq(str, "audio"))
media = "Audio";
if (media != NULL) {
pw_properties_setf(copy, PW_KEY_MEDIA_CLASS, "%s/Sink", media);
pw_properties_setf(props, PW_KEY_MEDIA_CLASS, "%s/Source", media);
}
}
sess->send = rtp_stream_new(impl->core,
PW_DIRECTION_INPUT, pw_properties_copy(props),
PW_DIRECTION_INPUT, copy,
&send_stream_events, sess);
sess->recv = rtp_stream_new(impl->core,
PW_DIRECTION_OUTPUT, pw_properties_copy(props),
PW_DIRECTION_OUTPUT, props,
&recv_stream_events, sess);
pw_properties_free(props);
return sess;
error:
pw_properties_free(props);

View file

@ -111,6 +111,8 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
#define DEFAULT_LOOP false
#define DEFAULT_DSCP 34 /* Default to AES-67 AF41 (34) */
#define DEFAULT_TS_OFFSET -1
#define USAGE "source.ip=<source IP address, default:"DEFAULT_SOURCE_IP"> " \
"destination.ip=<destination IP address, default:"DEFAULT_DESTINATION_IP"> " \
"destination.port=<int, default random beteen 46000 and 47024> " \
@ -395,6 +397,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
struct pw_properties *props = NULL, *stream_props = NULL;
char addr[64];
const char *str, *sess_name;
int64_t ts_offset;
int res = 0;
PW_LOG_TOPIC_INIT(mod_topic);
@ -460,6 +463,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
copy_props(impl, props, "sess.min-ptime");
copy_props(impl, props, "sess.max-ptime");
copy_props(impl, props, "sess.latency.msec");
copy_props(impl, props, "sess.ts-refclk");
str = pw_properties_get(props, "local.ifname");
impl->ifname = str ? strdup(str) : NULL;
@ -484,6 +488,11 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
impl->mcast_loop = pw_properties_get_bool(props, "net.loop", DEFAULT_LOOP);
impl->dscp = pw_properties_get_uint32(props, "net.dscp", DEFAULT_DSCP);
ts_offset = pw_properties_get_int64(props, "sess.ts-offset", DEFAULT_TS_OFFSET);
if (ts_offset == -1)
ts_offset = pw_rand32();
pw_properties_setf(stream_props, "rtp.sender-ts-offset", "%u", (uint32_t)ts_offset);
get_ip(&impl->src_addr, addr, sizeof(addr));
pw_properties_set(stream_props, "rtp.source.ip", addr);
get_ip(&impl->dst_addr, addr, sizeof(addr));

View file

@ -99,6 +99,8 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
#define DEFAULT_CLEANUP_SEC 60
#define DEFAULT_SOURCE_IP "224.0.0.56"
#define DEFAULT_TS_OFFSET -1
#define USAGE "local.ifname=<local interface name to use> " \
"source.ip=<source IP address, default:"DEFAULT_SOURCE_IP"> " \
"source.port=<int, source port> " \
@ -427,6 +429,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
const char *str, *sess_name;
struct timespec value, interval;
struct pw_properties *props, *stream_props;
int64_t ts_offset;
int res = 0;
PW_LOG_TOPIC_INIT(mod_topic);
@ -483,6 +486,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
copy_props(impl, props, "sess.min-ptime");
copy_props(impl, props, "sess.max-ptime");
copy_props(impl, props, "sess.latency.msec");
copy_props(impl, props, "sess.ts-direct");
str = pw_properties_get(props, "local.ifname");
impl->ifname = str ? strdup(str) : NULL;
@ -499,6 +503,11 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
goto out;
}
ts_offset = pw_properties_get_int64(props, "sess.ts-offset", DEFAULT_TS_OFFSET);
if (ts_offset == -1)
ts_offset = pw_rand32();
pw_properties_setf(stream_props, "rtp.receiver-ts-offset", "%u", (uint32_t)ts_offset);
impl->always_process = pw_properties_get_bool(stream_props,
PW_KEY_NODE_ALWAYS_PROCESS, true);

View file

@ -141,9 +141,9 @@ static int receive_rtp_audio(struct impl *impl, uint8_t *buffer, ssize_t len)
write = timestamp + impl->target_buffer;
if (!impl->have_sync) {
pw_log_info("sync to timestamp:%u seq:%u ts_offset:%u SSRC:%u direct:%d",
pw_log_info("sync to timestamp:%u seq:%u ts_offset:%u SSRC:%u target:%u direct:%u",
write, impl->seq-1, impl->ts_offset, impl->ssrc,
impl->direct_timestamp);
impl->target_buffer, impl->direct_timestamp);
/* we read from timestamp, keeping target_buffer of data
* in the ringbuffer. */

View file

@ -250,7 +250,7 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core,
const struct rtp_stream_events *events, void *data)
{
struct impl *impl;
const char *str, *media_class;
const char *str;
uint8_t buffer[1024];
struct spa_pod_builder b;
uint32_t n_params, min_samples, max_samples;
@ -301,7 +301,6 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core,
}
impl->stride = impl->format_info->size * impl->info.info.raw.channels;
impl->rate = impl->info.info.raw.rate;
media_class = direction == PW_DIRECTION_INPUT ? "Audio/Sink" : "Audio/Source";
break;
case SPA_MEDIA_TYPE_application:
impl->format_info = find_audio_format_info(&impl->info);
@ -314,7 +313,6 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core,
impl->rate = pw_properties_get_uint32(props, "midi.rate", 10000);
if (impl->rate == 0)
impl->rate = 10000;
media_class = direction == PW_DIRECTION_INPUT ? "Midi/Sink" : "Midi/Source";
break;
default:
spa_assert_not_reached();
@ -323,8 +321,6 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core,
pw_properties_setf(props, "rtp.mime", "%s", impl->format_info->mime);
if (pw_properties_get(props, PW_KEY_MEDIA_CLASS) == NULL)
pw_properties_set(props, PW_KEY_MEDIA_CLASS, media_class);
if (pw_properties_get(props, PW_KEY_NODE_VIRTUAL) == NULL)
pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true");
if (pw_properties_get(props, PW_KEY_NODE_NETWORK) == NULL)
@ -337,7 +333,7 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core,
impl->ts_offset = pw_properties_get_uint32(props, "rtp.sender-ts-offset", pw_rand32());
} else {
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))
if (pw_properties_fetch_uint32(props, "rtp.receiver-ts-offset", &impl->ts_offset) < 0)
impl->direct_timestamp = false;
}