mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-06-17 14:21:30 +00:00
Allow automatic detection of remote streaming
This commit is contained in:
@@ -231,6 +231,25 @@ int LiStartConnection(PSERVER_INFORMATION serverInfo, PSTREAM_CONFIGURATION stre
|
|||||||
ListenerCallbacks.stageComplete(STAGE_NAME_RESOLUTION);
|
ListenerCallbacks.stageComplete(STAGE_NAME_RESOLUTION);
|
||||||
Limelog("done\n");
|
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...");
|
Limelog("Starting RTSP handshake...");
|
||||||
ListenerCallbacks.stageStarting(STAGE_RTSP_HANDSHAKE);
|
ListenerCallbacks.stageStarting(STAGE_RTSP_HANDSHAKE);
|
||||||
err = performRtspHandshake();
|
err = performRtspHandshake();
|
||||||
|
|||||||
+13
-3
@@ -13,6 +13,11 @@ extern "C" {
|
|||||||
// Enable this definition during debugging to enable assertions
|
// Enable this definition during debugging to enable assertions
|
||||||
//#define LC_DEBUG
|
//#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 {
|
typedef struct _STREAM_CONFIGURATION {
|
||||||
// Dimensions in pixels of the desired video stream
|
// Dimensions in pixels of the desired video stream
|
||||||
int width;
|
int width;
|
||||||
@@ -24,11 +29,16 @@ typedef struct _STREAM_CONFIGURATION {
|
|||||||
// Bitrate of the desired video stream (audio adds another ~1 Mbps)
|
// Bitrate of the desired video stream (audio adds another ~1 Mbps)
|
||||||
int bitrate;
|
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;
|
int packetSize;
|
||||||
|
|
||||||
// Set to non-zero value to enable remote (over the Internet)
|
// Determines whether to enable remote (over the Internet)
|
||||||
// streaming optimizations. If unsure, set to 0.
|
// 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;
|
int streamingRemotely;
|
||||||
|
|
||||||
// Specifies the channel configuration of the audio stream.
|
// Specifies the channel configuration of the audio stream.
|
||||||
|
|||||||
@@ -348,6 +348,33 @@ int resolveHostName(const char* host, int family, int tcpTestPort, struct sockad
|
|||||||
#endif
|
#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) {
|
int initializePlatformSockets(void) {
|
||||||
#if defined(LC_WINDOWS)
|
#if defined(LC_WINDOWS)
|
||||||
WSADATA data;
|
WSADATA data;
|
||||||
|
|||||||
@@ -81,3 +81,4 @@ void shutdownTcpSocket(SOCKET s);
|
|||||||
int setNonFatalRecvTimeoutMs(SOCKET s, int timeoutMs);
|
int setNonFatalRecvTimeoutMs(SOCKET s, int timeoutMs);
|
||||||
void setRecvTimeout(SOCKET s, int timeoutSec);
|
void setRecvTimeout(SOCKET s, int timeoutSec);
|
||||||
void closeSocket(SOCKET s);
|
void closeSocket(SOCKET s);
|
||||||
|
int isPrivateNetworkAddress(struct sockaddr_storage* address);
|
||||||
|
|||||||
+5
-2
@@ -176,6 +176,9 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
|
|||||||
int audioChannelMask;
|
int audioChannelMask;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
// This must have been resolved to either local or remote by now
|
||||||
|
LC_ASSERT(StreamConfig.streamingRemotely != STREAM_CFG_AUTO);
|
||||||
|
|
||||||
optionHead = NULL;
|
optionHead = NULL;
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
@@ -259,7 +262,7 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
|
|||||||
err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.maximumBitrateKbps", payloadStr);
|
err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.maximumBitrateKbps", payloadStr);
|
||||||
}
|
}
|
||||||
else {
|
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].averageBitrate", "4");
|
||||||
err |= addAttributeString(&optionHead, "x-nv-video[0].peakBitrate", "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");
|
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-vqos[0].qosTrafficType", "0");
|
||||||
err |= addAttributeString(&optionHead, "x-nv-aqos.qosTrafficType", "0");
|
err |= addAttributeString(&optionHead, "x-nv-aqos.qosTrafficType", "0");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user