diff --git a/core/libgamestream/libgamestream/client.h b/core/libgamestream/libgamestream/client.h index 1101fc353..f5ee3a1ef 100644 --- a/core/libgamestream/libgamestream/client.h +++ b/core/libgamestream/libgamestream/client.h @@ -38,10 +38,8 @@ typedef struct _SERVER_DATA { /** ExternalPort */ unsigned short extPort; bool paired; - bool supports4K; - bool supportsHdr; bool unsupported; - bool isGfe; + bool isNvidiaSoftware; int currentGame; int serverMajorVersion; const char *gsVersion; diff --git a/core/libgamestream/src/client.c b/core/libgamestream/src/client.c index 93ae11480..926156e0f 100644 --- a/core/libgamestream/src/client.c +++ b/core/libgamestream/src/client.c @@ -512,7 +512,7 @@ int gs_start_app(GS_CLIENT hnd, PSERVER_DATA server, STREAM_CONFIGURATION *confi return gs_set_error(GS_NOT_SUPPORTED_MODE, "Selected mode is not supported by the host"); } - if (config->height >= 2160 && !server->supports4K) { + if (config->height >= 2160 && !server->serverInfo.serverCodecModeSupport) { return gs_set_error(GS_NOT_SUPPORTED_4K, "Host doesn't support 4K"); } @@ -728,6 +728,7 @@ static int load_server_status(GS_CLIENT hnd, PSERVER_DATA server) { char *currentGameText = NULL; char *stateText = NULL; char *serverCodecModeSupportText = NULL; + char *serverAudioCodecSupportText = NULL; char *httpsPortText = NULL; char *externalPortText = NULL; @@ -787,6 +788,10 @@ static int load_server_status(GS_CLIENT hnd, PSERVER_DATA server) { goto cleanup; } + if (xml_search(data->memory, data->size, "ServerAudioCodecSupport", &serverAudioCodecSupportText) != GS_OK) { + goto cleanup; + } + if (xml_search(data->memory, data->size, "gputype", (char **) &server->gpuType) != GS_OK) { goto cleanup; } @@ -820,16 +825,18 @@ static int load_server_status(GS_CLIENT hnd, PSERVER_DATA server) { int serverCodecModeSupport = serverCodecModeSupportText == NULL ? 0 : (int) strtol(serverCodecModeSupportText, NULL, 0); + int serverAudioCodecSupport = serverAudioCodecSupportText == NULL ? 0 : + (int) strtol(serverAudioCodecSupportText, NULL, 0); server->paired = pairedText != NULL && strcmp(pairedText, "1") == 0; server->currentGame = currentGameText == NULL ? 0 : (int) strtol(currentGameText, NULL, 0); - server->supports4K = serverCodecModeSupport != 0; - server->supportsHdr = serverCodecModeSupport & 0x200; + server->serverInfo.serverCodecModeSupport = serverCodecModeSupport == 0 ? SCM_H264 : serverCodecModeSupport; + server->serverInfo.serverAudioCodecSupport = serverAudioCodecSupport == 0 ? SAC_OPUS : serverAudioCodecSupport; server->serverMajorVersion = (int) strtol(server->serverInfo.serverInfoAppVersion, NULL, 0); // Real Nvidia host software (GeForce Experience and RTX Experience) both use the 'Mjolnir' // codename in the state field and no version of Sunshine does. We can use this to bypass // some assumptions about Nvidia hardware that don't apply to Sunshine hosts. - server->isGfe = strstr(stateText, "MJOLNIR") != NULL; + server->isNvidiaSoftware = strstr(stateText, "MJOLNIR") != NULL; server->httpsPort = httpsPortText == NULL ? 0 : (int) strtol(httpsPortText, NULL, 0); server->extPort = externalPortText == NULL ? 0 : (int) strtol(externalPortText, NULL, 0); @@ -862,6 +869,10 @@ static int load_server_status(GS_CLIENT hnd, PSERVER_DATA server) { free(serverCodecModeSupportText); } + if (serverAudioCodecSupportText != NULL) { + free(serverAudioCodecSupportText); + } + i++; } while (ret != GS_OK && i < 2); diff --git a/core/moonlight-common-c b/core/moonlight-common-c index eb2156154..187678d1c 160000 --- a/core/moonlight-common-c +++ b/core/moonlight-common-c @@ -1 +1 @@ -Subproject commit eb21561541874d9e9dbd7da26000c6dd55050748 +Subproject commit 187678d1cadc8fcab71b78f32ba0b8da1d8cf419 diff --git a/src/app/app.c b/src/app/app.c index 91d9c3f60..5888750be 100644 --- a/src/app/app.c +++ b/src/app/app.c @@ -322,7 +322,7 @@ static void libs_init(app_t *app, int argc, char *argv[]) { }; SS4S_Init(argc, argv, &ss4s_config); - SS4S_GetAudioCapabilities(&app->ss4s.audio_cap); + SS4S_GetAudioCapabilitiesByCodecs(&app->ss4s.audio_cap, SS4S_AUDIO_PCM_S16LE | SS4S_AUDIO_AC3 | SS4S_AUDIO_AAC); SS4S_GetVideoCapabilities(&app->ss4s.video_cap); diff --git a/src/app/backend/pcmanager/pcmanager_common.c b/src/app/backend/pcmanager/pcmanager_common.c index 7b153f088..07eff8f74 100644 --- a/src/app/backend/pcmanager/pcmanager_common.c +++ b/src/app/backend/pcmanager/pcmanager_common.c @@ -25,8 +25,6 @@ PSERVER_DATA serverdata_clone(const SERVER_DATA *src) { server->extPort = src->extPort; server->httpsPort = src->httpsPort; server->paired = src->paired; - server->supports4K = src->supports4K; - server->supportsHdr = src->supportsHdr; server->unsupported = src->unsupported; server->currentGame = src->currentGame; server->serverMajorVersion = src->serverMajorVersion; @@ -36,6 +34,8 @@ PSERVER_DATA serverdata_clone(const SERVER_DATA *src) { server->serverInfo.rtspSessionUrl = strdup_nullable(src->serverInfo.rtspSessionUrl); server->serverInfo.serverInfoAppVersion = strdup_nullable(src->serverInfo.serverInfoAppVersion); server->serverInfo.serverInfoGfeVersion = strdup_nullable(src->serverInfo.serverInfoGfeVersion); + server->serverInfo.serverCodecModeSupport = src->serverInfo.serverCodecModeSupport; + server->serverInfo.serverAudioCodecSupport = src->serverInfo.serverAudioCodecSupport; return server; } diff --git a/src/app/stream/audio/session_audio.c b/src/app/stream/audio/session_audio.c index 7d6523310..c616fb56f 100644 --- a/src/app/stream/audio/session_audio.c +++ b/src/app/stream/audio/session_audio.c @@ -3,8 +3,7 @@ #include "stream/connection/session_connection.h" #include "ss4s.h" #include "stream/session_priv.h" - -#define SAMPLES_PER_FRAME 240 +#include "logging.h" static session_t *session = NULL; static SS4S_Player *player = NULL; @@ -12,14 +11,18 @@ static OpusMSDecoder *decoder = NULL; static unsigned char *pcmbuf = NULL; static int frame_size = 0, unit_size = 0; -static int aud_init(int audioConfiguration, const POPUS_MULTISTREAM_CONFIGURATION opusConfig, void *context, - int arFlags) { +static int aud_init(int audioFormat, int audioConfiguration, const OPUS_MULTISTREAM_CONFIGURATION *opusConfig, + void *context, int arFlags) { (void) audioConfiguration; (void) arFlags; session = context; player = session->player; SS4S_AudioCodec codec = SS4S_AUDIO_PCM_S16LE; - if (session->audio_cap.codecs & SS4S_AUDIO_OPUS) { + if (audioFormat & AUDIO_FORMAT_MASK_AC3) { + codec = SS4S_AUDIO_AC3; + decoder = NULL; + pcmbuf = NULL; + } else if (session->audio_cap.codecs & SS4S_AUDIO_OPUS) { codec = SS4S_AUDIO_OPUS; decoder = NULL; pcmbuf = NULL; @@ -30,8 +33,8 @@ static int aud_init(int audioConfiguration, const POPUS_MULTISTREAM_CONFIGURATIO if (rc != 0) { return rc; } - frame_size = SAMPLES_PER_FRAME * 64; unit_size = (int) (opusConfig->channelCount * sizeof(int16_t)); + frame_size = opusConfig->samplesPerFrame; pcmbuf = calloc(unit_size, frame_size); } SS4S_AudioInfo info = { @@ -40,8 +43,10 @@ static int aud_init(int audioConfiguration, const POPUS_MULTISTREAM_CONFIGURATIO .appName = "Moonlight", .streamName = "Streaming", .sampleRate = opusConfig->sampleRate, - .samplesPerFrame = SAMPLES_PER_FRAME, + .samplesPerFrame = opusConfig->samplesPerFrame, }; + commons_log_info("Audio", "Audio init: codec=%s, sampleRate=%d, channelCount=%d, samplesPerFrame=%d", + SS4S_AudioCodecName(codec), info.sampleRate, info.numOfChannels, info.samplesPerFrame); return SS4S_PlayerAudioOpen(player, &info); } @@ -72,7 +77,7 @@ static void aud_feed(char *sampleData, int sampleLength) { } AUDIO_RENDERER_CALLBACKS ss4s_aud_callbacks = { - .init = aud_init, + .init2 = aud_init, .cleanup = aud_cleanup, .decodeAndPlaySample = aud_feed, .capabilities = CAPABILITY_DIRECT_SUBMIT, diff --git a/src/app/stream/session.c b/src/app/stream/session.c index 3f6bc0144..5e50926ce 100644 --- a/src/app/stream/session.c +++ b/src/app/stream/session.c @@ -264,15 +264,16 @@ void session_config_init(app_t *app, session_config_t *config, const SERVER_DATA if (video_cap.codecs & SS4S_VIDEO_H264) { config->stream.supportedVideoFormats |= VIDEO_FORMAT_H264; } - if (app_config->hevc && video_cap.codecs & SS4S_VIDEO_H265) { + int scm = server->serverInfo.serverCodecModeSupport; + if (app_config->hevc && scm & SCM_MASK_HEVC && video_cap.codecs & SS4S_VIDEO_H265) { config->stream.supportedVideoFormats |= VIDEO_FORMAT_H265; - if (app_config->hdr && video_cap.hdr) { + if (app_config->hdr && scm & SCM_HEVC_MAIN10 && video_cap.hdr) { config->stream.supportedVideoFormats |= VIDEO_FORMAT_H265_MAIN10; } } - if (app_config->av1 && video_cap.codecs & SS4S_VIDEO_AV1) { + if (app_config->av1 && scm & SCM_MASK_AV1 && video_cap.codecs & SS4S_VIDEO_AV1) { config->stream.supportedVideoFormats |= VIDEO_FORMAT_AV1_MAIN8; - if (app_config->hdr && video_cap.hdr) { + if (app_config->hdr && scm & SCM_AV1_MAIN10 && video_cap.hdr) { config->stream.supportedVideoFormats |= VIDEO_FORMAT_AV1_MAIN10; } } @@ -300,6 +301,17 @@ void session_config_init(app_t *app, session_config_t *config, const SERVER_DATA config->stream.audioConfiguration = AUDIO_CONFIGURATION_STEREO; } #endif - config->stream.encryptionFlags = ENCFLG_AUDIO; + int sac = server->serverInfo.serverAudioCodecSupport; + if (sac & SAC_MASK_AC3 && audio_cap.codecs & SS4S_AUDIO_AC3) { + config->stream.supportedAudioFormats |= AUDIO_FORMAT_AC3; + } + if (sac & SAC_MASK_AAC && audio_cap.codecs & SS4S_AUDIO_AAC) { + config->stream.supportedAudioFormats |= AUDIO_FORMAT_AAC; + } + if (config->stream.supportedAudioFormats == 0) { + config->stream.supportedAudioFormats = AUDIO_FORMAT_OPUS; + } + + config->stream.encryptionFlags = ENCFLG_ALL; } diff --git a/src/app/stream/session_worker.c b/src/app/stream/session_worker.c index eb48f8522..7f48119b8 100644 --- a/src/app/stream/session_worker.c +++ b/src/app/stream/session_worker.c @@ -24,7 +24,7 @@ int session_worker(session_t *session) { commons_log_info("Session", "Launch app %d...", appId); GS_CLIENT client = app_gs_client_new(app); gs_set_timeout(client, 30); - int ret = gs_start_app(client, server, &session->config.stream, appId, server->isGfe, session->config.sops, + int ret = gs_start_app(client, server, &session->config.stream, appId, server->isNvidiaSoftware, session->config.sops, session->config.local_audio, app_input_gamepads_mask(&app->input)); if (ret != GS_OK) { session_set_state(session, STREAMING_ERROR); diff --git a/src/app/ui/launcher/apps.controller.c b/src/app/ui/launcher/apps.controller.c index b1405a002..af2d181d9 100644 --- a/src/app/ui/launcher/apps.controller.c +++ b/src/app/ui/launcher/apps.controller.c @@ -21,6 +21,7 @@ #include "util/i18n.h" #include "pair.dialog.h" #include "ui/common/progress_dialog.h" +#include "logging.h" typedef void (*action_cb_t)(apps_fragment_t *controller, lv_obj_t *buttons, uint16_t index); @@ -576,6 +577,7 @@ static void item_longpress_cb(lv_event_t *event) { static void launcher_launch_game(apps_fragment_t *controller, const apploader_item_t *app) { LV_ASSERT(app->base.id != 0); + commons_log_info("Apps" ,"Launching app %d", app->base.id); streaming_scene_arg_t args = { .global = controller->global, .uuid = controller->uuid, diff --git a/src/app/ui/launcher/server.context_menu.c b/src/app/ui/launcher/server.context_menu.c index a56aa0c1e..cd94ea2ce 100644 --- a/src/app/ui/launcher/server.context_menu.c +++ b/src/app/ui/launcher/server.context_menu.c @@ -120,7 +120,7 @@ static void context_menu_click_cb(lv_event_t *e) { open_info(node); } else if (target_userdata == forget_host) { forget_host(node); - }else if (target_userdata == show_hidden_apps) { + } else if (target_userdata == show_hidden_apps) { show_hidden_apps(node); } } @@ -130,14 +130,14 @@ static void open_info(const pclist_t *node) { const SERVER_DATA *server = node->server; lv_obj_t *mbox = lv_msgbox_create_i18n(NULL, server->hostname, "placeholder", btn_txts, false); lv_obj_t *message = lv_msgbox_get_text(mbox); - lv_label_set_text_fmt(message, locstr("IP address: %s\nGPU: %s\nSupports 4K: %s\n" - "Supports HDR: %s\nHost Software Version: %s\n" - "GeForce Experience: %s"), + lv_label_set_text_fmt(message, locstr( + "IP address: %s\n" + "GPU: %s\n" + "Host Software Version: %s\n" + "GeForce Experience: %s"), server->serverInfo.address, str_null_or_empty(server->gpuType) ? "Unknown" : server->gpuType, - server->supports4K ? "YES" : "NO", - server->supportsHdr ? "YES" : "NO", server->serverInfo.serverInfoAppVersion, - server->isGfe ? server->serverInfo.serverInfoGfeVersion : "NO"); + server->isNvidiaSoftware ? server->serverInfo.serverInfoGfeVersion : "NO"); lv_obj_add_event_cb(mbox, info_action_cb, LV_EVENT_VALUE_CHANGED, NULL); lv_obj_center(mbox); } diff --git a/src/main.c b/src/main.c index ae34452ca..dacf315ec 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,4 @@ +#include #include "app.h" #include "app_launch.h" #include "util/path.h" @@ -12,6 +13,11 @@ static int settings_load(app_settings_t *settings); int main(int argc, char *argv[]) { + static char log_path[1024]; + snprintf(log_path, sizeof(log_path), "/tmp/gst-moonlight-%d.log", getpid()); + setenv("GST_DEBUG_FILE_OVERWRITE", "enable", 1); + setenv("GST_DEBUG_FILE", log_path, 1); + setenv("GST_DEBUG", "4,rtkalsa:6,rtkaudiobasesink:6", 1); #ifdef TARGET_WEBOS if (getenv("EGL_PLATFORM") == NULL) { setenv("EGL_PLATFORM", "wayland", 0); diff --git a/third_party/ss4s b/third_party/ss4s index 38e00fb49..96a2eecad 160000 --- a/third_party/ss4s +++ b/third_party/ss4s @@ -1 +1 @@ -Subproject commit 38e00fb492259d2f47154d949355340fddfe407a +Subproject commit 96a2eecadc651b942d266ff60c2831a5e8d47ab5