Allow automatic detection of remote streaming

This commit is contained in:
Cameron Gutman 2018-11-21 20:52:50 -08:00
parent 42df6475c8
commit 639ff18dbb
5 changed files with 65 additions and 5 deletions

View File

@ -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();

View File

@ -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.

View File

@ -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;

View File

@ -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);

View File

@ -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");
}