obs-outputs: Implement send timeout in librtmp

This fixes a bug where the RTMP send thread can deadlock upon the
underlying TCP connection being broken. By introducing a send timeout,
this allows the thread to unblock and give up, triggering a reconnect
as normal. The correct solution to this problem would be to rewrite
librtmp with asynchronous IO, but that seems like something unlikely
to happen.

**Before**:
- Start stream in OBS
- Use tool (pfSense) to invalidate connection state
- OBS bitrate drops to 0
- Output does not respond to stop signals, and hangs for an undefined
amount of time (usually multiple minutes) before finally giving up

**After**:
- Start stream in OBS
- Use tool (pfSense) to invalidate connection state
- OBS bitrate drops to 0
- Output sits in blocked state for maximum of 8 seconds, then cleans
up and triggers the reconnect logic
This commit is contained in:
tt2468 2022-04-23 14:21:47 -07:00 committed by Jim
parent 34e570c5bc
commit 66a7db7f2a
2 changed files with 16 additions and 6 deletions

View File

@ -484,7 +484,8 @@ RTMP_Reset(RTMP *r)
r->m_fVideoCodecs = 252.0;
r->Link.curStreamIdx = 0;
r->Link.nStreams = 0;
r->Link.timeout = 30;
r->Link.receiveTimeout = 30;
r->Link.sendTimeout = 6;
r->Link.swfAge = 30;
}
@ -928,12 +929,20 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service, socklen_t addrlen)
/* set timeout */
{
SET_RCVTIMEO(tv, r->Link.timeout);
SET_RCVTIMEO(tvr, r->Link.receiveTimeout);
if (setsockopt
(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)))
(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tvr, sizeof(tvr)))
{
RTMP_Log(RTMP_LOGERROR, "%s, Setting socket timeout to %ds failed!",
__FUNCTION__, r->Link.timeout);
RTMP_Log(RTMP_LOGERROR, "%s, Setting socket receive timeout to %ds failed!",
__FUNCTION__, r->Link.receiveTimeout);
}
SET_RCVTIMEO(tvs, r->Link.sendTimeout);
if (setsockopt
(r->m_sb.sb_socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&tvs, sizeof(tvs)))
{
RTMP_Log(RTMP_LOGERROR, "%s, Setting socket send timeout to %ds failed!",
__FUNCTION__, r->Link.sendTimeout);
}
}

View File

@ -328,7 +328,8 @@ extern "C"
int swfAge;
int protocol;
int timeout; /* connection timeout in seconds */
int receiveTimeout; /* connection receive timeout in seconds */
int sendTimeout; /* connection send timeout in seconds */
#define RTMP_PUB_NAME 0x0001 /* send login to server */
#define RTMP_PUB_RESP 0x0002 /* send salted password hash */