Esempio n. 1
0
static int sdp_get_address(char *dest_addr, int size, int *ttl, const char *url)
{
    int port;
    const char *p;
    char proto[32];

    ff_url_split(proto, sizeof(proto), NULL, 0, dest_addr, size, &port, NULL, 0, url);

    *ttl = 0;

    if (strcmp(proto, "rtp")) {
        /* The url isn't for the actual rtp sessions,
         * don't parse out anything else than the destination.
         */
        return 0;
    }

    p = strchr(url, '?');
    if (p) {
        char buff[64];
        int is_multicast = find_info_tag(buff, sizeof(buff), "multicast", p);

        if (is_multicast) {
            if (find_info_tag(buff, sizeof(buff), "ttl", p)) {
                *ttl = strtol(buff, NULL, 10);
            } else {
                *ttl = 5;
            }
        }
    }

    return port;
}
Esempio n. 2
0
File: udp.c Progetto: AndyA/ffmbc
/**
 * If no filename is given to av_open_input_file because you want to
 * get the local port first, then you must call this function to set
 * the remote server address.
 *
 * url syntax: udp://host:port[?option=val...]
 * option: 'ttl=n'       : set the ttl value (for multicast only)
 *         'localport=n' : set the local port
 *         'pkt_size=n'  : set max packet size
 *         'reuse=1'     : enable reusing the socket
 *
 * @param h media file context
 * @param uri of the remote server
 * @return zero if no error.
 */
