diff --git a/src/AudioStream.c b/src/AudioStream.c index 3447d61..6407d3c 100644 --- a/src/AudioStream.c +++ b/src/AudioStream.c @@ -25,11 +25,6 @@ static uint8_t opusHeaderByte; #define MAX_PACKET_SIZE 1400 -// This is much larger than we should typically have buffered, but -// it needs to be. We need a cushion in case our thread gets blocked -// for longer than normal. -#define RTP_RECV_BUFFER (64 * 1024) - typedef struct _QUEUE_AUDIO_PACKET_HEADER { LINKED_BLOCKING_QUEUE_ENTRY lentry; int size; @@ -88,7 +83,7 @@ int initializeAudioStream(void) { // For GFE 3.22 compatibility, we must start the audio ping thread before the RTSP handshake. // It will not reply to our RTSP PLAY request until the audio ping has been received. - rtpSocket = bindUdpSocket(RemoteAddr.ss_family, RTP_RECV_BUFFER); + rtpSocket = bindUdpSocket(RemoteAddr.ss_family, 0); if (rtpSocket == INVALID_SOCKET) { return LastSocketFail(); } diff --git a/src/PlatformSockets.c b/src/PlatformSockets.c index 268b36d..986903d 100644 --- a/src/PlatformSockets.c +++ b/src/PlatformSockets.c @@ -266,36 +266,45 @@ SOCKET bindUdpSocket(int addrfamily, int bufferSize) { } #endif - // We start at the requested recv buffer value and step down until we find - // a value that the OS will accept. - for (;;) { - err = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&bufferSize, sizeof(bufferSize)); + if (bufferSize != 0) { + // We start at the requested recv buffer value and step down until we find + // a value that the OS will accept. + for (;;) { + err = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&bufferSize, sizeof(bufferSize)); + if (err == 0) { + // Successfully set a buffer size + break; + } + else if (bufferSize <= RCV_BUFFER_SIZE_MIN) { + // Failed to set a buffer size within the allowable range + break; + } + else if (bufferSize - RCV_BUFFER_SIZE_STEP <= RCV_BUFFER_SIZE_MIN) { + // Last shot - we're trying the minimum + bufferSize = RCV_BUFFER_SIZE_MIN; + } + else { + // Lower the requested size by another step + bufferSize -= RCV_BUFFER_SIZE_STEP; + } + } + +#if defined(LC_DEBUG) if (err == 0) { - // Successfully set a buffer size - break; - } - else if (bufferSize <= RCV_BUFFER_SIZE_MIN) { - // Failed to set a buffer size within the allowable range - break; - } - else if (bufferSize - RCV_BUFFER_SIZE_STEP <= RCV_BUFFER_SIZE_MIN) { - // Last shot - we're trying the minimum - bufferSize = RCV_BUFFER_SIZE_MIN; + Limelog("Selected receive buffer size: %d\n", bufferSize); } else { - // Lower the requested size by another step - bufferSize -= RCV_BUFFER_SIZE_STEP; + Limelog("Unable to set receive buffer size: %d\n", LastSocketError()); + } + + { + SOCKADDR_LEN len = sizeof(bufferSize); + if (getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&bufferSize, &len) == 0) { + Limelog("Actual receive buffer size: %d\n", bufferSize); + } } - } - -#if defined(LC_DEBUG) - if (err == 0) { - Limelog("Selected receive buffer size: %d\n", bufferSize); - } - else { - Limelog("Unable to set receive buffer size: %d\n", LastSocketError()); - } #endif + } return s; } diff --git a/src/SimpleStun.c b/src/SimpleStun.c index 55c62d7..56b5637 100644 --- a/src/SimpleStun.c +++ b/src/SimpleStun.c @@ -73,7 +73,7 @@ int LiFindExternalAddressIP4(const char* stunServer, unsigned short stunPort, un goto Exit; } - sock = bindUdpSocket(hints.ai_family, 2048); + sock = bindUdpSocket(hints.ai_family, 0); if (sock == INVALID_SOCKET) { err = LastSocketFail(); Limelog("Failed to connect to STUN server: %d\n", err); diff --git a/src/VideoStream.c b/src/VideoStream.c index 6d75069..1128dfb 100644 --- a/src/VideoStream.c +++ b/src/VideoStream.c @@ -5,8 +5,6 @@ #define FIRST_FRAME_PORT 47996 -#define RTP_RECV_BUFFER (512 * 1024) - static RTP_VIDEO_QUEUE rtpQueue; static SOCKET rtpSocket = INVALID_SOCKET; @@ -25,6 +23,14 @@ static bool receivedFullFrame; // the RTP queue will wait for missing/reordered packets. #define RTP_QUEUE_DELAY 10 +// This is the desired number of video packets that can be +// stored in the socket's receive buffer. 2048 is chosen +// because it should be large enough for all reasonable +// frame sizes (probably 2 or 3 frames) without using too +// much kernel memory with larger packet sizes. It also +// can smooth over transient pauses in network traffic +// and subsequent packet/frame bursts that follow. +#define RTP_RECV_PACKETS_BUFFERED 2048 // Initialize the video stream void initializeVideoStream(void) { @@ -254,7 +260,7 @@ int startVideoStream(void* rendererContext, int drFlags) { return err; } - rtpSocket = bindUdpSocket(RemoteAddr.ss_family, RTP_RECV_BUFFER); + rtpSocket = bindUdpSocket(RemoteAddr.ss_family, RTP_RECV_PACKETS_BUFFERED * (StreamConfig.packetSize + MAX_RTP_HEADER_SIZE)); if (rtpSocket == INVALID_SOCKET) { VideoCallbacks.cleanup(); return LastSocketError();