Opened 14 months ago

#9294 new enhancement

Multi-client SRT server

Reported by: a_sheetov Owned by:
Priority: normal Component: avformat
Version: git-master Keywords: libsrt srt multi-client
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

I’m using ffmpeg as a library from within my app. I’m currently developing an SRT server that accepts client connections and streams video to them. I compiled ffmpeg with libsrt and implemented SRT server based on a standard muxer (options: mode=listener, transtype=live).

During testing, I found two problems:

  1. Data transfer doesn’t start until the first client connects
  2. The second client can’t connect after the first one


So it looks like ffmpeg implementation of SRT server does not support multiple concurrent client connections.

I looked at the source code (libavformat/libsrt.c) and my assumptions were confirmed:

static int libsrt_listen(int eid, int fd, const struct sockaddr *addr, socklen_t addrlen, URLContext *h, int64_t timeout)
{
    int ret;
    int reuse = 1;
    if (srt_setsockopt(fd, SOL_SOCKET, SRTO_REUSEADDR, &reuse, sizeof(reuse))) {
        av_log(h, AV_LOG_WARNING, "setsockopt(SRTO_REUSEADDR) failed\n");
    }
    if (srt_bind(fd, addr, addrlen))
        return libsrt_neterrno(h);

    if (srt_listen(fd, 1))
        return libsrt_neterrno(h);

    ret = libsrt_network_wait_fd_timeout(h, eid, 1, timeout, &h->interrupt_callback);
    if (ret < 0)
        return ret;

    ret = srt_accept(fd, NULL, NULL);
    if (ret < 0)
        return libsrt_neterrno(h);
    if (libsrt_socket_nonblock(ret, 1) < 0)
        av_log(h, AV_LOG_DEBUG, "libsrt_socket_nonblock failed\n");

    return ret;
}

static int libsrt_setup(URLContext *h, const char *uri, int flags)
{
    // ...
    if (s->mode == SRT_MODE_LISTENER) {
        // multi-client
        ret = libsrt_listen(write_eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen, h, s->listen_timeout);
        srt_epoll_release(write_eid);
        if (ret < 0)
            goto fail1;
        srt_close(fd);
        fd = ret;
    }
    // ...
}

After the first client connects, server socket is closed and its descriptor is replaced with the client socket descriptor.

Change History (0)

Note: See TracTickets for help on using tickets.