mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2025-08-18 01:15:46 +00:00
Allow automatic detection of remote streaming
This commit is contained in:
parent
42df6475c8
commit
639ff18dbb
@ -231,6 +231,25 @@ int LiStartConnection(PSERVER_INFORMATION serverInfo, PSTREAM_CONFIGURATION stre
|
||||
ListenerCallbacks.stageComplete(STAGE_NAME_RESOLUTION);
|
||||
Limelog("done\n");
|
||||
|
||||
// If STREAM_CFG_AUTO was requested, determine the streamingRemotely value
|
||||
// now that we have resolved the target address and impose the video packet
|
||||
// size cap if required.
|
||||
if (StreamConfig.streamingRemotely == STREAM_CFG_AUTO) {
|
||||
if (isPrivateNetworkAddress(&RemoteAddr)) {
|
||||
StreamConfig.streamingRemotely = STREAM_CFG_LOCAL;
|
||||
}
|
||||
else {
|
||||
StreamConfig.streamingRemotely = STREAM_CFG_REMOTE;
|
||||
|
||||
if (StreamConfig.packetSize > 1024) {
|
||||
// Cap packet size at 1024 for remote streaming to avoid
|
||||
// MTU problems and fragmentation.
|
||||
Limelog("Packet size capped at 1KB for remote streaming\n");
|
||||
StreamConfig.packetSize = 1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Limelog("Starting RTSP handshake...");
|
||||
ListenerCallbacks.stageStarting(STAGE_RTSP_HANDSHAKE);
|
||||
err = performRtspHandshake();
|
||||
|
@ -13,6 +13,11 @@ extern "C" {
|
||||
// Enable this definition during debugging to enable assertions
|
||||
//#define LC_DEBUG
|
||||
|
||||
// Values for the 'streamingRemotely' field below
|
||||
#define STREAM_CFG_LOCAL 0
|
||||
#define STREAM_CFG_REMOTE 1
|
||||
#define STREAM_CFG_AUTO 2
|
||||
|
||||
typedef struct _STREAM_CONFIGURATION {
|
||||
// Dimensions in pixels of the desired video stream
|
||||
int width;
|
||||
@ -24,11 +29,16 @@ typedef struct _STREAM_CONFIGURATION {
|
||||
// Bitrate of the desired video stream (audio adds another ~1 Mbps)
|
||||
int bitrate;
|
||||
|
||||
// Max video packet size in bytes (use 1024 if unsure)
|
||||
// Max video packet size in bytes (use 1024 if unsure). If STREAM_CFG_AUTO
|
||||
// determines the stream is remote (see below), it will cap this value at
|
||||
// 1024 to avoid MTU-related issues like packet loss and fragmentation.
|
||||
int packetSize;
|
||||
|
||||
// Set to non-zero value to enable remote (over the Internet)
|
||||
// streaming optimizations. If unsure, set to 0.
|
||||
// Determines whether to enable remote (over the Internet)
|
||||
// streaming optimizations. If unsure, set to STREAM_CFG_AUTO.
|
||||
// STREAM_CFG_AUTO uses a heuristic (whether the target address is
|
||||
// in the RFC 1918 address blocks) to decide whether the stream
|
||||
// is remote or not.
|
||||
int streamingRemotely;
|
||||
|
||||
// Specifies the channel configuration of the audio stream.
|
||||
|
@ -348,6 +348,33 @@ int resolveHostName(const char* host, int family, int tcpTestPort, struct sockad
|
||||
#endif
|
||||
}
|
||||
|
||||
int isPrivateNetworkAddress(struct sockaddr_storage* address) {
|
||||
unsigned int addr;
|
||||
|
||||
// We only count IPv4 addresses as possibly private for now
|
||||
if (address->ss_family != AF_INET) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&addr, &((struct sockaddr_in*)address)->sin_addr, sizeof(addr));
|
||||
addr = htonl(addr);
|
||||
|
||||
// 10.0.0.0/8
|
||||
if ((addr & 0xFF000000) == 0x0A000000) {
|
||||
return 1;
|
||||
}
|
||||
// 172.16.0.0/12
|
||||
else if ((addr & 0xFFF00000) == 0xAC100000) {
|
||||
return 1;
|
||||
}
|
||||
// 192.168.0.0/16
|
||||
else if ((addr & 0xFFFF0000) == 0xC0A80000) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int initializePlatformSockets(void) {
|
||||
#if defined(LC_WINDOWS)
|
||||
WSADATA data;
|
||||
|
@ -81,3 +81,4 @@ void shutdownTcpSocket(SOCKET s);
|
||||
int setNonFatalRecvTimeoutMs(SOCKET s, int timeoutMs);
|
||||
void setRecvTimeout(SOCKET s, int timeoutSec);
|
||||
void closeSocket(SOCKET s);
|
||||
int isPrivateNetworkAddress(struct sockaddr_storage* address);
|
||||
|
@ -176,6 +176,9 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
|
||||
int audioChannelMask;
|
||||
int err;
|
||||
|
||||
// This must have been resolved to either local or remote by now
|
||||
LC_ASSERT(StreamConfig.streamingRemotely != STREAM_CFG_AUTO);
|
||||
|
||||
optionHead = NULL;
|
||||
err = 0;
|
||||
|
||||
@ -259,7 +262,7 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
|
||||
err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.maximumBitrateKbps", payloadStr);
|
||||
}
|
||||
else {
|
||||
if (StreamConfig.streamingRemotely) {
|
||||
if (StreamConfig.streamingRemotely == STREAM_CFG_REMOTE) {
|
||||
err |= addAttributeString(&optionHead, "x-nv-video[0].averageBitrate", "4");
|
||||
err |= addAttributeString(&optionHead, "x-nv-video[0].peakBitrate", "4");
|
||||
}
|
||||
@ -274,7 +277,7 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
|
||||
|
||||
err |= addAttributeString(&optionHead, "x-nv-vqos[0].videoQualityScoreUpdateTime", "5000");
|
||||
|
||||
if (StreamConfig.streamingRemotely) {
|
||||
if (StreamConfig.streamingRemotely == STREAM_CFG_REMOTE) {
|
||||
err |= addAttributeString(&optionHead, "x-nv-vqos[0].qosTrafficType", "0");
|
||||
err |= addAttributeString(&optionHead, "x-nv-aqos.qosTrafficType", "0");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user