Merge pull request #877 from LizardByte/nightly

v0.18.2
This commit is contained in:
ReenigneArcher
2023-02-13 14:19:40 -05:00
committed by GitHub
22 changed files with 267 additions and 44 deletions

View File

@@ -29,7 +29,7 @@ updates:
target-branch: "nightly"
open-pull-requests-limit: 10
- package-ecosystem: "pip"
- package-ecosystem: "nuget"
directory: "/"
schedule:
interval: "daily"
@@ -37,10 +37,18 @@ updates:
target-branch: "nightly"
open-pull-requests-limit: 10
- package-ecosystem: "gitsubmodule"
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"
time: "10:00"
target-branch: "nightly"
open-pull-requests-limit: 10
- package-ecosystem: "gitsubmodule"
directory: "/"
schedule:
interval: "daily"
time: "10:30"
target-branch: "nightly"
open-pull-requests-limit: 10

View File

@@ -946,7 +946,7 @@ jobs:
runs-on: windows-latest # the required action can only be run on Windows
steps:
- name: Release to WinGet
uses: vedantmgoyal2009/winget-releaser@v1
uses: vedantmgoyal2009/winget-releaser@v2
with:
identifier: LizardByte.Sunshine
release-tag: ${{ needs.setup_release.outputs.release_tag }}

View File

@@ -315,7 +315,7 @@ jobs:
- name: Build artifacts
if: ${{ steps.prepare.outputs.artifacts == 'true' }}
id: build_artifacts
uses: docker/build-push-action@v3
uses: docker/build-push-action@v4
with:
context: ./
file: ${{ matrix.dockerfile }}
@@ -334,7 +334,7 @@ jobs:
- name: Build and push
id: build
uses: docker/build-push-action@v3
uses: docker/build-push-action@v4
with:
context: ./
file: ${{ matrix.dockerfile }}
@@ -362,7 +362,7 @@ jobs:
if: ${{ steps.prepare.outputs.artifacts == 'true' }}
uses: actions/upload-artifact@v3
with:
name: sunshine${{ matrix.tag }}
name: Docker${{ matrix.tag }}
path: artifacts/
- name: Create/Update GitHub Release

View File

