From ab53f149f2383b39498e4b68ba5e6c2c09a47e0c Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 29 Aug 2023 20:46:35 -0500 Subject: [PATCH] Update moonlight-common-c with Sunshine extensions --- docs/README.pod | 6 +++--- libgamestream/client.c | 7 ++----- libgamestream/client.h | 1 - src/config.c | 9 ++++++--- src/config.h | 3 +-- src/main.c | 24 ++++++++++++++++++------ src/platform.c | 21 +++++++++++++++------ src/platform.h | 3 ++- third_party/moonlight-common-c | 2 +- 9 files changed, 48 insertions(+), 28 deletions(-) diff --git a/docs/README.pod b/docs/README.pod index 52608b7..0f2086a 100644 --- a/docs/README.pod +++ b/docs/README.pod @@ -99,9 +99,9 @@ By default, 1392 is used on LAN and 1024 on WAN. =item B<-codec> [I] Select codec to use. -Can be 'auto', 'h264', 'h265' or 'hevc'. -Not all video decoders do support H.265/HEVC. -Will still use H.264 if server doesn't support HEVC. +Can be 'auto', 'h264', 'h265', 'hevc', or 'av1'. +Not all video decoders support H.265/HEVC or AV1. +Will still use H.264 if server doesn't support HEVC or AV1. =item B<-remote> [I] diff --git a/libgamestream/client.c b/libgamestream/client.c index 6da825a..ad58f52 100644 --- a/libgamestream/client.c +++ b/libgamestream/client.c @@ -235,7 +235,7 @@ static int load_serverinfo(PSERVER_DATA server, bool https) { server->paired = pairedText != NULL && strcmp(pairedText, "1") == 0; server->currentGame = currentGameText == NULL ? 0 : atoi(currentGameText); - server->supports4K = serverCodecModeSupportText != NULL; + server->serverInfo.serverCodecModeSupport = serverCodecModeSupportText == NULL ? SCM_H264 : atoi(serverCodecModeSupportText); server->serverMajorVersion = atoi(server->serverInfo.serverInfoAppVersion); server->isNvidiaSoftware = strstr(stateText, "MJOLNIR") != NULL; @@ -714,9 +714,6 @@ int gs_start_app(PSERVER_DATA server, STREAM_CONFIGURATION *config, int appId, b if (!correct_mode && !server->unsupported) return GS_NOT_SUPPORTED_MODE; - if (config->height >= 2160 && !server->supports4K) - return GS_NOT_SUPPORTED_4K; - RAND_bytes(config->remoteInputAesKey, sizeof(config->remoteInputAesKey)); memset(config->remoteInputAesIv, 0, sizeof(config->remoteInputAesIv)); @@ -743,7 +740,7 @@ int gs_start_app(PSERVER_DATA server, STREAM_CONFIGURATION *config, int appId, b int surround_info = SURROUNDAUDIOINFO_FROM_AUDIO_CONFIGURATION(config->audioConfiguration); snprintf(url, sizeof(url), "https://%s:%u/%s?uniqueid=%s&uuid=%s&appid=%d&mode=%dx%dx%d&additionalStates=1&sops=%d&rikey=%s&rikeyid=%d&localAudioPlayMode=%d&surroundAudioInfo=%d&remoteControllersBitmap=%d&gcmap=%d%s", server->serverInfo.address, server->httpsPort, server->currentGame ? "resume" : "launch", unique_id, uuid_str, appId, config->width, config->height, fps, sops, rikey_hex, rikeyid, localaudio, surround_info, gamepad_mask, gamepad_mask, - config->enableHdr ? "&hdrMode=1&clientHdrCapVersion=0&clientHdrCapSupportedFlagsInUint32=0&clientHdrCapMetaDataId=NV_STATIC_METADATA_TYPE_1&clientHdrCapDisplayData=0x0x0x0x0x0x0x0x0x0x0" : ""); + (config->supportedVideoFormats & VIDEO_FORMAT_MASK_10BIT) ? "&hdrMode=1&clientHdrCapVersion=0&clientHdrCapSupportedFlagsInUint32=0&clientHdrCapMetaDataId=NV_STATIC_METADATA_TYPE_1&clientHdrCapDisplayData=0x0x0x0x0x0x0x0x0x0x0" : ""); if ((ret = http_request(url, data)) == GS_OK) server->currentGame = appId; else diff --git a/libgamestream/client.h b/libgamestream/client.h index 4afb168..d006774 100644 --- a/libgamestream/client.h +++ b/libgamestream/client.h @@ -31,7 +31,6 @@ typedef struct _SERVER_DATA { char* gpuType; bool paired; - bool supports4K; bool unsupported; bool isNvidiaSoftware; int currentGame; diff --git a/src/config.c b/src/config.c index 97f4eda..df13cad 100644 --- a/src/config.c +++ b/src/config.c @@ -17,6 +17,7 @@ * along with Moonlight; if not, see . */ +#include "platform.h" #include "config.h" #include "util.h" @@ -225,6 +226,8 @@ static void parse_argument(int c, char* value, PCONFIGURATION config) { config->codec = CODEC_H264; else if (strcasecmp(value, "h265") == 0 || strcasecmp(value, "hevc") == 0) config->codec = CODEC_HEVC; + else if (strcasecmp(value, "av1") == 0) + config->codec = CODEC_AV1; break; case 'y': config->unsupported = false; @@ -254,7 +257,7 @@ static void parse_argument(int c, char* value, PCONFIGURATION config) { config->port = atoi(value); break; case '7': - config->stream.enableHdr = true; + config->hdr = true; break; case 1: if (config->action == NULL) @@ -344,8 +347,7 @@ void config_parse(int argc, char* argv[], PCONFIGURATION config) { config->stream.packetSize = 1392; config->stream.streamingRemotely = STREAM_CFG_AUTO; config->stream.audioConfiguration = AUDIO_CONFIGURATION_STEREO; - config->stream.supportsHevc = false; - config->stream.enableHdr = false; + config->stream.supportedVideoFormats = SCM_H264; config->stream.encryptionFlags = ENCFLG_AUDIO; #ifdef __arm__ @@ -377,6 +379,7 @@ void config_parse(int argc, char* argv[], PCONFIGURATION config) { config->mouse_emulation = true; config->rotate = 0; config->codec = CODEC_UNSPECIFIED; + config->hdr = false; config->pin = 0; config->port = 47989; diff --git a/src/config.h b/src/config.h index 753c39c..91ee4a1 100644 --- a/src/config.h +++ b/src/config.h @@ -23,8 +23,6 @@ #define MAX_INPUTS 6 -enum codecs { CODEC_UNSPECIFIED, CODEC_H264, CODEC_HEVC }; - typedef struct _CONFIGURATION { STREAM_CONFIGURATION stream; int debug_level; @@ -47,6 +45,7 @@ typedef struct _CONFIGURATION { char* inputs[MAX_INPUTS]; int inputsCount; enum codecs codec; + bool hdr; int pin; unsigned short port; } CONFIGURATION, *PCONFIGURATION; diff --git a/src/main.c b/src/main.c index 3641bc6..d3b1dce 100644 --- a/src/main.c +++ b/src/main.c @@ -20,8 +20,8 @@ #include "loop.h" #include "connection.h" #include "configuration.h" -#include "config.h" #include "platform.h" +#include "config.h" #include "sdl.h" #include "audio/audio.h" @@ -96,7 +96,7 @@ static void stream(PSERVER_DATA server, PCONFIGURATION config, enum platform sys gamepads += sdl_gamepads; #endif int gamepad_mask = 0; - for (int i = 0; i < gamepads && i < 4; i++) + for (int i = 0; i < gamepads; i++) gamepad_mask = (gamepad_mask << 1) + 1; int ret = gs_start_app(server, &config->stream, appId, config->sops, config->localaudio, gamepad_mask); @@ -201,7 +201,7 @@ static void help() { printf("\t-fps \t\tSpecify the fps to use (default 60)\n"); printf("\t-bitrate \tSpecify the bitrate in Kbps\n"); printf("\t-packetsize \tSpecify the maximum packetsize in bytes\n"); - printf("\t-codec \t\tSelect used codec: auto/h264/h265 (default auto)\n"); + printf("\t-codec \t\tSelect used codec: auto/h264/h265/av1 (default auto)\n"); printf("\t-hdr\t\tEnable HDR streaming (experimental, requires host and device support)\n"); printf("\t-remote \t\t\tEnable optimizations for WAN streaming (default auto)\n"); printf("\t-app \t\tName of app to stream\n"); @@ -316,9 +316,21 @@ int main(int argc, char* argv[]) { fprintf(stderr, "You can't select a audio device for SDL\n"); exit(-1); } - config.stream.supportsHevc = config.codec != CODEC_H264 && (config.codec == CODEC_HEVC || platform_supports_hevc(system)); - if (config.stream.enableHdr && !config.stream.supportsHevc) { - fprintf(stderr, "HDR streaming requires HEVC codec\n"); + + config.stream.supportedVideoFormats = SCM_H264; + if (config.codec == CODEC_HEVC || (config.codec == CODEC_UNSPECIFIED && platform_prefers_codec(system, config.codec))) { + config.stream.supportedVideoFormats |= SCM_HEVC; + if (config.hdr) + config.stream.supportedVideoFormats |= SCM_HEVC_MAIN10; + } + if (config.codec == CODEC_AV1 || (config.codec == CODEC_UNSPECIFIED && platform_prefers_codec(system, config.codec))) { + config.stream.supportedVideoFormats |= SCM_AV1_MAIN8; + if (config.hdr) + config.stream.supportedVideoFormats |= SCM_AV1_MAIN10; + } + + if (config.hdr && !(config.stream.supportedVideoFormats & VIDEO_FORMAT_MASK_10BIT)) { + fprintf(stderr, "HDR streaming requires HEVC or AV1 codec\n"); exit(-1); } diff --git a/src/platform.c b/src/platform.c index 82c5cf5..0e873de 100644 --- a/src/platform.c +++ b/src/platform.c @@ -206,13 +206,22 @@ AUDIO_RENDERER_CALLBACKS* platform_get_audio(enum platform system, char* audio_d return NULL; } -bool platform_supports_hevc(enum platform system) { - switch (system) { - case AML: - case RK: - case X11_VAAPI: - case X11_VDPAU: +bool platform_prefers_codec(enum platform system, enum codecs codec) { + switch (codec) { + case CODEC_H264: + // H.264 is always supported return true; + case CODEC_HEVC: + switch (system) { + case AML: + case RK: + case X11_VAAPI: + case X11_VDPAU: + return true; + } + return false; + case CODEC_AV1: + return false; } return false; } diff --git a/src/platform.h b/src/platform.h index f80546f..67c5cc7 100644 --- a/src/platform.h +++ b/src/platform.h @@ -27,11 +27,12 @@ #define IS_EMBEDDED(SYSTEM) SYSTEM != SDL enum platform { NONE, SDL, X11, X11_VDPAU, X11_VAAPI, PI, MMAL, IMX, AML, RK, FAKE }; +enum codecs { CODEC_UNSPECIFIED, CODEC_H264, CODEC_HEVC, CODEC_AV1 }; enum platform platform_check(char*); PDECODER_RENDERER_CALLBACKS platform_get_video(enum platform system); PAUDIO_RENDERER_CALLBACKS platform_get_audio(enum platform system, char* audio_device); -bool platform_supports_hevc(enum platform system); +bool platform_prefers_codec(enum platform system, enum codecs codec); char* platform_name(enum platform system); void platform_start(enum platform system); diff --git a/third_party/moonlight-common-c b/third_party/moonlight-common-c index c9426a6..2bb026c 160000 --- a/third_party/moonlight-common-c +++ b/third_party/moonlight-common-c @@ -1 +1 @@ -Subproject commit c9426a6a71c4162e65dde8c0c71a25f1dbca46ba +Subproject commit 2bb026c763fc18807d7e4a93f918054c488f84e1