From ab736aa59095e90e42d3ebca4b0a7dd571a358ba Mon Sep 17 00:00:00 2001 From: "Castillo, Gerard" Date: Wed, 4 Sep 2013 14:46:33 +0200 Subject: [PATCH] rtp session init refactor. no rtcp between ug and rtsp server. --- src/rtp/net_udp.c | 185 +++++++++++++++++++++++---------------- src/rtp/rtp.c | 12 ++- src/rtp/rtpdec_h264.c | 43 +++++++++ src/rtp/rtpdec_h264.h | 43 +++++++++ src/video_capture/rtsp.c | 5 +- 5 files changed, 208 insertions(+), 80 deletions(-) diff --git a/src/rtp/net_udp.c b/src/rtp/net_udp.c index 8917e1ddc..f038c28d5 100644 --- a/src/rtp/net_udp.c +++ b/src/rtp/net_udp.c @@ -2,7 +2,10 @@ * FILE: net_udp.c * AUTHOR: Colin Perkins * MODIFIED: Orion Hodson & Piers O'Hanlon + * David Cassany + * Gerard Castillo * + * Copyright (c) 2005-2010 Fundació i2CAT, Internet I Innovació Digital a Catalunya * Copyright (c) 1998-2000 University College London * All rights reserved. * @@ -267,6 +270,92 @@ static int udp_addr_valid4(const char *dst) return FALSE; } +static int udp_init4_tx(socket_udp *s, const char *addr, const char *iface, + uint16_t tx_port, int udpbufsize, unsigned int ifindex) +{ + if (!resolve_address(s, addr)) { + socket_error("Can't resolve IP address for %s", addr); + free(s); + return 1; + } + if (iface != NULL) { +#ifdef HAVE_IF_NAMETOINDEX + if ((ifindex = if_nametoindex(iface)) == 0) { + debug_msg("Illegal interface specification\n"); + free(s); + return 1; + } +#else + fprintf(stderr, "Cannot set interface name, if_nametoindex not supported.\n"); +#endif + } else { + ifindex = 0; + } + if (SETSOCKOPT + (s->fd, SOL_SOCKET, SO_SNDBUF, (char *)&udpbufsize, + sizeof(udpbufsize)) != 0) { + debug_msg("WARNING: Unable to increase UDP sendbuffer\n"); + } + + if (IN_MULTICAST(ntohl(s->addr4.s_addr))) { +#ifndef WIN32 + char loop = 1; +#endif + struct ip_mreq imr; + + imr.imr_multiaddr.s_addr = s->addr4.s_addr; + imr.imr_interface.s_addr = ifindex; + + if (SETSOCKOPT + (s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&imr, + sizeof(struct ip_mreq)) != 0) { + socket_error("setsockopt IP_ADD_MEMBERSHIP"); + return 1; + } +#ifndef WIN32 + if (SETSOCKOPT + (s->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, + sizeof(loop)) != 0) { + socket_error("setsockopt IP_MULTICAST_LOOP"); + return 1; + } +#endif + if (SETSOCKOPT + (s->fd, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&s->ttl, + sizeof(s->ttl)) != 0) { + socket_error("setsockopt IP_MULTICAST_TTL"); + return 1; + } + if (SETSOCKOPT + (s->fd, IPPROTO_IP, IP_MULTICAST_IF, + (char *)&ifindex, sizeof(ifindex)) != 0) { + socket_error("setsockopt IP_MULTICAST_IF"); + return 1; + } + } + s->addr = strdup(addr); + return 0; +} + +static int udp_init4_rx(socket_udp *s, uint16_t rx_port, + int udpbufsize, struct sockaddr_in s_in) +{ + if (SETSOCKOPT + (s->fd, SOL_SOCKET, SO_RCVBUF, (char *)&udpbufsize, + sizeof(udpbufsize)) != 0) { + debug_msg("WARNING: Unable to increase UDP recvbuffer\n"); + } + s_in.sin_family = AF_INET; + s_in.sin_addr.s_addr = INADDR_ANY; + s_in.sin_port = htons(rx_port); + if (bind(s->fd, (struct sockaddr *)&s_in, sizeof(s_in)) != 0) { + socket_error("bind"); + return -1; + } + + return 0; +} + static socket_udp *udp_init4(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl) { @@ -281,24 +370,7 @@ static socket_udp *udp_init4(const char *addr, const char *iface, s->tx_port = tx_port; s->ttl = ttl; - if (!resolve_address(s, addr)) { - socket_error("Can't resolve IP address for %s", addr); - free(s); - return NULL; - } - if (iface != NULL) { -#ifdef HAVE_IF_NAMETOINDEX - if ((ifindex = if_nametoindex(iface)) == 0) { - debug_msg("Illegal interface specification\n"); - free(s); - return NULL; - } -#else - fprintf(stderr, "Cannot set interface name, if_nametoindex not supported.\n"); -#endif - } else { - ifindex = 0; - } + s->fd = socket(AF_INET, SOCK_DGRAM, 0); #ifdef WIN32 if (s->fd == INVALID_SOCKET) { @@ -308,16 +380,7 @@ static socket_udp *udp_init4(const char *addr, const char *iface, socket_error("Unable to initialize socket"); return NULL; } - if (SETSOCKOPT - (s->fd, SOL_SOCKET, SO_SNDBUF, (char *)&udpbufsize, - sizeof(udpbufsize)) != 0) { - debug_msg("WARNING: Unable to increase UDP sendbuffer\n"); - } - if (SETSOCKOPT - (s->fd, SOL_SOCKET, SO_RCVBUF, (char *)&udpbufsize, - sizeof(udpbufsize)) != 0) { - debug_msg("WARNING: Unable to increase UDP recvbuffer\n"); - } + if (SETSOCKOPT (s->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) != 0) { @@ -332,50 +395,19 @@ static socket_udp *udp_init4(const char *addr, const char *iface, return NULL; } #endif - s_in.sin_family = AF_INET; - s_in.sin_addr.s_addr = INADDR_ANY; - s_in.sin_port = htons(rx_port); - if (bind(s->fd, (struct sockaddr *)&s_in, sizeof(s_in)) != 0) { - socket_error("bind"); - return NULL; - } - if (IN_MULTICAST(ntohl(s->addr4.s_addr))) { -#ifndef WIN32 - char loop = 1; -#endif - struct ip_mreq imr; - imr.imr_multiaddr.s_addr = s->addr4.s_addr; - imr.imr_interface.s_addr = ifindex; + if (rx_port == 0) + debug_msg("No valid receive port, no receive session defined"); + else + if (udp_init4_rx(s, rx_port, udpbufsize, s_in) != 0) + return NULL; + + if (addr == NULL && tx_port == 0) + debug_msg("No valid transmit port, no transmit session defined"); + else + if (udp_init4_tx(s, addr, iface, tx_port, udpbufsize, ifindex) != 0) + return NULL; - if (SETSOCKOPT - (s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&imr, - sizeof(struct ip_mreq)) != 0) { - socket_error("setsockopt IP_ADD_MEMBERSHIP"); - return NULL; - } -#ifndef WIN32 - if (SETSOCKOPT - (s->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, - sizeof(loop)) != 0) { - socket_error("setsockopt IP_MULTICAST_LOOP"); - return NULL; - } -#endif - if (SETSOCKOPT - (s->fd, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&s->ttl, - sizeof(s->ttl)) != 0) { - socket_error("setsockopt IP_MULTICAST_TTL"); - 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); return s; } @@ -915,12 +947,13 @@ socket_udp *udp_init_if(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl, bool use_ipv6) { socket_udp *res; - - if (strchr(addr, ':') == NULL && !use_ipv6) { - res = udp_init4(addr, iface, rx_port, tx_port, ttl); - } else { - res = udp_init6(addr, iface, rx_port, tx_port, ttl); - } + + if ((addr == NULL || strchr(addr, ':') == NULL) && !use_ipv6) { + res = udp_init4(addr, iface, rx_port, tx_port, ttl); + } else { + res = udp_init6(addr, iface, rx_port, tx_port, ttl); + } + return res; } diff --git a/src/rtp/rtp.c b/src/rtp/rtp.c index 84c4dffb7..0a12c1ddb 100644 --- a/src/rtp/rtp.c +++ b/src/rtp/rtp.c @@ -13,12 +13,15 @@ * Jiri Matela * Dalibor Matura <255899@mail.muni.cz> * Ian Wesley-Smith + * David Cassany + * Gerard Castillo * * The routines in this file implement the Real-time Transport Protocol, * RTP, as specified in RFC1889 with current updates under discussion in * the IETF audio/video transport working group. Portions of the code are * derived from the algorithms published in that specification. * + * Copyright (c) 2005-2010 Fundació i2CAT, Internet I Innovació Digital a Catalunya * Copyright (c) 2005-2010 CESNET z.s.p.o. * Copyright (c) 2001-2004 University of Southern California * Copyright (c) 2003-2004 University of Glasgow @@ -1076,14 +1079,19 @@ struct rtp *rtp_init_if(const char *addr, const char *iface, session->magic = 0xfeedface; session->opt = (options *) malloc(sizeof(options)); session->userdata = userdata; - session->addr = strdup(addr); + if (addr != NULL) { + session->addr = strdup(addr); + } else { + session->addr = NULL; + } session->rx_port = rx_port; session->tx_port = tx_port; session->ttl = min(ttl, 127); session->rtp_socket = udp_init_if(addr, iface, rx_port, tx_port, ttl, use_ipv6); + session->rtcp_socket = udp_init_if(addr, iface, (uint16_t) (rx_port + (rx_port ? 1 : 0)), - (uint16_t) (tx_port + 1), ttl, use_ipv6); + (uint16_t) (tx_port + (tx_port ? 1 : 0)), ttl, use_ipv6); init_opt(session); diff --git a/src/rtp/rtpdec_h264.c b/src/rtp/rtpdec_h264.c index 6b409e1da..997bc0bbf 100644 --- a/src/rtp/rtpdec_h264.c +++ b/src/rtp/rtpdec_h264.c @@ -1,3 +1,46 @@ +/* + * AUTHOR: David Cassany , + * Ignacio Contreras , + * Gerard Castillo + * + * Copyright (c) 2005-2010 Fundació i2CAT, Internet I Innovació Digital a Catalunya + * + * Redistribution and use in source and binary forms, with or without + * modification, is permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * + * This product includes software developed by the University of Southern + * California Information Sciences Institute. + * + * 4. Neither the name of the University nor of the Institute may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #ifdef HAVE_CONFIG_H #include "config.h" #include "config_unix.h" diff --git a/src/rtp/rtpdec_h264.h b/src/rtp/rtpdec_h264.h index c82308f8d..2f1318707 100644 --- a/src/rtp/rtpdec_h264.h +++ b/src/rtp/rtpdec_h264.h @@ -1,3 +1,46 @@ +/* + * AUTHOR: David Cassany , + * Ignacio Contreras , + * Gerard Castillo + * + * Copyright (c) 2005-2010 Fundació i2CAT, Internet I Innovació Digital a Catalunya + * + * Redistribution and use in source and binary forms, with or without + * modification, is permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * + * This product includes software developed by the University of Southern + * California Information Sciences Institute. + * + * 4. Neither the name of the University nor of the Institute may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + #ifndef _RTP_DEC_H264_H #define _RTP_DEC_H264_H diff --git a/src/video_capture/rtsp.c b/src/video_capture/rtsp.c index a8872e490..d306dfe45 100644 --- a/src/video_capture/rtsp.c +++ b/src/video_capture/rtsp.c @@ -156,7 +156,8 @@ void * vidcap_rtsp_thread(void *arg) } rtp_update(s->device, s->curr_time); - rtp_send_ctrl(s->device, s->timestamp, 0, s->curr_time); + //TODO rtcp communication between ug and rtsp server? + //rtp_send_ctrl(s->device, s->timestamp, 0, s->curr_time); s->timeout.tv_sec = 0; s->timeout.tv_usec = 10000; @@ -415,7 +416,7 @@ void *vidcap_rtsp_init(char *fmt, unsigned int flags){ s->should_exit = false; - s->device = rtp_init_if(s->addr, s->mcast_if, s->port, s->port, s->ttl, s->rtcp_bw, 0, rtp_recv_callback, (void *)s->participants, 0); + s->device = rtp_init_if(NULL, s->mcast_if, s->port, 0, s->ttl, s->rtcp_bw, 0, rtp_recv_callback, (void *)s->participants, 0); if (s->device != NULL) { //printf("[rtsp] RTP INIT OPTIONS\n");