mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
ptp: Add ttl
configuration to gst_ptp_init_full()
This allows configuring the TTL that is used for multicast packets sent out on the sockets, and is defaulting to 1 as before. The default might change at some point. In some networks multiple hops are needed to reach the PTP clock and this allows to configure GStreamer in a way that works in such networks. At a later time, per-domain or per-interface TTL configurations might be added when needed. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5649>
This commit is contained in:
parent
12159cb294
commit
ba5684d0d7
3 changed files with 27 additions and 8 deletions
|
@ -21,6 +21,7 @@ pub struct Args {
|
||||||
pub interfaces: Vec<String>,
|
pub interfaces: Vec<String>,
|
||||||
pub verbose: bool,
|
pub verbose: bool,
|
||||||
pub clock_id: u64,
|
pub clock_id: u64,
|
||||||
|
pub ttl: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse the command-line arguments.
|
/// Parse the command-line arguments.
|
||||||
|
@ -28,6 +29,7 @@ pub fn parse_args() -> Result<Args, Error> {
|
||||||
let mut interfaces = Vec::new();
|
let mut interfaces = Vec::new();
|
||||||
let mut verbose = false;
|
let mut verbose = false;
|
||||||
let mut clock_id = 0;
|
let mut clock_id = 0;
|
||||||
|
let mut ttl = 1;
|
||||||
|
|
||||||
let mut args = env::args();
|
let mut args = env::args();
|
||||||
// Skip executable name
|
// Skip executable name
|
||||||
|
@ -50,6 +52,11 @@ pub fn parse_args() -> Result<Args, Error> {
|
||||||
clock_id =
|
clock_id =
|
||||||
u64::from_str_radix(&clock_id_arg[2..], 16).context("Invalid clock ID")?;
|
u64::from_str_radix(&clock_id_arg[2..], 16).context("Invalid clock ID")?;
|
||||||
}
|
}
|
||||||
|
"--ttl" => {
|
||||||
|
let ttl_arg = args.next().context("No TTL following --ttl")?;
|
||||||
|
ttl = ttl_arg.parse::<u32>().context("Invalid TTL value")?;
|
||||||
|
}
|
||||||
|
|
||||||
arg => {
|
arg => {
|
||||||
bail!("Unknown command-line argument {}", arg);
|
bail!("Unknown command-line argument {}", arg);
|
||||||
}
|
}
|
||||||
|
@ -60,6 +67,7 @@ pub fn parse_args() -> Result<Args, Error> {
|
||||||
interfaces,
|
interfaces,
|
||||||
verbose,
|
verbose,
|
||||||
clock_id,
|
clock_id,
|
||||||
|
ttl,
|
||||||
};
|
};
|
||||||
|
|
||||||
info!("Running with arguments {:#?}", args);
|
info!("Running with arguments {:#?}", args);
|
||||||
|
|
|
@ -58,16 +58,18 @@ const MSG_TYPE_CLOCK_ID: u8 = 2;
|
||||||
const MSG_TYPE_SEND_TIME_ACK: u8 = 3;
|
const MSG_TYPE_SEND_TIME_ACK: u8 = 3;
|
||||||
|
|
||||||
/// Create a new `UdpSocket` for the given port and configure it for PTP.
|
/// Create a new `UdpSocket` for the given port and configure it for PTP.
|
||||||
fn create_socket(port: u16, iface: &net::InterfaceInfo) -> Result<UdpSocket, Error> {
|
fn create_socket(port: u16, iface: &net::InterfaceInfo, ttl: u32) -> Result<UdpSocket, Error> {
|
||||||
let socket = net::create_udp_socket(&Ipv4Addr::UNSPECIFIED, port, Some(iface))
|
let socket = net::create_udp_socket(&Ipv4Addr::UNSPECIFIED, port, Some(iface))
|
||||||
.with_context(|| format!("Failed to bind socket to port {}", port))?;
|
.with_context(|| format!("Failed to bind socket to port {}", port))?;
|
||||||
|
|
||||||
socket
|
socket
|
||||||
.set_nonblocking(true)
|
.set_nonblocking(true)
|
||||||
.context("Failed setting socket non-blocking")?;
|
.context("Failed setting socket non-blocking")?;
|
||||||
socket.set_ttl(1).context("Failed setting TTL on socket")?;
|
|
||||||
socket
|
socket
|
||||||
.set_multicast_ttl_v4(1)
|
.set_ttl(ttl)
|
||||||
|
.context("Failed setting TTL on socket")?;
|
||||||
|
socket
|
||||||
|
.set_multicast_ttl_v4(ttl)
|
||||||
.context("Failed to set multicast TTL on socket")?;
|
.context("Failed to set multicast TTL on socket")?;
|
||||||
|
|
||||||
Ok(socket)
|
Ok(socket)
|
||||||
|
@ -123,10 +125,10 @@ fn run() -> Result<(), Error> {
|
||||||
for iface in &ifaces {
|
for iface in &ifaces {
|
||||||
info!("Binding to interface {}", iface.name);
|
info!("Binding to interface {}", iface.name);
|
||||||
|
|
||||||
let event_socket =
|
let event_socket = create_socket(PTP_EVENT_PORT, iface, args.ttl)
|
||||||
create_socket(PTP_EVENT_PORT, iface).context("Failed creating event socket")?;
|
.context("Failed creating event socket")?;
|
||||||
let general_socket =
|
let general_socket = create_socket(PTP_GENERAL_PORT, iface, args.ttl)
|
||||||
create_socket(PTP_GENERAL_PORT, iface).context("Failed creating general socket")?;
|
.context("Failed creating general socket")?;
|
||||||
|
|
||||||
for socket in [&event_socket, &general_socket].iter() {
|
for socket in [&event_socket, &general_socket].iter() {
|
||||||
net::join_multicast_v4(socket, &PTP_MULTICAST_ADDR, iface)
|
net::join_multicast_v4(socket, &PTP_MULTICAST_ADDR, iface)
|
||||||
|
|
|
@ -2680,6 +2680,8 @@ count_directories (const char *filepath)
|
||||||
* interface.
|
* interface.
|
||||||
* * #GStrv `interfaces`: The interface names to listen on for PTP packets. If
|
* * #GStrv `interfaces`: The interface names to listen on for PTP packets. If
|
||||||
* none are provided then all compatible interfaces will be used.
|
* none are provided then all compatible interfaces will be used.
|
||||||
|
* * #guint `ttl`: The TTL to use for multicast packets sent out by GStreamer.
|
||||||
|
* This defaults to 1, i.e. packets will not leave the local network.
|
||||||
*
|
*
|
||||||
* This function is automatically called by gst_ptp_clock_new() with default
|
* This function is automatically called by gst_ptp_clock_new() with default
|
||||||
* parameters if it wasn't called before.
|
* parameters if it wasn't called before.
|
||||||
|
@ -2698,6 +2700,7 @@ gst_ptp_init_full (const GstStructure * config)
|
||||||
guint64 clock_id = GST_CLOCK_TIME_NONE;
|
guint64 clock_id = GST_CLOCK_TIME_NONE;
|
||||||
const GValue *v;
|
const GValue *v;
|
||||||
gchar **interfaces = NULL;
|
gchar **interfaces = NULL;
|
||||||
|
guint ttl = 1;
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (ptp_debug, "ptp", 0, "PTP clock");
|
GST_DEBUG_CATEGORY_INIT (ptp_debug, "ptp", 0, "PTP clock");
|
||||||
|
@ -2726,7 +2729,7 @@ gst_ptp_init_full (const GstStructure * config)
|
||||||
}
|
}
|
||||||
|
|
||||||
argc = 1;
|
argc = 1;
|
||||||
gst_structure_get_uint64(config, "clock-id", &clock_id);
|
gst_structure_get_uint64 (config, "clock-id", &clock_id);
|
||||||
if (clock_id != GST_PTP_CLOCK_ID_NONE)
|
if (clock_id != GST_PTP_CLOCK_ID_NONE)
|
||||||
argc += 2;
|
argc += 2;
|
||||||
v = gst_structure_get_value (config, "interfaces");
|
v = gst_structure_get_value (config, "interfaces");
|
||||||
|
@ -2734,7 +2737,10 @@ gst_ptp_init_full (const GstStructure * config)
|
||||||
interfaces = g_value_get_boxed (v);
|
interfaces = g_value_get_boxed (v);
|
||||||
if (interfaces != NULL)
|
if (interfaces != NULL)
|
||||||
argc += 2 * g_strv_length (interfaces);
|
argc += 2 * g_strv_length (interfaces);
|
||||||
|
gst_structure_get_uint (config, "ttl", &ttl);
|
||||||
|
argc += 2;
|
||||||
|
|
||||||
|
// 3 for: executable, -v and NULL
|
||||||
argv = g_new0 (gchar *, argc + 3);
|
argv = g_new0 (gchar *, argc + 3);
|
||||||
argc_c = 0;
|
argc_c = 0;
|
||||||
|
|
||||||
|
@ -2814,6 +2820,9 @@ gst_ptp_init_full (const GstStructure * config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
argv[argc_c++] = g_strdup ("--ttl");
|
||||||
|
argv[argc_c++] = g_strdup_printf ("%u", ttl);
|
||||||
|
|
||||||
/* Check if the helper process should be verbose */
|
/* Check if the helper process should be verbose */
|
||||||
env = g_getenv ("GST_PTP_HELPER_VERBOSE");
|
env = g_getenv ("GST_PTP_HELPER_VERBOSE");
|
||||||
if (env && g_ascii_strcasecmp (env, "no") != 0) {
|
if (env && g_ascii_strcasecmp (env, "no") != 0) {
|
||||||
|
|
Loading…
Reference in a new issue