@@ -1,5 +1,14 @@
# Changelog
## [0.18.2] - 2023-02-13
### Fixed
- (Video/KMV/Linux) Fixed wayland capture on Nvidia for KMS
- (Video/Linux) Implement vaSyncBuffer stuf for libva <2.9.0
- (UI) Fix issue where mime type was not being set for node_modules when using a reverse proxy
- (UI/macOS) Added missing audio sink config options
- (Linux) Specify correct Boost dependency versions
- (Video/AMF) Add missing encoder tunables
## [0.18.1] - 2023-01-31
### Fixed
- (Linux) Fixed missing dependencies for deb and rpm packages
@@ -307,3 +316,4 @@ settings. In v0.17.0, games now run under your user account without elevated pri
[0.17.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.17.0
[0.18.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.0
[0.18.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.1
[0.18.2]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.2

View File

@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.18)
# `CMAKE_CUDA_ARCHITECTURES` requires 3.18
project(Sunshine VERSION 0.18.1
project(Sunshine VERSION 0.18.2
DESCRIPTION "Sunshine is a self-hosted game stream host for Moonlight."
HOMEPAGE_URL "https://app.lizardbyte.dev")
@@ -789,10 +789,10 @@ elseif(UNIX)
set(CPACK_DEB_COMPONENT_INSTALL ON)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "\
${CPACK_DEB_PLATFORM_PACKAGE_DEPENDS} \
libboost-filesystem1.67.0 | libboost-filesystem1.71.0 | libboost-filesystem1.74.0, \
libboost-log1.67.0 | libboost-log1.71.0 | libboost-log1.74.0, \
libboost-program-options1.67.0 | libboost-program-options1.71.0 | libboost-program-options1.74.0, \
libboost-thread1.67.0 | libboost-thread1.71.0 | libboost-thread1.74.0, \
libboost-filesystem${Boost_VERSION}, \
libboost-log${Boost_VERSION}, \
libboost-program-options${Boost_VERSION}, \
libboost-thread${Boost_VERSION}, \
libcap2, \
libcurl4, \
libdrm2, \
@@ -808,10 +808,10 @@ elseif(UNIX)
openssl | libssl3")
set(CPACK_RPM_PACKAGE_REQUIRES "\
${CPACK_RPM_PLATFORM_PACKAGE_REQUIRES} \
boost-filesystem >= 1.67.0, \
boost-log >= 1.67.0, \
boost-program-options >= 1.67.0, \
boost-thread >= 1.67.0, \
boost-filesystem >= ${Boost_VERSION}, \
boost-log >= ${Boost_VERSION}, \
boost-program-options >= ${Boost_VERSION}, \
boost-thread >= ${Boost_VERSION}, \
libcap >= 2.22, \
libcurl >= 7.0, \
libdrm >= 2.4.97, \

View File

@@ -1,4 +1,4 @@
furo==2022.12.7
m2r2==0.3.3
m2r2==0.3.3.post2
Sphinx==6.1.3
sphinx-copybutton==0.5.1

View File

@@ -1081,6 +1081,68 @@ amd_rc
amd_rc = vbr_latency
amd_usage
^^^^^^^^^
**Description**
The encoder usage profile, used to balance latency with encoding quality.
.. Note:: This option only applies when using amdvce `encoder`_.
**Choices**
.. table::
:widths: auto
=============== ===========
Value Description
=============== ===========
transcoding transcoding (slowest)
webcam webcam (slow)
lowlatency low latency (fast)
ultralowlatency ultra low latency (fastest)
=============== ===========
**Default**
``ultralowlatency``
**Example**
.. code-block:: text
amd_usage = ultralowlatency
amd_preanalysis
^^^^^^^^^^^^^^^
**Description**
Preanalysis can increase encoding quality at the cost of latency.
.. Note:: This option only applies when using amdvce `encoder`_.
**Default**
``disabled``
**Example**
.. code-block:: text
amd_preanalysis = disabled
amd_vbaq
^^^^^^^^
**Description**
Variance Based Adaptive Quantization (VBAQ) can increase subjective visual quality.
.. Note:: This option only applies when using amdvce `encoder`_.
**Default**
``enabled``
**Example**
.. code-block:: text
amd_vbaq = enabled
amd_coder
^^^^^^^^^

View File

@@ -146,8 +146,7 @@ macOS
^^^^^
Sunshine can only access microphones on macOS due to system limitations. To stream system audio use
`Soundflower <https://github.com/mattingalls/Soundflower>`_ or
`BlackHole <https://github.com/ExistentialAudio/BlackHole>`_ and
select their sink as audio device in `sunshine.conf`.
`BlackHole <https://github.com/ExistentialAudio/BlackHole>`_.
.. Note:: Command Keys are not forwarded by Moonlight. Right Option-Key is mapped to CMD-Key.

View File

@@ -130,6 +130,14 @@ namespace amd {
#define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR 1
#define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR 2
#define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR 3
#define AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING 0
#define AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY 1
#define AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY 2
#define AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM 3
#define AMF_VIDEO_ENCODER_USAGE_TRANSCONDING 0
#define AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY 1
#define AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY 2
#define AMF_VIDEO_ENCODER_USAGE_WEBCAM 3
#define AMF_VIDEO_ENCODER_UNDEFINED 0
#define AMF_VIDEO_ENCODER_CABAC 1
#define AMF_VIDEO_ENCODER_CALV 2
@@ -164,6 +172,20 @@ enum class rc_h264_e : int {
cbr = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR
};
enum class usage_hevc_e : int {
transcoding = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING,
webcam = AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM,
lowlatency = AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY,
ultralowlatency = AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY
};
enum class usage_h264_e : int {
transcoding = AMF_VIDEO_ENCODER_USAGE_TRANSCONDING,
webcam = AMF_VIDEO_ENCODER_USAGE_WEBCAM,
lowlatency = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY,
ultralowlatency = AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY
};
enum coder_e : int {
_auto = AMF_VIDEO_ENCODER_UNDEFINED,
cabac = AMF_VIDEO_ENCODER_CABAC,
@@ -191,6 +213,17 @@ std::optional<int> rc_from_view(const std::string_view &rc, int codec) {
return std::nullopt;
}
std::optional<int> usage_from_view(const std::string_view &rc, int codec) {
#define _CONVERT_(x) \
if(rc == #x##sv) return codec == 0 ? (int)usage_hevc_e::x : (int)usage_h264_e::x
_CONVERT_(transcoding);
_CONVERT_(webcam);
_CONVERT_(lowlatency);
_CONVERT_(ultralowlatency);
#undef _CONVERT_
return std::nullopt;
}
int coder_from_view(const std::string_view &coder) {
if(coder == "auto"sv) return _auto;
if(coder == "cabac"sv || coder == "ac"sv) return cabac;
@@ -300,12 +333,16 @@ video_t video {
}, // qsv
{
(int)amd::quality_h264_e::balanced, // quality (h264)
(int)amd::quality_hevc_e::balanced, // quality (hevc)
(int)amd::rc_h264_e::vbr_latency, // rate control (h264)
(int)amd::rc_hevc_e::vbr_latency, // rate control (hevc)
(int)amd::coder_e::_auto, // coder
}, // amd
(int)amd::quality_h264_e::balanced, // quality (h264)
(int)amd::quality_hevc_e::balanced, // quality (hevc)
(int)amd::rc_h264_e::vbr_latency, // rate control (h264)
(int)amd::rc_hevc_e::vbr_latency, // rate control (hevc)
(int)amd::usage_h264_e::ultralowlatency, // usage (h264)
(int)amd::usage_hevc_e::ultralowlatency, // usage (hevc)
0, // preanalysis
1, // vbaq
(int)amd::coder_e::_auto, // coder
}, // amd
{
0,
@@ -826,6 +863,16 @@ void apply_config(std::unordered_map<std::string, std::string> &&vars) {
video.amd.rc_hevc = amd::rc_from_view(rc, 0);
}
std::string usage;
string_f(vars, "amd_usage", usage);
if(!usage.empty()) {
video.amd.usage_h264 = amd::usage_from_view(rc, 1);
video.amd.usage_hevc = amd::usage_from_view(rc, 0);
}
bool_f(vars, "amd_preanalysis", (bool &)video.amd.preanalysis);
bool_f(vars, "amd_vbaq", (bool &)video.amd.vbaq);
int_f(vars, "vt_coder", video.vt.coder, vt::coder_from_view);
int_f(vars, "vt_software", video.vt.allow_sw, vt::allow_software_from_view);
int_f(vars, "vt_software", video.vt.require_sw, vt::force_software_from_view);

View File

@@ -38,6 +38,10 @@ struct video_t {
std::optional<int> quality_hevc;
std::optional<int> rc_h264;
std::optional<int> rc_hevc;
std::optional<int> usage_h264;
std::optional<int> usage_hevc;
std::optional<int> preanalysis;
std::optional<int> vbaq;
int coder;
} amd;

View File

@@ -144,6 +144,7 @@ void not_found(resp_https_t response, req_https_t request) {
<< data.str();
}
// todo - combine these functions into a single function that accepts the page, i.e "index", "pin", "apps"
void getIndexPage(resp_https_t response, req_https_t request) {
if(!authenticate(response, request)) return;
@@ -229,6 +230,8 @@ void getTroubleshootingPage(resp_https_t response, req_https_t request) {
}
void getFaviconImage(resp_https_t response, req_https_t request) {
// todo - combine function with getSunshineLogoImage and possibly getNodeModules
// todo - use mime_types map
print_req(request);
std::ifstream in(WEB_DIR "images/favicon.ico", std::ios::binary);
@@ -238,6 +241,8 @@ void getFaviconImage(resp_https_t response, req_https_t request) {
}
void getSunshineLogoImage(resp_https_t response, req_https_t request) {
// todo - combine function with getFaviconImage and possibly getNodeModules
// todo - use mime_types map
print_req(request);
std::ifstream in(WEB_DIR "images/logo-sunshine-45.png", std::ios::binary);
@@ -269,17 +274,18 @@ void getNodeModules(resp_https_t response, req_https_t request) {
}
else {
auto relPath = fs::relative(filePath, webDirPath);
if(relPath.extension() == ".ttf" or relPath.extension() == ".woff2") {
// Fonts are read differntly
// get the mime type from the file extension mime_types map
// remove the leading period from the extension
auto mimeType = mime_types.find(relPath.extension().string().substr(1));
// check if the extension is in the map at the x position
if(mimeType != mime_types.end()) {
// if it is, set the content type to the mime type
SimpleWeb::CaseInsensitiveMultimap headers;
std::ifstream in((filePath).c_str(), std::ios::binary);
headers.emplace("Content-Type", "font/" + filePath.extension().string().substr(1));
headers.emplace("Content-Type", mimeType->second);
std::ifstream in(filePath.string(), std::ios::binary);
response->write(SimpleWeb::StatusCode::success_ok, in, headers);
}
else {
std::string content = read_file((filePath.string()).c_str());
response->write(content);
}
// do not return any file if the type is not in the map
}
}

View File

@@ -16,4 +16,23 @@ constexpr auto PORT_HTTPS = 1;
void start();
} // namespace confighttp
// mime types map
const std::map<std::string, std::string> mime_types = {
{ "css", "text/css" },
{ "gif", "image/gif" },
{ "htm", "text/html" },
{ "html", "text/html" },
{ "ico", "image/x-icon" },
{ "jpeg", "image/jpeg" },
{ "jpg", "image/jpeg" },
{ "js", "application/javascript" },
{ "json", "application/json" },
{ "png", "image/png" },
{ "svg", "image/svg+xml" },
{ "ttf", "font/ttf" },
{ "txt", "text/plain" },
{ "woff2", "font/woff2" },
{ "xml", "text/xml" },
};
#endif // SUNSHINE_CONFIGHTTP_H

View File

@@ -755,6 +755,12 @@ public:
auto &rgb = *rgb_opt;
gl::ctx.BindTexture(GL_TEXTURE_2D, rgb->tex[0]);
int w, h;
gl::ctx.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
gl::ctx.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
BOOST_LOG(debug) << "width and height: w "sv << w << " h "sv << h;
gl::ctx.GetTextureSubImage(rgb->tex[0], 0, img_offset_x, img_offset_y, 0, width, height, 1, GL_BGRA, GL_UNSIGNED_BYTE, img_out_base->height * img_out_base->row_pitch, img_out_base->data);
if(cursor_opt && cursor) {

View File

@@ -5,6 +5,17 @@
extern "C" {
#include <libavcodec/avcodec.h>
#include <va/va.h>
#if !VA_CHECK_VERSION(1, 9, 0)
/* vaSyncBuffer stub allows Sunshine built against libva <2.9.0
to link against ffmpeg on libva 2.9.0 or later */
VAStatus vaSyncBuffer(
VADisplay dpy,
VABufferID buf_id,
uint64_t timeout_ns) {
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
#endif
}
#include "graphics.h"

View File

@@ -167,7 +167,7 @@ public:
int w, h;
gl::ctx.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
gl::ctx.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &h);
gl::ctx.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
BOOST_LOG(debug) << "width and height: w "sv << w << " h "sv << h;
gl::ctx.GetTextureSubImage((*rgb_opt)->tex[0], 0, 0, 0, 0, width, height, 1, GL_BGRA, GL_UNSIGNED_BYTE, img_out_base->height * img_out_base->row_pitch, img_out_base->data);

View File

@@ -539,15 +539,16 @@ static encoder_t amdvce {
{
// Common options
{
{ "enforce_hrd"s, true },
{ "filler_data"s, true },
{ "gops_per_idr"s, 1 },
{ "header_insertion_mode"s, "idr"s },
{ "preanalysis"s, &config::video.amd.preanalysis },
{ "qmax"s, 51 },
{ "qmin"s, 0 },
{ "quality"s, &config::video.amd.quality_hevc },
{ "rc"s, &config::video.amd.rc_hevc },
{ "usage"s, "ultralowlatency"s },
{ "vbaq"s, true },
{ "usage"s, &config::video.amd.usage_hevc },
{ "vbaq"s, &config::video.amd.vbaq },
},
{}, // SDR-specific options
{}, // HDR-specific options
@@ -557,14 +558,15 @@ static encoder_t amdvce {
{
// Common options
{
{ "enforce_hrd"s, true },
{ "filler_data"s, true },
{ "log_to_dbg"s, "1"s },
{ "preanalysis"s, &config::video.amd.preanalysis },
{ "qmax"s, 51 },
{ "qmin"s, 0 },
{ "quality"s, &config::video.amd.quality_h264 },
{ "rc"s, &config::video.amd.rc_h264 },
{ "usage"s, "ultralowlatency"s },
{ "vbaq"s, true },
{ "usage"s, &config::video.amd.usage_h264 },
{ "vbaq"s, &config::video.amd.vbaq },
},
{}, // SDR-specific options
{}, // HDR-specific options

View File

@@ -369,6 +369,29 @@
<br />
</div>
</div>
<div class="mb-3" v-if="platform === 'macos'">
<label for="audio_sink" class="form-label">Audio Sink</label>
<input
type="text"
class="form-control"
id="audio_sink"
placeholder="BlackHole 2ch"
v-model="config.audio_sink"
/>
<div class="form-text">
The name of the audio sink used for Audio Loopback<br />
Sunshine can only access microphones on macOS due to system limitations.<br />
To stream system audio using <a
href="https://github.com/mattingalls/Soundflower"
target="_blank">
Soundflower
</a> or <a
href="https://github.com/ExistentialAudio/BlackHole"
target="_blank">
BlackHole
</a>.
</div>
</div>
<!--Virtual Sink-->
<div class="mb-3" v-if="platform === 'windows'">
<label for="virtual_sink" class="form-label">Virtual Sink</label>
@@ -742,6 +765,29 @@
<option value="cbr">cbr -- constant bitrate</option>
</select>
</div>
<div class="mb-3">
<label for="amd_usage" class="form-label">AMF Usage</label>
<select id="amd_usage" class="form-select" v-model="config.amd_usage">
<option value="transcoding">transcoding -- transcoding (slowest)</option>
<option value="webcam">webcam -- webcam (slow)</option>
<option value="lowlatency">lowlatency - low latency (fast)</option>
<option value="ultralowlatency">ultralowlatency - ultra low latency (fastest)</option>
</select>
</div>
<div class="mb-3">
<label for="amd_preanalysis" class="form-label">AMF Preanalysis</label>
<select id="amd_preanalysis" class="form-select" v-model="config.amd_preanalysis">
<option value="enabled">enabled</option>
<option value="disabled">disabled (default)</option>
</select>
</div>
<div class="mb-3">
<label for="amd_vbaq" class="form-label">AMF Variance Based Adaptive Quantization (VBAQ)</label>
<select id="amd_vbaq" class="form-select" v-model="config.amd_vbaq">
<option value="enabled">enabled (default)</option>
<option value="disabled">disabled</option>
</select>
</div>
<div class="mb-3">
<label for="amd_coder" class="form-label">AMF Coder (H264)</label>
<select id="amd_coder" class="form-select" v-model="config.amd_coder">
@@ -915,8 +961,11 @@
this.config.qsv_preset = this.config.qsv_preset || "medium";
this.config.qsv_coder = this.config.qsv_coder || "auto";
this.config.amd_coder = this.config.amd_coder || "auto"
this.config.amd_preanalysis = this.config.amd_preanalysis || "disabled";
this.config.amd_quality = this.config.amd_quality || "balanced";
this.config.amd_rc = this.config.amd_rc || "vbr_latency";
this.config.amd_usage = this.config.amd_usage || "ultralowlatency";
this.config.amd_vbaq = this.config.amd_vbaq || "enabled";
this.config.vt_coder = this.config.vt_coder || "auto";
this.config.vt_software = this.config.vt_software || "auto";
this.config.vt_realtime = this.config.vt_realtime || "enabled";