mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2025-08-17 17:05:50 +00:00
Parse the ports from RTSP SETUP instead of RTSP DESCRIBE
RTSP SETUP is better because it can provide multiple IP+port candidates
This commit is contained in:
parent
f05be47ed8
commit
46887c0447
@ -525,55 +525,34 @@ static int parseOpusConfigFromParamString(char* paramStr, int channelCount, POPU
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parseMediaEntry(PRTSP_MESSAGE response, const char* mediaType, const char* transport, uint16_t* port) {
|
// Parse the server port from the Transport header
|
||||||
char paramsPrefix[128];
|
// Example: unicast;server_port=48000-48001;source=192.168.35.177
|
||||||
char paramsSuffix[128];
|
static bool parseServerPortFromTransport(PRTSP_MESSAGE response, uint16_t* port) {
|
||||||
char* paramStart;
|
char* transport;
|
||||||
|
char* portStart;
|
||||||
|
|
||||||
sprintf(paramsPrefix, "m=%s ", mediaType);
|
transport = getOptionContent(response->options, "Transport");
|
||||||
sprintf(paramsSuffix, " %s", transport);
|
if (transport == NULL) {
|
||||||
|
return false;
|
||||||
// Look for the next match
|
|
||||||
paramStart = response->payload;
|
|
||||||
while ((paramStart = strstr(paramStart, paramsPrefix)) != NULL) {
|
|
||||||
// Skip the prefix
|
|
||||||
paramStart += strlen(paramsPrefix);
|
|
||||||
|
|
||||||
// The first part should be the port number
|
|
||||||
char* nextToken;
|
|
||||||
long int rawPort = strtol(paramStart, &nextToken, 10);
|
|
||||||
if (rawPort <= 0 || rawPort >= 65535) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip this entry if the transport isn't what we expect
|
|
||||||
if (strncmp(nextToken, paramsSuffix, strlen(paramsSuffix)) != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This entry is a match
|
|
||||||
*port = (uint16_t)rawPort;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No match for this media type and transport
|
// Look for the server_port= entry in the Transport option
|
||||||
return false;
|
portStart = strstr(transport, "server_port=");
|
||||||
}
|
if (portStart == NULL) {
|
||||||
|
return false;
|
||||||
static void parsePortConfigurations(PRTSP_MESSAGE response) {
|
|
||||||
// Don't parse ports on very old GFE versions
|
|
||||||
if (!APP_VERSION_AT_LEAST(7, 0, 0)) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parseMediaEntry(response, "video", "RTP/AVP", &VideoPortNumber);
|
// Skip the prefix
|
||||||
parseMediaEntry(response, "audio", "RTP/AVP", &AudioPortNumber);
|
portStart += strlen("server_port=");
|
||||||
|
|
||||||
if (!parseMediaEntry(response, "application", "udp", &ControlPortNumber)) {
|
// Validate the port number
|
||||||
if (!parseMediaEntry(response, "application", "udp_enc", &ControlPortNumber)) {
|
long int rawPort = strtol(portStart, NULL, 10);
|
||||||
parseMediaEntry(response, "application", "udp_ag", &ControlPortNumber);
|
if (rawPort <= 0 || rawPort >= 65535) {
|
||||||
}
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*port = (uint16_t)rawPort;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses the Opus configuration from an RTSP DESCRIBE response
|
// Parses the Opus configuration from an RTSP DESCRIBE response
|
||||||
@ -824,14 +803,6 @@ int performRtspHandshake(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse audio, video, and control ports out of the RTSP DESCRIBE response.
|
|
||||||
parsePortConfigurations(&response);
|
|
||||||
|
|
||||||
// Let the audio stream know the port number is now finalized.
|
|
||||||
// NB: This is needed because audio stream init happens before RTSP,
|
|
||||||
// which is not the case for the video stream.
|
|
||||||
notifyAudioPortNegotiationComplete();
|
|
||||||
|
|
||||||
// Parse the Opus surround parameters out of the RTSP DESCRIBE response.
|
// Parse the Opus surround parameters out of the RTSP DESCRIBE response.
|
||||||
ret = parseOpusConfigurations(&response);
|
ret = parseOpusConfigurations(&response);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@ -861,6 +832,14 @@ int performRtspHandshake(void) {
|
|||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse the audio port out of the RTSP SETUP response
|
||||||
|
parseServerPortFromTransport(&response, &AudioPortNumber);
|
||||||
|
|
||||||
|
// Let the audio stream know the port number is now finalized.
|
||||||
|
// NB: This is needed because audio stream init happens before RTSP,
|
||||||
|
// which is not the case for the video stream.
|
||||||
|
notifyAudioPortNegotiationComplete();
|
||||||
|
|
||||||
sessionId = getOptionContent(response.options, "Session");
|
sessionId = getOptionContent(response.options, "Session");
|
||||||
|
|
||||||
if (sessionId == NULL) {
|
if (sessionId == NULL) {
|
||||||
@ -905,6 +884,9 @@ int performRtspHandshake(void) {
|
|||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse the video port out of the RTSP SETUP response
|
||||||
|
parseServerPortFromTransport(&response, &VideoPortNumber);
|
||||||
|
|
||||||
freeMessage(&response);
|
freeMessage(&response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -927,6 +909,9 @@ int performRtspHandshake(void) {
|
|||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse the control port out of the RTSP SETUP response
|
||||||
|
parseServerPortFromTransport(&response, &ControlPortNumber);
|
||||||
|
|
||||||
freeMessage(&response);
|
freeMessage(&response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user