Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

obs-ffmpeg: Fix SRT listener bug #10508

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 21 additions & 23 deletions plugins/obs-ffmpeg/obs-ffmpeg-mpegts.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,14 @@ void ffmpeg_mpegts_log_error(int log_level, struct ffmpeg_data *data,
blog(log_level, "%s", out);
}

static bool is_rist(struct ffmpeg_output *stream)
static bool is_rist(const char *url)
{
return !strncmp(stream->ff_data.config.url, RIST_PROTO,
sizeof(RIST_PROTO) - 1);
return !strncmp(url, RIST_PROTO, sizeof(RIST_PROTO) - 1);
}

static bool is_srt(struct ffmpeg_output *stream)
static bool is_srt(const char *url)
{
return !strncmp(stream->ff_data.config.url, SRT_PROTO,
sizeof(SRT_PROTO) - 1);
return !strncmp(url, SRT_PROTO, sizeof(SRT_PROTO) - 1);
}

static bool proto_is_allowed(struct ffmpeg_output *stream)
Expand Down Expand Up @@ -467,8 +465,8 @@ static inline int open_output_file(struct ffmpeg_output *stream,
struct ffmpeg_data *data)
{
int ret;
bool rist = is_rist(stream);
bool srt = is_srt(stream);
bool rist = data->config.is_rist;
bool srt = data->config.is_srt;
bool allowed_proto = proto_is_allowed(stream);
AVDictionary *dict = NULL;

Expand Down Expand Up @@ -591,10 +589,7 @@ static void close_audio(struct ffmpeg_data *data)
static void close_mpegts_url(struct ffmpeg_output *stream, bool is_rist)
{
int err = 0;
AVIOContext *s = stream->s;
if (!s)
return;
URLContext *h = s->opaque;
URLContext *h = stream->h;
if (!h)
return; /* can happen when opening the url fails */

Expand All @@ -608,10 +603,14 @@ static void close_mpegts_url(struct ffmpeg_output *stream, bool is_rist)
av_freep(h);

/* close custom avio_context for srt or rist */
avio_flush(stream->s);
stream->s->opaque = NULL;
av_freep(&stream->s->buffer);
avio_context_free(&stream->s);
AVIOContext *s = stream->s;
if (!s)
return;

avio_flush(s);
pkviet marked this conversation as resolved.
Show resolved Hide resolved
s->opaque = NULL;
av_freep(&s->buffer);
avio_context_free(&s);

if (err)
info("[ffmpeg mpegts muxer]: Error closing URL %s",
Expand All @@ -632,8 +631,8 @@ void ffmpeg_mpegts_data_free(struct ffmpeg_output *stream,
}

if (data->output) {
if (is_rist(stream) || is_srt(stream)) {
close_mpegts_url(stream, is_rist(stream));
if (data->config.is_rist || data->config.is_srt) {
close_mpegts_url(stream, data->config.is_rist);
} else {
avio_close(data->output->pb);
}
Expand Down Expand Up @@ -757,11 +756,10 @@ static void ffmpeg_mpegts_destroy(void *data)
struct ffmpeg_output *output = data;

if (output) {
ffmpeg_mpegts_full_stop(output);
if (output->connecting)
pthread_join(output->start_thread, NULL);

ffmpeg_mpegts_full_stop(output);

pthread_mutex_destroy(&output->write_mutex);
os_sem_destroy(output->write_sem);
os_event_destroy(output->stop_event);
Expand Down Expand Up @@ -910,7 +908,8 @@ static bool set_config(struct ffmpeg_output *stream)
service, OBS_SERVICE_CONNECT_INFO_ENCRYPT_PASSPHRASE);
config.format_name = "mpegts";
config.format_mime_type = "video/M2PT";

config.is_rist = is_rist(config.url);
config.is_srt = is_srt(config.url);
/* 2. video settings */

// 2.a) set width & height
Expand Down Expand Up @@ -1110,6 +1109,7 @@ static void ffmpeg_mpegts_full_stop(void *data)
obs_output_end_data_capture(output->output);
ffmpeg_mpegts_deactivate(output);
}
ffmpeg_mpegts_data_free(output, &output->ff_data);
}

static void ffmpeg_mpegts_stop(void *data, uint64_t ts)
Expand Down Expand Up @@ -1144,8 +1144,6 @@ static void ffmpeg_mpegts_deactivate(struct ffmpeg_output *output)
da_free(output->packets);

pthread_mutex_unlock(&output->write_mutex);

ffmpeg_mpegts_data_free(output, &output->ff_data);
}

static uint64_t ffmpeg_mpegts_total_bytes(void *data)
Expand Down
2 changes: 2 additions & 0 deletions plugins/obs-ffmpeg/obs-ffmpeg-output.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ struct ffmpeg_cfg {
const char *password;
const char *stream_id;
const char *encrypt_passphrase;
bool is_srt;
bool is_rist;
};

struct ffmpeg_audio_info {
Expand Down
23 changes: 14 additions & 9 deletions plugins/obs-ffmpeg/obs-ffmpeg-srt.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,15 @@ static int libsrt_network_wait_fd(URLContext *h, int eid, int write)
int ret, len = 1, errlen = 1;
SRTSOCKET ready[1];
SRTSOCKET error[1];

SRTContext *s = (SRTContext *)h->priv_data;
if (write) {
ret = srt_epoll_wait(eid, error, &errlen, ready, &len,
POLLING_TIME, 0, 0, 0, 0);
} else {
ret = srt_epoll_wait(eid, ready, &len, error, &errlen,
POLLING_TIME, 0, 0, 0, 0);
}
if (len == 1 && errlen == 1) {
if (len == 1 && errlen == 1 && s->mode == SRT_MODE_CALLER) {
/* Socket reported in wsock AND rsock signifies an error. */
int reason = srt_getrejectreason(*ready);

Expand Down Expand Up @@ -232,7 +232,7 @@ static int libsrt_listen(int eid, SRTSOCKET fd, const struct sockaddr *addr,
if (srt_listen(fd, 1))
return libsrt_neterrno(h);

ret = libsrt_network_wait_fd_timeout(h, eid, 1, timeout,
ret = libsrt_network_wait_fd_timeout(h, eid, 0, timeout,
&h->interrupt_callback);
if (ret < 0)
return ret;
Expand Down Expand Up @@ -462,7 +462,7 @@ static int libsrt_setup(URLContext *h, const char *uri)
char hostname[1024], proto[1024], path[1024];
char portstr[10];
int64_t open_timeout = 0;
int eid, write_eid;
int eid;
struct sockaddr_in la;

av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
Expand Down Expand Up @@ -552,20 +552,23 @@ static int libsrt_setup(URLContext *h, const char *uri)
blog(LOG_DEBUG,
"[obs-ffmpeg mpegts muxer / libsrt]: libsrt_socket_nonblock failed");

ret = write_eid = libsrt_epoll_create(h, fd, 1);
if (ret < 0)
goto fail1;
if (s->mode == SRT_MODE_LISTENER) {
int read_eid = ret = libsrt_epoll_create(h, fd, 0);
if (ret < 0)
goto fail1;
// multi-client
ret = libsrt_listen(write_eid, fd, cur_ai->ai_addr,
ret = libsrt_listen(read_eid, fd, cur_ai->ai_addr,
(socklen_t)cur_ai->ai_addrlen, h,
s->listen_timeout);
srt_epoll_release(write_eid);
srt_epoll_release(read_eid);
if (ret < 0)
goto fail1;
srt_close(fd);
fd = ret;
} else {
int write_eid = ret = libsrt_epoll_create(h, fd, 1);
if (ret < 0)
goto fail1;
if (s->mode == SRT_MODE_RENDEZVOUS) {
if (srt_bind(fd, (struct sockaddr *)&la,
sizeof(struct sockaddr_in))) {
Expand Down Expand Up @@ -878,6 +881,8 @@ static int libsrt_write(URLContext *h, const uint8_t *buf, int size)
static int libsrt_close(URLContext *h)
{
SRTContext *s = (SRTContext *)h->priv_data;
if (!s)
return 0;
if (s->streamid)
av_freep(&s->streamid);
if (s->passphrase)
Expand Down