mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 17:40:23 +00:00
allow specifiing multicast iface
This commit is contained in:
@@ -121,7 +121,8 @@ typedef void (*audio_device_help_t)(void);
|
||||
static void *audio_sender_thread(void *arg);
|
||||
static void *audio_receiver_thread(void *arg);
|
||||
static struct rtp *initialize_audio_network(char *addr, int recv_port,
|
||||
int send_port, struct pdb *participants, bool use_ipv6);
|
||||
int send_port, struct pdb *participants, bool use_ipv6,
|
||||
char *mcast_if);
|
||||
|
||||
static void audio_channel_map_usage(void);
|
||||
static void audio_scale_usage(void);
|
||||
@@ -159,7 +160,7 @@ static void audio_scale_usage(void)
|
||||
*/
|
||||
struct state_audio * audio_cfg_init(char *addrs, int recv_port, int send_port, char *send_cfg, char *recv_cfg,
|
||||
char *jack_cfg, char *fec_cfg, char *audio_channel_map, const char *audio_scale,
|
||||
bool echo_cancellation, bool use_ipv6)
|
||||
bool echo_cancellation, bool use_ipv6, char *mcast_if)
|
||||
{
|
||||
struct state_audio *s = NULL;
|
||||
char *tmp, *unused = NULL;
|
||||
@@ -227,8 +228,8 @@ struct state_audio * audio_cfg_init(char *addrs, int recv_port, int send_port, c
|
||||
addr = strtok_r(tmp, ",", &unused);
|
||||
if ((s->audio_network_device =
|
||||
initialize_audio_network(addr, recv_port, send_port,
|
||||
s->audio_participants, use_ipv6)) ==
|
||||
NULL) {
|
||||
s->audio_participants, use_ipv6, mcast_if))
|
||||
== NULL) {
|
||||
printf("Unable to open audio network\n");
|
||||
goto error;
|
||||
}
|
||||
@@ -344,13 +345,15 @@ void audio_done(struct state_audio *s)
|
||||
}
|
||||
|
||||
static struct rtp *initialize_audio_network(char *addr, int recv_port,
|
||||
int send_port, struct pdb *participants, bool use_ipv6) // GiX
|
||||
int send_port, struct pdb *participants, bool use_ipv6,
|
||||
char *mcast_if) // GiX
|
||||
{
|
||||
struct rtp *r;
|
||||
double rtcp_bw = 1024 * 512; // FIXME: something about 5% for rtcp is said in rfc
|
||||
|
||||
r = rtp_init(addr, recv_port, send_port, 255, rtcp_bw, FALSE, rtp_recv_callback,
|
||||
(void *)participants, use_ipv6);
|
||||
r = rtp_init_if(addr, mcast_if, recv_port, send_port, 255, rtcp_bw,
|
||||
FALSE, rtp_recv_callback, (void *)participants,
|
||||
use_ipv6);
|
||||
if (r != NULL) {
|
||||
pdb_add(participants, rtp_my_ssrc(r));
|
||||
rtp_set_option(r, RTP_OPT_WEAK_VALIDATION, TRUE);
|
||||
|
||||
@@ -72,7 +72,7 @@ audio_frame;
|
||||
|
||||
struct state_audio * audio_cfg_init(char *addrs, int recv_port, int send_port, char *send_cfg, char *recv_cfg,
|
||||
char *jack_cfg, char *fec_cfg, char *audio_channel_map, const char *audio_scale,
|
||||
bool echo_cancellation, bool use_ipv6);
|
||||
bool echo_cancellation, bool use_ipv6, char *mcast_iface);
|
||||
void audio_finish(struct state_audio *s);
|
||||
void audio_done(struct state_audio *s);
|
||||
void audio_join(struct state_audio *s);
|
||||
|
||||
@@ -127,6 +127,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
35
src/main.c
35
src/main.c
@@ -106,6 +106,7 @@
|
||||
#define AUDIO_SCALE (('a' << 8) | 's')
|
||||
#define ECHO_CANCELLATION (('E' << 8) | 'C')
|
||||
#define CUDA_DEVICE (('C' << 8) | 'D')
|
||||
#define MCAST_IF (('M' << 8) | 'I')
|
||||
|
||||
#ifdef HAVE_MACOSX
|
||||
#define INITIAL_VIDEO_RECV_BUFFER_SIZE 5944320
|
||||
@@ -175,7 +176,8 @@ static struct state_uv *uv_state;
|
||||
// prototypes
|
||||
//
|
||||
static struct rtp **initialize_network(char *addrs, int recv_port_base,
|
||||
int send_port_base, struct pdb *participants, bool use_ipv6);
|
||||
int send_port_base, struct pdb *participants, bool use_ipv6,
|
||||
char *mcast_if);
|
||||
|
||||
void list_video_display_devices(void);
|
||||
void list_video_capture_devices(void);
|
||||
@@ -228,9 +230,9 @@ static void usage(void)
|
||||
printf("\nUsage: uv [-d <display_device>] [-t <capture_device>] [-r <audio_playout>]\n");
|
||||
printf(" [-s <audio_caputre>] [-l <limit_bitrate>] "
|
||||
"[-m <mtu>] [-c] [-i] [-6]\n");
|
||||
printf(" [-M <video_mode>] [-p <postprocess>] "
|
||||
"[-f <FEC_options>] [-P <port>]\n");
|
||||
printf(" address(es)\n\n");
|
||||
printf(" [-m <video_mode>] [-p <postprocess>] "
|
||||
"[-f <fec_options>] [-p <port>]\n");
|
||||
printf(" [--mcast-if <iface>] address(es)\n\n");
|
||||
printf
|
||||
("\t-d <display_device> \tselect display device, use '-d help'\n");
|
||||
printf("\t \tto get list of supported devices\n");
|
||||
@@ -247,6 +249,8 @@ static void usage(void)
|
||||
printf("\t-6 \tUse IPv6\n");
|
||||
printf("\n");
|
||||
#endif // HAVE_IPv6
|
||||
printf("\t--mcast-if <iface> \tBind to specified interface for multicast\n");
|
||||
printf("\n");
|
||||
printf("\t-r <playback_device> \tAudio playback device (see '-r help')\n");
|
||||
printf("\n");
|
||||
printf("\t-s <capture_device> \tAudio capture device (see '-s help')\n");
|
||||
@@ -414,7 +418,8 @@ static void display_buf_increase_warning(int size)
|
||||
}
|
||||
|
||||
static struct rtp **initialize_network(char *addrs, int recv_port_base,
|
||||
int send_port_base, struct pdb *participants, bool use_ipv6)
|
||||
int send_port_base, struct pdb *participants, bool use_ipv6,
|
||||
char *mcast_if)
|
||||
{
|
||||
struct rtp **devices = NULL;
|
||||
double rtcp_bw = 5 * 1024 * 1024; /* FIXME */
|
||||
@@ -451,9 +456,10 @@ static struct rtp **initialize_network(char *addrs, int recv_port_base,
|
||||
if (send_port == send_port_base + 2)
|
||||
send_port += 2;
|
||||
|
||||
devices[index] = rtp_init(addr, recv_port, send_port, ttl, rtcp_bw,
|
||||
FALSE, rtp_recv_callback,
|
||||
(void *)participants, use_ipv6);
|
||||
devices[index] = rtp_init_if(addr, mcast_if, recv_port,
|
||||
send_port, ttl, rtcp_bw, FALSE,
|
||||
rtp_recv_callback, (void *)participants,
|
||||
use_ipv6);
|
||||
if (devices[index] != NULL) {
|
||||
rtp_set_option(devices[index], RTP_OPT_WEAK_VALIDATION,
|
||||
TRUE);
|
||||
@@ -861,6 +867,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
bool echo_cancellation = false;
|
||||
bool use_ipv6 = false;
|
||||
char *mcast_if = NULL;
|
||||
|
||||
int bitrate = 0;
|
||||
|
||||
@@ -906,6 +913,7 @@ int main(int argc, char *argv[])
|
||||
{"audio-capture-channels", required_argument, 0, AUDIO_CAPTURE_CHANNELS},
|
||||
{"echo-cancellation", no_argument, 0, ECHO_CANCELLATION},
|
||||
{"cuda-device", required_argument, 0, CUDA_DEVICE},
|
||||
{"mcast-if", required_argument, 0, MCAST_IF},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
int option_index = 0;
|
||||
@@ -1058,6 +1066,9 @@ int main(int argc, char *argv[])
|
||||
fprintf(stderr, "CUDA support is not enabled!\n");
|
||||
return EXIT_FAIL_USAGE;
|
||||
#endif // HAVE_CUDA
|
||||
case MCAST_IF:
|
||||
mcast_if = optarg;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
return EXIT_FAIL_USAGE;
|
||||
@@ -1104,8 +1115,10 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
char *tmp_requested_fec = strdup(DEFAULT_AUDIO_FEC);
|
||||
uv->audio = audio_cfg_init (network_device, uv->recv_port_number + 2, uv->send_port_number + 2, audio_send, audio_recv, jack_cfg,
|
||||
tmp_requested_fec, audio_channel_map, audio_scale, echo_cancellation, use_ipv6);
|
||||
uv->audio = audio_cfg_init (network_device, uv->recv_port_number + 2,
|
||||
uv->send_port_number + 2, audio_send, audio_recv,
|
||||
jack_cfg, tmp_requested_fec, audio_channel_map,
|
||||
audio_scale, echo_cancellation, use_ipv6, mcast_if);
|
||||
free(tmp_requested_fec);
|
||||
if(!uv->audio)
|
||||
goto cleanup;
|
||||
@@ -1226,7 +1239,7 @@ int main(int argc, char *argv[])
|
||||
} else {
|
||||
if ((uv->network_devices =
|
||||
initialize_network(network_device, uv->recv_port_number,
|
||||
uv->send_port_number, uv->participants, use_ipv6))
|
||||
uv->send_port_number, uv->participants, use_ipv6, mcast_if))
|
||||
== NULL) {
|
||||
printf("Unable to open network\n");
|
||||
exit_uv(EXIT_FAIL_NETWORK);
|
||||
|
||||
@@ -271,7 +271,7 @@ static socket_udp *udp_init4(const char *addr, const char *iface,
|
||||
int reuse = 1;
|
||||
int udpbufsize = 16 * 1024 * 1024;
|
||||
struct sockaddr_in s_in;
|
||||
struct in_addr iface_addr;
|
||||
unsigned int ifindex;
|
||||
socket_udp *s = (socket_udp *) malloc(sizeof(socket_udp));
|
||||
s->mode = IPv4;
|
||||
s->addr = NULL;
|
||||
@@ -288,13 +288,13 @@ static socket_udp *udp_init4(const char *addr, const char *iface,
|
||||
memcpy(&(s->addr4), h->h_addr_list[0], sizeof(s->addr4));
|
||||
}
|
||||
if (iface != NULL) {
|
||||
if (inet_pton(AF_INET, iface, &iface_addr) != 1) {
|
||||
if ((ifindex = if_nametoindex(iface)) == 0) {
|
||||
debug_msg("Illegal interface specification\n");
|
||||
free(s);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
iface_addr.s_addr = 0;
|
||||
ifindex = 0;
|
||||
}
|
||||
s->fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s->fd < 0) {
|
||||
@@ -337,7 +337,7 @@ static socket_udp *udp_init4(const char *addr, const char *iface,
|
||||
struct ip_mreq imr;
|
||||
|
||||
imr.imr_multiaddr.s_addr = s->addr4.s_addr;
|
||||
imr.imr_interface.s_addr = iface_addr.s_addr;
|
||||
imr.imr_interface.s_addr = ifindex;
|
||||
|
||||
if (SETSOCKOPT
|
||||
(s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&imr,
|
||||
@@ -359,13 +359,11 @@ static socket_udp *udp_init4(const char *addr, const char *iface,
|
||||
socket_error("setsockopt IP_MULTICAST_TTL");
|
||||
return NULL;
|
||||
}
|
||||
if (iface_addr.s_addr != 0) {
|
||||
if (SETSOCKOPT
|
||||
(s->fd, IPPROTO_IP, IP_MULTICAST_IF,
|
||||
(char *)&iface_addr, sizeof(iface_addr)) != 0) {
|
||||
socket_error("setsockopt IP_MULTICAST_IF");
|
||||
return NULL;
|
||||
}
|
||||
if (SETSOCKOPT
|
||||
(s->fd, IPPROTO_IP, IP_MULTICAST_IF,
|
||||
(char *)&ifindex, sizeof(ifindex)) != 0) {
|
||||
socket_error("setsockopt IP_MULTICAST_IF");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
s->addr = strdup(addr);
|
||||
@@ -541,11 +539,17 @@ static socket_udp *udp_init6(const char *addr, const char *iface,
|
||||
s->tx_port = tx_port;
|
||||
s->ttl = ttl;
|
||||
struct addrinfo hints, *res0;
|
||||
unsigned int ifindex;
|
||||
int err;
|
||||
|
||||
if (iface != NULL) {
|
||||
debug_msg("Not yet implemented\n");
|
||||
abort();
|
||||
if ((ifindex = if_nametoindex(iface)) == 0) {
|
||||
debug_msg("Illegal interface specification\n");
|
||||
free(s);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
ifindex = 0;
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
@@ -607,7 +611,7 @@ static socket_udp *udp_init6(const char *addr, const char *iface,
|
||||
imr.i6mr_multiaddr = s->addr6;
|
||||
#else
|
||||
imr.ipv6mr_multiaddr = s->addr6;
|
||||
imr.ipv6mr_interface = 0;
|
||||
imr.ipv6mr_interface = ifindex;
|
||||
#endif
|
||||
|
||||
if (SETSOCKOPT
|
||||
@@ -629,6 +633,11 @@ static socket_udp *udp_init6(const char *addr, const char *iface,
|
||||
socket_error("setsockopt IPV6_MULTICAST_HOPS");
|
||||
return NULL;
|
||||
}
|
||||
if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
|
||||
(char *)&ifindex, sizeof(ifindex)) != 0) {
|
||||
socket_error("setsockopt IPV6_MULTICAST_IF");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
assert(s != NULL);
|
||||
@@ -722,7 +731,8 @@ static const char *udp_host_addr6(socket_udp * s)
|
||||
int gai_err, newsock;
|
||||
struct addrinfo hints, *ai;
|
||||
struct sockaddr_in6 local, addr6;
|
||||
int len = sizeof(local), result = 0;
|
||||
socklen_t len = sizeof(local);
|
||||
int result = 0;
|
||||
|
||||
newsock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
memset((char *)&addr6, 0, len);
|
||||
|
||||
Reference in New Issue
Block a user