From fd72e351b88bc572ef60870e030b5d61c7fca53b Mon Sep 17 00:00:00 2001 From: Mariotaku Date: Tue, 16 Apr 2024 00:32:19 +0900 Subject: [PATCH] supports custom surround params --- src/audio.cpp | 10 ++++++++++ src/audio.h | 4 ++++ src/nvhttp.cpp | 1 + src/process.cpp | 1 + src/rtsp.cpp | 29 +++++++++++++++++++++++++++++ src/rtsp.h | 1 + 6 files changed, 46 insertions(+) diff --git a/src/audio.cpp b/src/audio.cpp index 1995e380ea7..5e64f1ed57c 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -99,6 +99,10 @@ namespace audio { encodeThread(sample_queue_t samples, config_t config, void *channel_data) { auto packets = mail::man->queue(mail::audio_packets); auto stream = &stream_configs[map_stream(config.channels, config.flags[config_t::HIGH_QUALITY])]; + if (config.flags[config_t::CUSTOM_SURROUND_PARAMS]) { + // sampleRate and bitrate are already updated in capture function + stream = &config.customStreamConfig; + } // Encoding takes place on this thread platf::adjust_thread_priority(platf::thread_priority_e::high); @@ -136,6 +140,12 @@ namespace audio { capture(safe::mail_t mail, config_t config, void *channel_data) { auto shutdown_event = mail->event(mail::shutdown); auto stream = &stream_configs[map_stream(config.channels, config.flags[config_t::HIGH_QUALITY])]; + if (config.flags[config_t::CUSTOM_SURROUND_PARAMS]) { + auto orig = stream; + stream = &config.customStreamConfig; + stream->sampleRate = orig->sampleRate; + stream->bitrate = orig->bitrate; + } auto ref = control_shared.ref(); if (!ref) { diff --git a/src/audio.h b/src/audio.h index fe22c94611d..9449f9474b2 100644 --- a/src/audio.h +++ b/src/audio.h @@ -32,6 +32,7 @@ namespace audio { enum flags_e : int { HIGH_QUALITY, HOST_AUDIO, + CUSTOM_SURROUND_PARAMS, MAX_FLAGS }; @@ -39,6 +40,9 @@ namespace audio { int channels; int mask; + std::uint8_t customStreamMapping[8]; + opus_stream_config_t customStreamConfig; + std::bitset flags; }; diff --git a/src/nvhttp.cpp b/src/nvhttp.cpp index 695820f4b3a..670bc3f2e48 100644 --- a/src/nvhttp.cpp +++ b/src/nvhttp.cpp @@ -296,6 +296,7 @@ namespace nvhttp { launch_session->appid = util::from_view(get_arg(args, "appid", "unknown")); launch_session->enable_sops = util::from_view(get_arg(args, "sops", "0")); launch_session->surround_info = util::from_view(get_arg(args, "surroundAudioInfo", "196610")); + launch_session->surround_params = (get_arg(args, "surroundParams", "")); launch_session->gcmap = util::from_view(get_arg(args, "gcmap", "0")); launch_session->enable_hdr = util::from_view(get_arg(args, "hdrMode", "0")); diff --git a/src/process.cpp b/src/process.cpp index 89dc4dc5ae5..32af14ebd9d 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -185,6 +185,7 @@ namespace proc { _env["SUNSHINE_CLIENT_AUDIO_CONFIGURATION"] = "7.1"; break; } + _env["SUNSHINE_CLIENT_AUDIO_SURROUND_PARAMS"] = launch_session->surround_params; if (!_app.output.empty() && _app.output != "null"sv) { #ifdef _WIN32 diff --git a/src/rtsp.cpp b/src/rtsp.cpp index 0180fbee37a..b860218ae86 100644 --- a/src/rtsp.cpp +++ b/src/rtsp.cpp @@ -818,6 +818,12 @@ namespace rtsp_stream { ss << "a=rtpmap:98 AV1/90000"sv << std::endl; } + if (!session.surround_params.empty()) { + // If we have our own surround parameters, advertise them twice first + ss << "a=fmtp:97 surround-params="sv << session.surround_params << std::endl; + ss << "a=fmtp:97 surround-params="sv << session.surround_params << std::endl; + } + for (int x = 0; x < audio::MAX_STREAM_CONFIG; ++x) { auto &stream_config = audio::stream_configs[x]; std::uint8_t mapping[platf::speaker::MAX_SPEAKERS]; @@ -1031,6 +1037,29 @@ namespace rtsp_stream { config.audio.flags[audio::config_t::HIGH_QUALITY] = (content.find("0.0.0.0"sv) == std::string::npos); } } + } else if (session.surround_params.length() > 3) { + // Channels + std::uint8_t c = session.surround_params[0] - '0'; + // Streams + std::uint8_t n = session.surround_params[1] - '0'; + // Coupled streams + std::uint8_t m = session.surround_params[2] - '0'; + auto valid = false; + if ((c == 6 || c == 8) && c == config.audio.channels && n + m == c && session.surround_params.length() == c + 3) { + config.audio.customStreamConfig.channelCount = c; + config.audio.customStreamConfig.streams = n; + config.audio.customStreamConfig.coupledStreams = m; + config.audio.customStreamConfig.mapping = config.audio.customStreamMapping; + valid = true; + for (std::uint8_t i = 0; i < c; i++) { + config.audio.customStreamMapping[i] = session.surround_params[i + 3] - '0'; + if (config.audio.customStreamMapping[i] >= c) { + valid = false; + break; + } + } + } + config.audio.flags[audio::config_t::CUSTOM_SURROUND_PARAMS] = valid; } // If the client sent a configured bitrate, we will choose the actual bitrate ourselves diff --git a/src/rtsp.h b/src/rtsp.h index 20bb8453998..16dba1e0592 100644 --- a/src/rtsp.h +++ b/src/rtsp.h @@ -29,6 +29,7 @@ namespace rtsp_stream { int gcmap; int appid; int surround_info; + std::string surround_params; bool enable_hdr; bool enable_sops;