int udp_set_remote_url(URLContext *h, const char *uri)
{
    UDPContext *s = h->priv_data;
    char hostname[256], buf[10];
    int port;
    const char *p;

    av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);

    /* set the destination address */
    s->dest_addr_len = udp_set_url(&s->dest_addr, hostname, port);
    if (s->dest_addr_len < 0) {
        return AVERROR(EIO);
    }
    s->is_multicast = ff_is_multicast_address((struct sockaddr*) &s->dest_addr);
    p = strchr(uri, '?');
    if (p) {
        if (find_info_tag(buf, sizeof(buf), "connect", p)) {
            int was_connected = s->is_connected;
            s->is_connected = strtol(buf, NULL, 10);
            if (s->is_connected && !was_connected) {
                if (connect(s->udp_fd, (struct sockaddr *) &s->dest_addr,
                            s->dest_addr_len)) {
                    s->is_connected = 0;
                    av_log(NULL, AV_LOG_ERROR, "connect: %s\n", strerror(errno));
                    return AVERROR(EIO);
                }
            }
        }
    }

    return 0;
}
Esempio n. 3
0
/* return non zero if error */
static int udp_open(URLContext *h, const char *uri, int flags)
{
    char hostname[1024];
    int port, udp_fd = -1, tmp, bind_ret = -1;
    UDPContext *s = NULL;
    int is_output;
    const char *p;
    char buf[256];
#if !CONFIG_IPV6
    struct sockaddr_in my_addr;
#else
    struct sockaddr_storage my_addr;
#endif
    int len;

    h->is_streamed = 1;
    h->max_packet_size = 1472;

    is_output = (flags & URL_WRONLY);

    if(!ff_network_init())
        return AVERROR(EIO);

    s = av_mallocz(sizeof(UDPContext));
    if (!s)
        return AVERROR(ENOMEM);

    h->priv_data = s;
    s->ttl = 16;
    s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_MAX_PKT_SIZE;

    p = strchr(uri, '?');
    if (p) {
        s->reuse_socket = find_info_tag(buf, sizeof(buf), "reuse", p);
        if (find_info_tag(buf, sizeof(buf), "ttl", p)) {
            s->ttl = strtol(buf, NULL, 10);
        }
        if (find_info_tag(buf, sizeof(buf), "localport", p)) {
            s->local_port = strtol(buf, NULL, 10);
        }
        if (find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
            h->max_packet_size = strtol(buf, NULL, 10);
        }
        if (find_info_tag(buf, sizeof(buf), "buffer_size", p)) {
            s->buffer_size = strtol(buf, NULL, 10);
        }
    }

    /* fill the dest addr */
    url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);

    /* XXX: fix url_split */
    if (hostname[0] == '\0' || hostname[0] == '?') {
        /* only accepts null hostname if input */
        if (flags & URL_WRONLY)
            goto fail;
    } else {
        udp_set_remote_url(h, uri);
    }

    if (s->is_multicast && !(h->flags & URL_WRONLY))
        s->local_port = port;
    udp_fd = udp_socket_create(s, &my_addr, &len);
    if (udp_fd < 0)
        goto fail;

    if (s->reuse_socket)
        if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0)
            goto fail;

    /* the bind is needed to give a port to the socket now */
    /* if multicast, try the multicast address bind first */
    if (s->is_multicast && !(h->flags & URL_WRONLY)) {
        bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len);
    }
    /* bind to the local address if not multicast or if the multicast
     * bind failed */
    if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0)
        goto fail;

    len = sizeof(my_addr);
    getsockname(udp_fd, (struct sockaddr *)&my_addr, &len);
    s->local_port = udp_port(&my_addr, len);

    if (s->is_multicast) {
        if (h->flags & URL_WRONLY) {
            /* output */
            if (udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0)
                goto fail;
        } else {
            /* input */
            if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
                goto fail;
        }
    }

    if (is_output) {
        /* limit the tx buf size to limit latency */
        tmp = s->buffer_size;
        if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) {
            av_log(NULL, AV_LOG_ERROR, "setsockopt(SO_SNDBUF): %s\n", strerror(errno));
            goto fail;
        }
    } else {
        /* set udp recv buffer size to the largest possible udp packet size to
         * avoid losing data on OSes that set this too low by default. */
        tmp = s->buffer_size;
        if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)) < 0) {
            av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_RECVBUF): %s\n", strerror(errno));
        }
        /* make the socket non-blocking */
        ff_socket_nonblock(udp_fd, 1);
    }

    s->udp_fd = udp_fd;
    return 0;
 fail:
    if (udp_fd >= 0)
        closesocket(udp_fd);
    av_free(s);
    return AVERROR(EIO);
}
Esempio n. 4
0
File: udp.c Progetto: suborb/reelvdr
/* return non zero if error */
static int udp_open(URLContext *h, const char *uri, int flags)
{
    char hostname[1024];
    int port, udp_fd = -1, tmp;
    UDPContext *s = NULL;
    int is_output;
    const char *p;
    char buf[256];
#ifndef CONFIG_IPV6
    struct sockaddr_in my_addr, my_addr1;
    int len;
#endif

    h->is_streamed = 1;
    h->max_packet_size = 1472;

    is_output = (flags & URL_WRONLY);
    
    s = av_malloc(sizeof(UDPContext));
    if (!s)
        return -ENOMEM;

    h->priv_data = s;
    s->ttl = 16;
    s->is_multicast = 0;
    s->local_port = 0;
    p = strchr(uri, '?');
    if (p) {
        s->is_multicast = find_info_tag(buf, sizeof(buf), "multicast", p);
        if (find_info_tag(buf, sizeof(buf), "ttl", p)) {
            s->ttl = strtol(buf, NULL, 10);
        }
        if (find_info_tag(buf, sizeof(buf), "localport", p)) {
            s->local_port = strtol(buf, NULL, 10);
        }
        if (find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
            h->max_packet_size = strtol(buf, NULL, 10);
        }
    }

    /* fill the dest addr */
    url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
    
    /* XXX: fix url_split */
    if (hostname[0] == '\0' || hostname[0] == '?') {
        /* only accepts null hostname if input */
        if (s->is_multicast || (flags & URL_WRONLY))
            goto fail;
    } else {
        udp_set_remote_url(h, uri);
    }

#ifndef CONFIG_IPV6
    udp_fd = socket(PF_INET, SOCK_DGRAM, 0);
    if (udp_fd < 0)
        goto fail;

    my_addr.sin_family = AF_INET;
    my_addr.sin_addr.s_addr = htonl (INADDR_ANY);
    if (s->is_multicast && !(h->flags & URL_WRONLY)) {
        /* special case: the bind must be done on the multicast address port */
        my_addr.sin_port = s->dest_addr.sin_port;
    } else {
        my_addr.sin_port = htons(s->local_port);
    }

    /* the bind is needed to give a port to the socket now */
    if (bind(udp_fd,(struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) 
        goto fail;

    len = sizeof(my_addr1);
    getsockname(udp_fd, (struct sockaddr *)&my_addr1, &len);
    s->local_port = ntohs(my_addr1.sin_port);

#ifndef CONFIG_BEOS_NETSERVER
    if (s->is_multicast) {
        if (h->flags & URL_WRONLY) {
            /* output */
            if (setsockopt(udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, 
                           &s->ttl, sizeof(s->ttl)) < 0) {
                perror("IP_MULTICAST_TTL");
                goto fail;
            }
        } else {
            /* input */
            memset(&s->mreq, 0, sizeof(s->mreq));
            s->mreq.imr_multiaddr = s->dest_addr.sin_addr;
            s->mreq.imr_interface.s_addr = htonl (INADDR_ANY);
            if (setsockopt(udp_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, 
                           &s->mreq, sizeof(s->mreq)) < 0) {
                perror("rtp: IP_ADD_MEMBERSHIP");
                goto fail;
            }
        }
    }
#endif
#else
    if (s->is_multicast && !(h->flags & URL_WRONLY))
        s->local_port = port;
    udp_fd = udp_ipv6_set_local(h);
    if (udp_fd < 0)
        goto fail;
#ifndef CONFIG_BEOS_NETSERVER
    if (s->is_multicast) {
        if (h->flags & URL_WRONLY) {
            if (udp_ipv6_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0)
                goto fail;
        } else {
            if (udp_ipv6_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
                goto fail;
        }
    }
#endif          
#endif

    if (is_output) {
        /* limit the tx buf size to limit latency */
        tmp = UDP_TX_BUF_SIZE;
        if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) {
            perror("setsockopt sndbuf");
            goto fail;
        }
    }

    s->udp_fd = udp_fd;
    return 0;
 fail:
    if (udp_fd >= 0)
#ifdef CONFIG_BEOS_NETSERVER
        closesocket(udp_fd);
#else
        close(udp_fd);
#endif
    av_free(s);
    return AVERROR_IO;
}
Esempio n. 5
0
/*
 * url syntax: rtp://host:port[?option=val...]
 * option: 'multicast=1' : enable multicast
 *         'ttl=n'       : set the ttl value (for multicast only)
 *         'localport=n' : set the local port to n
 *
 */
static int rtp_open(URLContext *h, const char *uri, int flags)
{
    RTPContext *s;
    int port, is_output, is_multicast, ttl, local_port;
    char hostname[256];
    char buf[1024];
    char path[1024];
    const char *p;

    is_output = (flags & URL_WRONLY);

    s = av_mallocz(sizeof(RTPContext));
    if (!s)
        return AVERROR(ENOMEM);
    h->priv_data = s;

    url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port,
              path, sizeof(path), uri);
    /* extract parameters */
    is_multicast = 0;
    ttl = -1;
    local_port = -1;
    p = strchr(uri, '?');
    if (p) {
        is_multicast = find_info_tag(buf, sizeof(buf), "multicast", p);
        if (find_info_tag(buf, sizeof(buf), "ttl", p)) {
            ttl = strtol(buf, NULL, 10);
        }
        if (find_info_tag(buf, sizeof(buf), "localport", p)) {
            local_port = strtol(buf, NULL, 10);
        }
    }

    build_udp_url(buf, sizeof(buf),
                  hostname, port, local_port, is_multicast, ttl);
    if (url_open(&s->rtp_hd, buf, flags) < 0)
        goto fail;
    local_port = udp_get_local_port(s->rtp_hd);
    /* XXX: need to open another connexion if the port is not even */

    /* well, should suppress localport in path */

    build_udp_url(buf, sizeof(buf),
                  hostname, port + 1, local_port + 1, is_multicast, ttl);
    if (url_open(&s->rtcp_hd, buf, flags) < 0)
        goto fail;

    /* just to ease handle access. XXX: need to suppress direct handle
       access */
    s->rtp_fd = udp_get_file_handle(s->rtp_hd);
    s->rtcp_fd = udp_get_file_handle(s->rtcp_hd);

    h->max_packet_size = url_get_max_packet_size(s->rtp_hd);
    h->is_streamed = 1;
    return 0;

fail:
    if (s->rtp_hd)
        url_close(s->rtp_hd);
    if (s->rtcp_hd)
        url_close(s->rtcp_hd);
    av_free(s);
    return AVERROR_IO;
}
Esempio n. 6
0
static int rtp_open(URLContext *h, const char *uri, int flags)
{
    RTPContext *s;
    int rtp_port, rtcp_port,
        is_output, ttl,
        local_rtp_port, local_rtcp_port, max_packet_size;
    char hostname[256];
    char buf[1024];
    char path[1024];
    const char *p;

    is_output = (flags & URL_WRONLY);

    s = av_mallocz(sizeof(RTPContext));
    if (!s)
        return AVERROR(ENOMEM);
    h->priv_data = s;

    av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
                 path, sizeof(path), uri);
    /* extract parameters */
    ttl = -1;
    rtcp_port = rtp_port+1;
    local_rtp_port = -1;
    local_rtcp_port = -1;
    max_packet_size = -1;

    p = strchr(uri, '?');
    if (p) {
        if (find_info_tag(buf, sizeof(buf), "ttl", p)) {
            ttl = strtol(buf, NULL, 10);
        }
        if (find_info_tag(buf, sizeof(buf), "rtcpport", p)) {
            rtcp_port = strtol(buf, NULL, 10);
        }
        if (find_info_tag(buf, sizeof(buf), "localport", p)) {
            local_rtp_port = strtol(buf, NULL, 10);
        }
        if (find_info_tag(buf, sizeof(buf), "localrtpport", p)) {
            local_rtp_port = strtol(buf, NULL, 10);
        }
        if (find_info_tag(buf, sizeof(buf), "localrtcpport", p)) {
            local_rtcp_port = strtol(buf, NULL, 10);
        }
        if (find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
            max_packet_size = strtol(buf, NULL, 10);
        }
    }

    build_udp_url(buf, sizeof(buf),
                  hostname, rtp_port, local_rtp_port, ttl, max_packet_size);
    if (url_open(&s->rtp_hd, buf, flags) < 0)
        goto fail;
    if (local_rtp_port>=0 && local_rtcp_port<0)
        local_rtcp_port = udp_get_local_port(s->rtp_hd) + 1;

    build_udp_url(buf, sizeof(buf),
                  hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size);
    if (url_open(&s->rtcp_hd, buf, flags) < 0)
        goto fail;

    /* just to ease handle access. XXX: need to suppress direct handle
       access */
    s->rtp_fd = url_get_file_handle(s->rtp_hd);
    s->rtcp_fd = url_get_file_handle(s->rtcp_hd);

    h->max_packet_size = url_get_max_packet_size(s->rtp_hd);
    h->is_streamed = 1;
    return 0;

 fail:
    if (s->rtp_hd)
        url_close(s->rtp_hd);
    if (s->rtcp_hd)
        url_close(s->rtcp_hd);
    av_free(s);
    return AVERROR(EIO);
}