mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2025-07-01 07:15:39 +00:00
Add basic QoS attributes to our A/V sockets
This commit is contained in:
parent
68153174bc
commit
c0e3dc64a4
@ -93,7 +93,7 @@ int notifyAudioPortNegotiationComplete(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, &LocalAddr, AddrLen, 0);
|
||||
rtpSocket = bindUdpSocket(RemoteAddr.ss_family, &LocalAddr, AddrLen, 0, SOCK_QOS_TYPE_AUDIO);
|
||||
if (rtpSocket == INVALID_SOCKET) {
|
||||
return LastSocketFail();
|
||||
}
|
||||
|
@ -235,7 +235,56 @@ void closeSocket(SOCKET s) {
|
||||
#endif
|
||||
}
|
||||
|
||||
SOCKET bindUdpSocket(int addressFamily, struct sockaddr_storage* localAddr, SOCKADDR_LEN addrLen, int bufferSize) {
|
||||
// These set "safe" host or link-local QoS options that we can unconditionally
|
||||
// set without having to worry about routers blockholing the traffic.
|
||||
static void setSocketQos(SOCKET s, int socketQosType) {
|
||||
#ifdef SO_NET_SERVICE_TYPE
|
||||
int value;
|
||||
switch (socketQosType) {
|
||||
case SOCK_QOS_TYPE_BEST_EFFORT:
|
||||
value = NET_SERVICE_TYPE_BE;
|
||||
break;
|
||||
case SOCK_QOS_TYPE_AUDIO:
|
||||
value = NET_SERVICE_TYPE_VO;
|
||||
break;
|
||||
case SOCK_QOS_TYPE_VIDEO:
|
||||
value = NET_SERVICE_TYPE_VI;
|
||||
break;
|
||||
default:
|
||||
Limelog("Unknown QoS type: %d\n", socketQosType);
|
||||
return;
|
||||
}
|
||||
|
||||
// iOS/macOS
|
||||
if (setsockopt(s, SOL_SOCKET, SO_NET_SERVICE_TYPE, (char*)&value, sizeof(value)) < 0) {
|
||||
Limelog("setsockopt(SO_NET_SERVICE_TYPE, %d) failed: %d\n", value, (int)LastSocketError());
|
||||
}
|
||||
#endif
|
||||
#ifdef SO_PRIORITY
|
||||
int value;
|
||||
switch (socketQosType) {
|
||||
case SOCK_QOS_TYPE_BEST_EFFORT:
|
||||
value = 0;
|
||||
break;
|
||||
case SOCK_QOS_TYPE_AUDIO:
|
||||
value = 6;
|
||||
break;
|
||||
case SOCK_QOS_TYPE_VIDEO:
|
||||
value = 5;
|
||||
break;
|
||||
default:
|
||||
Limelog("Unknown QoS type: %d\n", socketQosType);
|
||||
return;
|
||||
}
|
||||
|
||||
// Linux
|
||||
if (setsockopt(s, SOL_SOCKET, SO_PRIORITY, (char*)&value, sizeof(value)) < 0) {
|
||||
Limelog("setsockopt(SO_PRIORITY, %d) failed: %d\n", value, (int)LastSocketError());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SOCKET bindUdpSocket(int addressFamily, struct sockaddr_storage* localAddr, SOCKADDR_LEN addrLen, int bufferSize, int socketQosType) {
|
||||
SOCKET s;
|
||||
LC_SOCKADDR bindAddr;
|
||||
int err;
|
||||
@ -294,6 +343,11 @@ SOCKET bindUdpSocket(int addressFamily, struct sockaddr_storage* localAddr, SOCK
|
||||
}
|
||||
#endif
|
||||
|
||||
// Enable QOS for the socket (best effort)
|
||||
if (socketQosType != SOCK_QOS_TYPE_BEST_EFFORT) {
|
||||
setSocketQos(s, socketQosType);
|
||||
}
|
||||
|
||||
if (bufferSize != 0) {
|
||||
// We start at the requested recv buffer value and step down until we find
|
||||
// a value that the OS will accept.
|
||||
|
@ -95,10 +95,14 @@ typedef struct sockaddr_in LC_SOCKADDR;
|
||||
#endif
|
||||
void addrToUrlSafeString(struct sockaddr_storage* addr, char* string, size_t stringLength);
|
||||
|
||||
#define SOCK_QOS_TYPE_BEST_EFFORT 0
|
||||
#define SOCK_QOS_TYPE_AUDIO 1
|
||||
#define SOCK_QOS_TYPE_VIDEO 2
|
||||
|
||||
SOCKET createSocket(int addressFamily, int socketType, int protocol, bool nonBlocking);
|
||||
SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port, int timeoutSec);
|
||||
int sendMtuSafe(SOCKET s, char* buffer, int size);
|
||||
SOCKET bindUdpSocket(int addressFamily, struct sockaddr_storage* localAddr, SOCKADDR_LEN addrLen, int bufferSize);
|
||||
SOCKET bindUdpSocket(int addressFamily, struct sockaddr_storage* localAddr, SOCKADDR_LEN addrLen, int bufferSize, int socketQosType);
|
||||
int enableNoDelay(SOCKET s);
|
||||
int setSocketNonBlocking(SOCKET s, bool enabled);
|
||||
int recvUdpSocket(SOCKET s, char* buffer, int size, bool useSelect);
|
||||
|
@ -73,7 +73,7 @@ int LiFindExternalAddressIP4(const char* stunServer, unsigned short stunPort, un
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
sock = bindUdpSocket(hints.ai_family, NULL, 0, 0);
|
||||
sock = bindUdpSocket(hints.ai_family, NULL, 0, 0, SOCK_QOS_TYPE_BEST_EFFORT);
|
||||
if (sock == INVALID_SOCKET) {
|
||||
err = LastSocketFail();
|
||||
Limelog("Failed to connect to STUN server: %d\n", err);
|
||||
|
@ -337,7 +337,8 @@ int startVideoStream(void* rendererContext, int drFlags) {
|
||||
}
|
||||
|
||||
rtpSocket = bindUdpSocket(RemoteAddr.ss_family, &LocalAddr, AddrLen,
|
||||
RTP_RECV_PACKETS_BUFFERED * (StreamConfig.packetSize + MAX_RTP_HEADER_SIZE));
|
||||
RTP_RECV_PACKETS_BUFFERED * (StreamConfig.packetSize + MAX_RTP_HEADER_SIZE),
|
||||
SOCK_QOS_TYPE_VIDEO);
|
||||
if (rtpSocket == INVALID_SOCKET) {
|
||||
VideoCallbacks.cleanup();
|
||||
return LastSocketError();
|
||||
|
Loading…
x
Reference in New Issue
Block a user