mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-04-12 10:46:06 +00:00
Tune SO_RCVBUF logic
- Calculate desired SO_RCVBUF by packet size for the video socket - Use the OS default SO_RCVBUF for audio and STUN sockets
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user