Skip to content

Commit

Permalink
extra audio codec support
Browse files Browse the repository at this point in the history
  • Loading branch information
mariotaku committed Apr 9, 2024
1 parent 1b29c0d commit b975143
Show file tree
Hide file tree
Showing 12 changed files with 67 additions and 33 deletions.
4 changes: 1 addition & 3 deletions core/libgamestream/libgamestream/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
19 changes: 15 additions & 4 deletions core/libgamestream/src/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion src/app/app.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);


Expand Down
4 changes: 2 additions & 2 deletions src/app/backend/pcmanager/pcmanager_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down
21 changes: 13 additions & 8 deletions src/app/stream/audio/session_audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,26 @@
#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;
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;
Expand All @@ -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 = {
Expand All @@ -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);
}

Expand Down Expand Up @@ -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,
Expand Down
22 changes: 17 additions & 5 deletions src/app/stream/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}

2 changes: 1 addition & 1 deletion src/app/stream/session_worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions src/app/ui/launcher/apps.controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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,
Expand Down
14 changes: 7 additions & 7 deletions src/app/ui/launcher/server.context_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand All @@ -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);
}
Expand Down
6 changes: 6 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <unistd.h>
#include "app.h"
#include "app_launch.h"
#include "util/path.h"
Expand All @@ -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);
Expand Down

0 comments on commit b975143

Please sign in to comment.