mirror of
https://github.com/LizardByte/Sunshine.git
synced 2026-08-07 18:36:34 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a00f7985f1 | |||
| 8e4fccdfc6 | |||
| 4353158d60 | |||
| 69751d1943 | |||
| 6300ea0641 | |||
| 31801ad4ea | |||
| d3a73d47c9 |
@@ -0,0 +1,256 @@
|
||||
---
|
||||
name: CI-FreeBSD
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
release_commit:
|
||||
required: true
|
||||
type: string
|
||||
release_version:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
env:
|
||||
FREEBSD_CLANG_VERSION: 19
|
||||
|
||||
jobs:
|
||||
setup-matrix:
|
||||
name: Setup Build Matrix
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.generate-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- name: Generate Matrix
|
||||
id: generate-matrix
|
||||
shell: bash
|
||||
run: |
|
||||
# Base matrix with amd64 build
|
||||
matrix='{
|
||||
"include": [
|
||||
{
|
||||
"bsd_release": "14.3",
|
||||
"arch": "x86_64",
|
||||
"cmake_processor": "amd64",
|
||||
"runner": "ubuntu-latest"
|
||||
}
|
||||
]
|
||||
}'
|
||||
|
||||
# Add aarch64 build only if not a pull request event
|
||||
if [[ "${{ github.event_name }}" != "pull_request" ]]; then
|
||||
matrix=$(echo "$matrix" | jq '.include += [{
|
||||
"bsd_release": "14.3",
|
||||
"arch": "aarch64",
|
||||
"cmake_processor": "aarch64",
|
||||
"runner": "ubuntu-latest"
|
||||
}]')
|
||||
fi
|
||||
|
||||
# Use heredoc for multiline JSON output
|
||||
{
|
||||
echo "matrix<<EOF"
|
||||
echo "$matrix"
|
||||
echo "EOF"
|
||||
} >> "${GITHUB_OUTPUT}"
|
||||
|
||||
echo "Generated matrix:"
|
||||
echo "$matrix" | jq .
|
||||
|
||||
build_freebsd:
|
||||
name: ${{ matrix.cmake_processor }}-${{ matrix.bsd_release }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: setup-matrix
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.setup-matrix.outputs.matrix) }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Get Processor Count
|
||||
id: processor_count
|
||||
shell: bash
|
||||
run: |
|
||||
PROCESSOR_COUNT=$(nproc)
|
||||
echo "PROCESSOR_COUNT=${PROCESSOR_COUNT}" >> "${GITHUB_OUTPUT}"
|
||||
echo "PROCESSOR_COUNT: $PROCESSOR_COUNT"
|
||||
|
||||
- name: Setup FreeBSD
|
||||
uses: vmactions/freebsd-vm@v1.2.3
|
||||
with:
|
||||
arch: ${{ matrix.arch }}
|
||||
cpu: ${{ steps.processor_count.outputs.PROCESSOR_COUNT }}
|
||||
# TODO: there is no libcap for freebsd... we need graphics/libdrm if we find a way to use libcap
|
||||
# TODO: docs are off because doxygen is too old: https://www.freshports.org/devel/doxygen/ must be >= 1.10
|
||||
prepare: |
|
||||
set -e
|
||||
|
||||
pkg update
|
||||
pkg upgrade -y
|
||||
pkg install -y \
|
||||
audio/opus \
|
||||
audio/pulseaudio \
|
||||
devel/cmake-core \
|
||||
devel/evdev-proto \
|
||||
devel/git \
|
||||
devel/libayatana-appindicator \
|
||||
devel/libevdev \
|
||||
devel/libnotify \
|
||||
devel/llvm${{ env.FREEBSD_CLANG_VERSION }} \
|
||||
devel/ninja \
|
||||
devel/pkgconf \
|
||||
ftp/curl \
|
||||
graphics/libdrm \
|
||||
graphics/wayland \
|
||||
lang/python312 \
|
||||
multimedia/libva \
|
||||
net/miniupnpc \
|
||||
ports-mgmt/pkg \
|
||||
security/openssl \
|
||||
shells/bash \
|
||||
www/npm \
|
||||
x11/libX11 \
|
||||
x11/libxcb \
|
||||
x11/libXfixes \
|
||||
x11/libXrandr \
|
||||
x11/libXtst \
|
||||
x11-servers/xorg-server
|
||||
|
||||
# create symlink for shebang bash compatibility
|
||||
ln -s /usr/local/bin/bash /bin/bash
|
||||
|
||||
# setup python
|
||||
ln -s /usr/local/bin/python3.12 /usr/local/bin/python
|
||||
python -m ensurepip
|
||||
release: ${{ matrix.bsd_release }}
|
||||
run: |
|
||||
set -e
|
||||
# install gcvor
|
||||
python -m pip install gcovr
|
||||
|
||||
# fix git safe.directory issues
|
||||
git config --global --add safe.directory "*"
|
||||
sync: nfs
|
||||
|
||||
- name: Configure
|
||||
env:
|
||||
BRANCH: ${{ github.head_ref || github.ref_name }}
|
||||
BUILD_VERSION: ${{ inputs.release_version }}
|
||||
COMMIT: ${{ inputs.release_commit }}
|
||||
shell: freebsd {0}
|
||||
run: |
|
||||
set -e
|
||||
cd "${GITHUB_WORKSPACE}"
|
||||
|
||||
export BRANCH="${BRANCH}"
|
||||
export BUILD_VERSION="${BUILD_VERSION}"
|
||||
export COMMIT="${COMMIT}"
|
||||
|
||||
cc_path="$(which clang${{ env.FREEBSD_CLANG_VERSION }})"
|
||||
cxx_path="$(which clang++${{ env.FREEBSD_CLANG_VERSION }})"
|
||||
|
||||
export CC="${cc_path}"
|
||||
export CXX="${cxx_path}"
|
||||
|
||||
mkdir -p build
|
||||
cmake \
|
||||
-B build \
|
||||
-G Ninja \
|
||||
-S . \
|
||||
-DBUILD_DOCS=OFF \
|
||||
-DBUILD_WERROR=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr/local \
|
||||
-DSUNSHINE_ASSETS_DIR=share/assets \
|
||||
-DSUNSHINE_EXECUTABLE_PATH=/usr/local/bin/sunshine \
|
||||
-DSUNSHINE_ENABLE_CUDA=OFF \
|
||||
-DSUNSHINE_ENABLE_DRM=OFF \
|
||||
-DSUNSHINE_ENABLE_WAYLAND=ON \
|
||||
-DSUNSHINE_ENABLE_X11=ON \
|
||||
-DSUNSHINE_PUBLISHER_NAME='${{ github.repository_owner }}' \
|
||||
-DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' \
|
||||
-DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support'
|
||||
|
||||
- name: Build
|
||||
shell: freebsd {0}
|
||||
run: |
|
||||
set -e
|
||||
cd "${GITHUB_WORKSPACE}"
|
||||
ninja -C build
|
||||
|
||||
- name: Package
|
||||
shell: freebsd {0}
|
||||
run: |
|
||||
set -e
|
||||
cd "${GITHUB_WORKSPACE}"
|
||||
|
||||
mkdir -p artifacts
|
||||
|
||||
cd build
|
||||
cpack -G FREEBSD
|
||||
|
||||
# move compiled files to artifacts
|
||||
mv ./cpack_artifacts/Sunshine.pkg \
|
||||
../artifacts/Sunshine-FreeBSD-${{ matrix.bsd_release }}-${{ matrix.cmake_processor }}.pkg
|
||||
|
||||
- name: Debug +MANIFEST
|
||||
if: always()
|
||||
shell: bash
|
||||
working-directory: build/cpack_artifacts
|
||||
run: cat ./_CPack_Packages/FreeBSD/FREEBSD/Sunshine/+MANIFEST
|
||||
|
||||
- name: Test
|
||||
id: test
|
||||
shell: freebsd {0}
|
||||
run: |
|
||||
set -e
|
||||
cd "${GITHUB_WORKSPACE}/build/tests"
|
||||
|
||||
export DISPLAY=:1
|
||||
Xvfb ${DISPLAY} -screen 0 1024x768x24 &
|
||||
XVFB_PID=$!
|
||||
|
||||
./test_sunshine --gtest_color=yes --gtest_output=xml:test_results.xml
|
||||
|
||||
kill ${XVFB_PID}
|
||||
|
||||
- name: Generate gcov report
|
||||
id: test_report
|
||||
# any except canceled or skipped
|
||||
if: >-
|
||||
always() &&
|
||||
(steps.test.outcome == 'success' || steps.test.outcome == 'failure')
|
||||
shell: freebsd {0}
|
||||
run: |
|
||||
cd "${GITHUB_WORKSPACE}/build"
|
||||
python -m gcovr . -r ../src \
|
||||
--exclude-noncode-lines \
|
||||
--exclude-throw-branches \
|
||||
--exclude-unreachable-branches \
|
||||
--verbose \
|
||||
--xml-pretty \
|
||||
-o coverage.xml
|
||||
|
||||
- name: Upload coverage artifact
|
||||
if: >-
|
||||
always() &&
|
||||
(steps.test_report.outcome == 'success')
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-FreeBSD-${{ matrix.bsd_release }}-${{ matrix.cmake_processor }}
|
||||
path: |
|
||||
build/coverage.xml
|
||||
build/tests/test_results.xml
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-FreeBSD-${{ matrix.bsd_release }}-${{ matrix.cmake_processor }}
|
||||
path: artifacts/
|
||||
if-no-files-found: error
|
||||
@@ -5,8 +5,6 @@ permissions:
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
@@ -69,6 +67,14 @@ jobs:
|
||||
GH_BOT_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
build-freebsd:
|
||||
name: FreeBSD
|
||||
needs: release-setup
|
||||
uses: ./.github/workflows/ci-freebsd.yml
|
||||
with:
|
||||
release_commit: ${{ needs.release-setup.outputs.release_commit }}
|
||||
release_version: ${{ needs.release-setup.outputs.release_version }}
|
||||
|
||||
build-homebrew:
|
||||
name: Homebrew
|
||||
needs: release-setup
|
||||
@@ -128,6 +134,7 @@ jobs:
|
||||
!cancelled() &&
|
||||
startsWith(github.repository, 'LizardByte/')
|
||||
needs:
|
||||
- build-freebsd
|
||||
- build-linux
|
||||
- build-linux-flatpak
|
||||
- build-homebrew
|
||||
@@ -137,29 +144,53 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: FreeBSD-14.3-amd64
|
||||
coverage: true
|
||||
pr: true
|
||||
- name: FreeBSD-14.3-aarch64
|
||||
coverage: true
|
||||
pr: false
|
||||
- name: Linux-AppImage
|
||||
coverage: true
|
||||
pr: true
|
||||
- name: Homebrew-macos-14
|
||||
coverage: false
|
||||
pr: true
|
||||
- name: Homebrew-macos-15
|
||||
coverage: false
|
||||
pr: true
|
||||
- name: Homebrew-macos-26
|
||||
coverage: false
|
||||
pr: true
|
||||
- name: Homebrew-ubuntu-latest
|
||||
coverage: false
|
||||
pr: true
|
||||
- name: Windows-AMD64
|
||||
coverage: true
|
||||
pr: true
|
||||
steps:
|
||||
- name: Should run
|
||||
id: should_run
|
||||
run: |
|
||||
if [ ${{ github.event_name }} != 'pull_request' ] || [ ${{ matrix.pr }} == 'true' ]; then
|
||||
echo "SHOULD_RUN=true" >> "${GITHUB_OUTPUT}"
|
||||
else
|
||||
echo "SHOULD_RUN=false" >> "${GITHUB_OUTPUT}"
|
||||
fi
|
||||
|
||||
- name: Checkout
|
||||
if: steps.should_run.outputs.SHOULD_RUN == 'true'
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Download coverage artifact
|
||||
if: steps.should_run.outputs.SHOULD_RUN == 'true'
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: coverage-${{ matrix.name }}
|
||||
path: _coverage
|
||||
|
||||
- name: Upload test results
|
||||
if: steps.should_run.outputs.SHOULD_RUN == 'true'
|
||||
uses: codecov/test-results-action@v1
|
||||
with:
|
||||
disable_search: true
|
||||
@@ -170,8 +201,8 @@ jobs:
|
||||
verbose: true
|
||||
|
||||
- name: Upload coverage
|
||||
if: steps.should_run.outputs.SHOULD_RUN == 'true' && matrix.coverage != false
|
||||
uses: codecov/codecov-action@v5
|
||||
if: matrix.coverage != false
|
||||
with:
|
||||
disable_search: true
|
||||
fail_ci_if_error: true
|
||||
@@ -188,6 +219,7 @@ jobs:
|
||||
needs:
|
||||
- release-setup
|
||||
- build-docker
|
||||
- build-freebsd
|
||||
- build-linux
|
||||
- build-linux-flatpak
|
||||
- build-homebrew
|
||||
|
||||
@@ -24,6 +24,10 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
set(FREEBSD ON)
|
||||
endif()
|
||||
|
||||
# set the module path, used for includes
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# linux specific compile definitions
|
||||
|
||||
add_compile_definitions(SUNSHINE_PLATFORM="linux")
|
||||
if(FREEBSD)
|
||||
add_compile_definitions(SUNSHINE_PLATFORM="freebsd")
|
||||
else()
|
||||
add_compile_definitions(SUNSHINE_PLATFORM="linux")
|
||||
endif()
|
||||
|
||||
# AppImage
|
||||
if(${SUNSHINE_BUILD_APPIMAGE})
|
||||
@@ -211,6 +215,9 @@ endif()
|
||||
# These need to be set before adding the inputtino subdirectory in order for them to be picked up
|
||||
set(LIBEVDEV_CUSTOM_INCLUDE_DIR "${EVDEV_INCLUDE_DIR}")
|
||||
set(LIBEVDEV_CUSTOM_LIBRARY "${EVDEV_LIBRARY}")
|
||||
if(FREEBSD)
|
||||
set(USE_UHID OFF)
|
||||
endif()
|
||||
|
||||
add_subdirectory("${CMAKE_SOURCE_DIR}/third-party/inputtino")
|
||||
list(APPEND SUNSHINE_EXTERNAL_LIBRARIES inputtino::libinputtino)
|
||||
|
||||
@@ -7,6 +7,36 @@ include(dependencies/Boost_Sunshine)
|
||||
# submodules
|
||||
# moonlight common library
|
||||
set(ENET_NO_INSTALL ON CACHE BOOL "Don't install any libraries built for enet")
|
||||
|
||||
# Apply FreeBSD patch to ENet if on FreeBSD
|
||||
if(FREEBSD)
|
||||
set(ENET_PATCH_FILE "${CMAKE_SOURCE_DIR}/patches/enet-freebsd-support.patch")
|
||||
set(ENET_SOURCE_FILE "${CMAKE_SOURCE_DIR}/third-party/moonlight-common-c/enet/unix.c")
|
||||
|
||||
# Check if patch needs to be applied
|
||||
execute_process(
|
||||
COMMAND patch -p0 -N --dry-run -i ${ENET_PATCH_FILE}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/third-party/moonlight-common-c/enet
|
||||
RESULT_VARIABLE PATCH_DRY_RUN_RESULT
|
||||
OUTPUT_QUIET
|
||||
ERROR_QUIET
|
||||
)
|
||||
|
||||
# Apply patch if it hasn't been applied yet
|
||||
if(PATCH_DRY_RUN_RESULT EQUAL 0)
|
||||
message(STATUS "Applying FreeBSD patch to ENet")
|
||||
execute_process(
|
||||
COMMAND patch -p0 -N -i ${ENET_PATCH_FILE}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/third-party/moonlight-common-c/enet
|
||||
RESULT_VARIABLE PATCH_RESULT
|
||||
)
|
||||
|
||||
if(NOT PATCH_RESULT EQUAL 0)
|
||||
message(FATAL_ERROR "Failed to apply FreeBSD patch to ENet")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_subdirectory("${CMAKE_SOURCE_DIR}/third-party/moonlight-common-c/enet")
|
||||
|
||||
# web server
|
||||
@@ -30,6 +60,9 @@ include_directories(SYSTEM ${MINIUPNP_INCLUDE_DIRS})
|
||||
if(NOT DEFINED FFMPEG_PREPARED_BINARIES)
|
||||
if(WIN32)
|
||||
set(FFMPEG_PLATFORM_LIBRARIES mfplat ole32 strmiids mfuuid vpl)
|
||||
elseif(FREEBSD)
|
||||
# numa is not available on FreeBSD
|
||||
set(FFMPEG_PLATFORM_LIBRARIES va va-drm va-x11 X11)
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
set(FFMPEG_PLATFORM_LIBRARIES numa va va-drm va-x11 X11)
|
||||
endif()
|
||||
|
||||
@@ -34,6 +34,14 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# RPM specific
|
||||
set(CPACK_RPM_PACKAGE_LICENSE "GPLv3")
|
||||
|
||||
# FreeBSD specific
|
||||
set(CPACK_FREEBSD_PACKAGE_MAINTAINER "${CPACK_PACKAGE_VENDOR}")
|
||||
set(CPACK_FREEBSD_PACKAGE_ORIGIN "misc/${CPACK_PACKAGE_NAME}")
|
||||
set(CPACK_FREEBSD_PACKAGE_LICENSE "GPLv3")
|
||||
|
||||
# Post install
|
||||
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/postinst")
|
||||
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/postinst")
|
||||
@@ -77,6 +85,15 @@ set(CPACK_RPM_PACKAGE_REQUIRES "\
|
||||
openssl >= 3.0.2, \
|
||||
pulseaudio-libs >= 10.0, \
|
||||
which >= 2.21")
|
||||
list(APPEND CPACK_FREEBSD_PACKAGE_DEPS
|
||||
audio/opus
|
||||
ftp/curl
|
||||
devel/libevdev
|
||||
net/avahi
|
||||
x11/libX11
|
||||
net/miniupnpc
|
||||
security/openssl
|
||||
)
|
||||
|
||||
if(NOT BOOST_USE_STATIC)
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "\
|
||||
@@ -91,6 +108,9 @@ if(NOT BOOST_USE_STATIC)
|
||||
boost-locale >= ${Boost_VERSION}, \
|
||||
boost-log >= ${Boost_VERSION}, \
|
||||
boost-program-options >= ${Boost_VERSION}")
|
||||
list(APPEND CPACK_FREEBSD_PACKAGE_DEPS
|
||||
devel/boost-libs
|
||||
)
|
||||
endif()
|
||||
|
||||
# This should automatically figure out dependencies, doesn't work with the current config
|
||||
@@ -141,6 +161,10 @@ if(${SUNSHINE_TRAY} STREQUAL 1)
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES "\
|
||||
${CPACK_RPM_PACKAGE_REQUIRES}, \
|
||||
libappindicator-gtk3 >= 12.10.0")
|
||||
list(APPEND CPACK_FREEBSD_PACKAGE_DEPS
|
||||
devel/libayatana-appindicator
|
||||
devel/libnotify
|
||||
)
|
||||
endif()
|
||||
|
||||
# desktop file
|
||||
|
||||
@@ -26,6 +26,14 @@ and applications to Sunshine.
|
||||
> process is killed.
|
||||
|
||||
@tabs{
|
||||
@tab{FreeBSD | <!-- -->
|
||||
\| Field \| Value \|
|
||||
\|------------------------------\|------------------------------------------------------\|
|
||||
\| Application Name \| @code{}Steam Big Picture@endcode \|
|
||||
\| Command Preporations -> Undo \| @code{}setsid steam steam://close/bigpicture@endcode \|
|
||||
\| Detached Commands \| @code{}setsid steam steam://open/bigpicture@endcode \|
|
||||
\| Image \| @code{}steam.png@endcode \|
|
||||
}
|
||||
@tab{Linux | <!-- -->
|
||||
\| Field \| Value \|
|
||||
\|------------------------------\|------------------------------------------------------\|
|
||||
@@ -97,6 +105,12 @@ and applications to Sunshine.
|
||||
#### URI
|
||||
|
||||
@tabs{
|
||||
@tab{FreeBSD | <!-- -->
|
||||
\| Field \| Value \|
|
||||
\|-------------------\|------------------------------------------------------\|
|
||||
\| Application Name \| @code{}Surviving Mars@endcode \|
|
||||
\| Detached Commands \| @code{}setsid steam steam://rungameid/464920@endcode \|
|
||||
}
|
||||
@tab{Linux | <!-- -->
|
||||
\| Field \| Value \|
|
||||
\|-------------------\|------------------------------------------------------\|
|
||||
@@ -119,6 +133,13 @@ and applications to Sunshine.
|
||||
|
||||
#### Binary (w/ working directory
|
||||
@tabs{
|
||||
@tab{FreeBSD | <!-- -->
|
||||
\| Field \| Value \|
|
||||
\|-------------------\|--------------------------------------------------------------\|
|
||||
\| Application Name \| @code{}Surviving Mars@endcode \|
|
||||
\| Command \| @code{}MarsSteam@endcode \|
|
||||
\| Working Directory \| @code{}~/.steam/steam/SteamApps/common/Survivng Mars@endcode \|
|
||||
}
|
||||
@tab{Linux | <!-- -->
|
||||
\| Field \| Value \|
|
||||
\|-------------------\|--------------------------------------------------------------\|
|
||||
@@ -144,6 +165,12 @@ and applications to Sunshine.
|
||||
|
||||
#### Binary (w/o working directory)
|
||||
@tabs{
|
||||
@tab{FreeBSD | <!-- -->
|
||||
\| Field \| Value \|
|
||||
\|-------------------\|------------------------------------------------------------------------\|
|
||||
\| Application Name \| @code{}Surviving Mars@endcode \|
|
||||
\| Command \| @code{}~/.steam/steam/SteamApps/common/Survivng Mars/MarsSteam@endcode \|
|
||||
}
|
||||
@tab{Linux | <!-- -->
|
||||
\| Field \| Value \|
|
||||
\|-------------------\|------------------------------------------------------------------------\|
|
||||
|
||||
@@ -14,6 +14,39 @@ It is recommended to use one of the following compilers:
|
||||
|
||||
### Dependencies
|
||||
|
||||
#### FreeBSD
|
||||
> [!CAUTION]
|
||||
> Sunshine support for FreeBSD is experimental and may be incomplete or not work as expected
|
||||
|
||||
##### Install dependencies
|
||||
```sh
|
||||
pkg install -y \
|
||||
audio/opus \
|
||||
audio/pulseaudio \
|
||||
devel/cmake \
|
||||
devel/evdev-proto \
|
||||
devel/git \
|
||||
devel/libayatana-appindicator \
|
||||
devel/libevdev \
|
||||
devel/libnotify \
|
||||
devel/ninja \
|
||||
devel/pkgconf \
|
||||
ftp/curl \
|
||||
graphics/libdrm \
|
||||
graphics/wayland \
|
||||
multimedia/libva \
|
||||
net/miniupnpc \
|
||||
ports-mgmt/pkg \
|
||||
security/openssl \
|
||||
shells/bash \
|
||||
www/npm \
|
||||
x11/libX11 \
|
||||
x11/libxcb \
|
||||
x11/libXfixes \
|
||||
x11/libXrandr \
|
||||
x11/libXtst
|
||||
```
|
||||
|
||||
#### Linux
|
||||
Dependencies vary depending on the distribution. You can reference our
|
||||
[linux_build.sh](https://github.com/LizardByte/Sunshine/blob/master/scripts/linux_build.sh) script for a list of
|
||||
@@ -135,6 +168,11 @@ ninja -C build
|
||||
### Package
|
||||
|
||||
@tabs{
|
||||
@tab{FreeBSD | @tabs{
|
||||
@tab{pkg | ```bash
|
||||
cpack -G FREEBSD --config ./build/CPackConfig.cmake
|
||||
```}
|
||||
}}
|
||||
@tab{Linux | @tabs{
|
||||
@tab{deb | ```bash
|
||||
cpack -G DEB --config ./build/CPackConfig.cmake
|
||||
|
||||
+13
-12
@@ -26,6 +26,7 @@ location by modifying the configuration file.
|
||||
| OS | Location |
|
||||
|---------|-------------------------------------------------|
|
||||
| Docker | @code{}/config@endcode |
|
||||
| FreeBSD | @code{}~/.config/sunshine@endcode |
|
||||
| Linux | @code{}~/.config/sunshine@endcode |
|
||||
| macOS | @code{}~/.config/sunshine@endcode |
|
||||
| Windows | @code{}%ProgramFiles%\\Sunshine\\config@endcode |
|
||||
@@ -339,12 +340,12 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
<tr>
|
||||
<td>ds5</td>
|
||||
<td>DualShock 5 controller (PS5)
|
||||
@note{This option applies to Linux only.}</td>
|
||||
@note{This option applies to FreeBSD and Linux only.}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>switch</td>
|
||||
<td>Switch Pro controller
|
||||
@note{This option applies to Linux only.}</td>
|
||||
@note{This option applies to FreeBSD and Linux only.}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>x360</td>
|
||||
@@ -354,7 +355,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
<tr>
|
||||
<td>xone</td>
|
||||
<td>Xbox One controller
|
||||
@note{This option applies to Linux only.}</td>
|
||||
@note{This option applies to FreeBSD and Linux only.}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -735,14 +736,14 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
@tip{To find the name of the audio sink follow these instructions.
|
||||
<br>
|
||||
<br>
|
||||
**Linux + pulseaudio:**
|
||||
**FreeBSD/Linux + pulseaudio:**
|
||||
<br>
|
||||
@code{}
|
||||
pacmd list-sinks | grep "name:"
|
||||
@endcode
|
||||
<br>
|
||||
<br>
|
||||
**Linux + pipewire:**
|
||||
**FreeBSD/Linux + pipewire:**
|
||||
<br>
|
||||
@code{}
|
||||
pactl info | grep Source
|
||||
@@ -776,7 +777,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
<td colspan="2">Sunshine will select the default audio device.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Example (Linux)</td>
|
||||
<td>Example (FreeBSD/Linux)</td>
|
||||
<td colspan="2">@code{}
|
||||
audio_sink = alsa_output.pci-0000_09_00.3.analog-stereo
|
||||
@endcode</td>
|
||||
@@ -883,7 +884,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
@tip{To find the appropriate values follow these instructions.
|
||||
<br>
|
||||
<br>
|
||||
**Linux + VA-API:**
|
||||
**FreeBSD/Linux + VA-API:**
|
||||
<br>
|
||||
Unlike with *amdvce* and *nvenc*, it doesn't matter if video encoding is done on a different GPU.
|
||||
@code{}
|
||||
@@ -913,7 +914,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
<td colspan="2">Sunshine will select the default video card.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Example (Linux)</td>
|
||||
<td>Example (FreeBSD/Linux)</td>
|
||||
<td colspan="2">@code{}
|
||||
adapter_name = /dev/dri/renderD128
|
||||
@endcode</td>
|
||||
@@ -936,7 +937,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
@tip{To find the appropriate values follow these instructions.
|
||||
<br>
|
||||
<br>
|
||||
**Linux:**
|
||||
**FreeBSD/Linux:**
|
||||
<br>
|
||||
During Sunshine startup, you should see the list of detected displays:
|
||||
@code{}
|
||||
@@ -1021,7 +1022,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
<td colspan="2">Sunshine will select the default display.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Example (Linux)</td>
|
||||
<td>Example (FreeBSD/Linux)</td>
|
||||
<td colspan="2">@code{}
|
||||
output_name = 0
|
||||
@endcode</td>
|
||||
@@ -2034,7 +2035,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
<tr>
|
||||
<td>x11</td>
|
||||
<td>Uses XCB. This is the slowest and most CPU intensive so should be avoided if possible.
|
||||
@note{Applies to Linux only.}</td>
|
||||
@note{Applies to FreeBSD and Linux only.}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ddx</td>
|
||||
@@ -2083,7 +2084,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>vaapi</td>
|
||||
<td>Use Linux VA-API (AMD, Intel)</td>
|
||||
<td>Use VA-API (AMD, Intel)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>software</td>
|
||||
|
||||
+42
-1
@@ -8,7 +8,7 @@ and release artifacts may be missing when merging changes on a faster cadence.
|
||||
|
||||
## Binaries
|
||||
|
||||
Binaries of Sunshine are created for each release. They are available for Linux, macOS, and Windows.
|
||||
Binaries of Sunshine are created for each release. They are available for FreeBSD, Linux, macOS, and Windows.
|
||||
Binaries can be found in the [latest release][latest-release].
|
||||
|
||||
> [!NOTE]
|
||||
@@ -28,7 +28,42 @@ and [ghcr.io](https://github.com/orgs/LizardByte/packages?repo_name=sunshine).
|
||||
|
||||
See [Docker](../DOCKER_README.md) for more information.
|
||||
|
||||
### FreeBSD
|
||||
|
||||
#### Install
|
||||
1. Download the appropriate package for your architecture
|
||||
|
||||
| Architecture | Package |
|
||||
|---------------|----------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| amd64/x86_64 | [Sunshine-FreeBSD-14.3-amd64.pkg](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-FreeBSD-14.3-amd64.pkg) |
|
||||
| arm64/aarch64 | [Sunshine-FreeBSD-14.3-aarch64.pkg](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-FreeBSD-14.3-aarch64.pkg) |
|
||||
|
||||
2. Open terminal and run the following command.
|
||||
```sh
|
||||
sudo pkg install ./Sunshine-FreeBSD-14.3-{arch}.pkg
|
||||
```
|
||||
|
||||
#### Additional Requirements
|
||||
|
||||
For gaming on FreeBSD, you'll need to install additional packages:
|
||||
|
||||
**For Steam gaming:**
|
||||
```sh
|
||||
sudo pkg install linux-steam-utils
|
||||
```
|
||||
|
||||
**For NVIDIA GPU support:**
|
||||
```sh
|
||||
sudo pkg install nvidia-driver
|
||||
```
|
||||
|
||||
##### Uninstall
|
||||
```sh
|
||||
sudo pkg delete Sunshine
|
||||
```
|
||||
|
||||
### Linux
|
||||
|
||||
**CUDA Compatibility**
|
||||
|
||||
CUDA is used for NVFBC capture.
|
||||
@@ -522,6 +557,12 @@ All shortcuts start with `Ctrl+Alt+Shift`, just like Moonlight.
|
||||
* The "Desktop" app works the same as any other application except it has no commands. It does not start an application,
|
||||
instead it simply starts a stream. If you removed it and would like to get it back, just add a new application with
|
||||
the name "Desktop" and "desktop.png" as the image path.
|
||||
* The FreeBSD version of Sunshine is missing some features that are present on Linux.
|
||||
The following are known limitations.
|
||||
|
||||
* Only X11 and Wayland capture are supported
|
||||
* DualSense5 emulation is limited due to missing uhid features
|
||||
|
||||
* For the Linux flatpak you must prepend commands with `flatpak-spawn --host`.
|
||||
* If inputs (mouse, keyboard, gamepads...) aren't working after connecting, add the user running sunshine to the `input` group.
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
diff --git a/unix.c b/unix.c
|
||||
index 3d57e9d..c2318ca 100644
|
||||
--- a/unix.c
|
||||
+++ b/unix.c
|
||||
@@ -373,6 +373,14 @@ enet_socket_create (int af, ENetSocketType type)
|
||||
}
|
||||
#endif
|
||||
|
||||
+#if defined(__FreeBSD__) && defined(IP_RECVDSTADDR)
|
||||
+ {
|
||||
+ // Enable IP_RECVDSTADDR for FreeBSD to receive destination address
|
||||
+ int on = 1;
|
||||
+ setsockopt(sock, IPPROTO_IP, IP_RECVDSTADDR, (char *)&on, sizeof(on));
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
#ifdef IP_PKTINFO
|
||||
{
|
||||
// We turn this on for all sockets because it may be required for IPv4
|
||||
@@ -617,6 +625,21 @@ enet_socket_send (ENetSocket socket,
|
||||
// from this peer to ensure it correctly recognizes our responses as
|
||||
// coming from the expected host.
|
||||
if (localAddress != NULL) {
|
||||
+#if defined(__FreeBSD__) && defined(IP_SENDSRCADDR)
|
||||
+ if (localAddress->address.ss_family == AF_INET) {
|
||||
+ struct in_addr srcAddr = ((struct sockaddr_in*)&localAddress->address)->sin_addr;
|
||||
+
|
||||
+ msgHdr.msg_control = controlBufData;
|
||||
+ msgHdr.msg_controllen = CMSG_SPACE(sizeof(srcAddr));
|
||||
+
|
||||
+ struct cmsghdr *chdr = CMSG_FIRSTHDR(&msgHdr);
|
||||
+ chdr->cmsg_level = IPPROTO_IP;
|
||||
+ chdr->cmsg_type = IP_SENDSRCADDR;
|
||||
+ chdr->cmsg_len = CMSG_LEN(sizeof(srcAddr));
|
||||
+ memcpy(CMSG_DATA(chdr), &srcAddr, sizeof(srcAddr));
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
#ifdef IP_PKTINFO
|
||||
if (localAddress->address.ss_family == AF_INET) {
|
||||
struct in_pktinfo pktInfo;
|
||||
@@ -744,6 +767,21 @@ enet_socket_receive (ENetSocket socket,
|
||||
// to ensure we respond from the correct address/interface.
|
||||
if (localAddress != NULL) {
|
||||
for (struct cmsghdr *chdr = CMSG_FIRSTHDR(&msgHdr); chdr != NULL; chdr = CMSG_NXTHDR(&msgHdr, chdr)) {
|
||||
+#if defined(__FreeBSD__) && defined(IP_RECVDSTADDR)
|
||||
+ if (chdr->cmsg_level == IPPROTO_IP && chdr->cmsg_type == IP_RECVDSTADDR) {
|
||||
+ struct sockaddr_in *localAddr = (struct sockaddr_in*)&localAddress->address;
|
||||
+
|
||||
+ localAddr->sin_family = AF_INET;
|
||||
+ localAddr->sin_addr = *(struct in_addr*)CMSG_DATA(chdr);
|
||||
+ // FreeBSD doesn't populate sin_port in RECVDSTADDR, but we don't need it
|
||||
+ // since we only use the address part for routing decisions
|
||||
+ localAddr->sin_port = 0;
|
||||
+
|
||||
+ localAddress->addressLength = sizeof(*localAddr);
|
||||
+ break;
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
#ifdef IP_PKTINFO
|
||||
if (chdr->cmsg_level == IPPROTO_IP && chdr->cmsg_type == IP_PKTINFO) {
|
||||
struct sockaddr_in *localAddr = (struct sockaddr_in*)&localAddress->address;
|
||||
@@ -35,6 +35,21 @@
|
||||
#include "src/platform/common.h"
|
||||
#include "vaapi.h"
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
// Define constants that are missing in FreeBSD
|
||||
#ifndef SOL_IP // socket level for IPv4
|
||||
#define SOL_IP IPPROTO_IP
|
||||
#endif
|
||||
#ifndef SOL_IPV6 // socket level for IPv6
|
||||
#define SOL_IPV6 IPPROTO_IPV6
|
||||
#endif
|
||||
#ifndef SO_PRIORITY // socket option for priority, disabled for FreeBSD
|
||||
#define SO_PRIORITY -1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define SUNSHINE_GNUC_EXTENSION __extension__
|
||||
#else
|
||||
@@ -377,7 +392,11 @@ namespace platf {
|
||||
}
|
||||
|
||||
union {
|
||||
#ifdef __FreeBSD__
|
||||
char buf[CMSG_SPACE(sizeof(uint16_t)) + std::max(CMSG_SPACE(sizeof(struct in_addr)), CMSG_SPACE(sizeof(struct in6_pktinfo)))];
|
||||
#else
|
||||
char buf[CMSG_SPACE(sizeof(uint16_t)) + std::max(CMSG_SPACE(sizeof(struct in_pktinfo)), CMSG_SPACE(sizeof(struct in6_pktinfo)))];
|
||||
#endif
|
||||
struct cmsghdr alignment;
|
||||
} cmbuf = {}; // Must be zeroed for CMSG_NXTHDR()
|
||||
|
||||
@@ -403,6 +422,18 @@ namespace platf {
|
||||
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
||||
memcpy(CMSG_DATA(pktinfo_cm), &pktInfo, sizeof(pktInfo));
|
||||
} else {
|
||||
#ifdef __FreeBSD__
|
||||
// FreeBSD uses IP_SENDSRCADDR instead of IP_PKTINFO
|
||||
struct sockaddr_in saddr_v4 = to_sockaddr(send_info.source_address.to_v4(), 0);
|
||||
struct in_addr srcAddr = saddr_v4.sin_addr;
|
||||
|
||||
cmbuflen += CMSG_SPACE(sizeof(srcAddr));
|
||||
|
||||
pktinfo_cm->cmsg_level = IPPROTO_IP;
|
||||
pktinfo_cm->cmsg_type = IP_SENDSRCADDR;
|
||||
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(srcAddr));
|
||||
memcpy(CMSG_DATA(pktinfo_cm), &srcAddr, sizeof(srcAddr));
|
||||
#else
|
||||
struct in_pktinfo pktInfo;
|
||||
|
||||
struct sockaddr_in saddr_v4 = to_sockaddr(send_info.source_address.to_v4(), 0);
|
||||
@@ -415,6 +446,7 @@ namespace platf {
|
||||
pktinfo_cm->cmsg_type = IP_PKTINFO;
|
||||
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
||||
memcpy(CMSG_DATA(pktinfo_cm), &pktInfo, sizeof(pktInfo));
|
||||
#endif
|
||||
}
|
||||
|
||||
auto const max_iovs_per_msg = send_info.payload_buffers.size() + (send_info.headers ? 1 : 0);
|
||||
@@ -507,8 +539,8 @@ namespace platf {
|
||||
|
||||
{
|
||||
// If GSO is not supported, use sendmmsg() instead.
|
||||
struct mmsghdr msgs[send_info.block_count];
|
||||
struct iovec iovs[send_info.block_count * (send_info.headers ? 2 : 1)];
|
||||
std::vector<struct mmsghdr> msgs(send_info.block_count);
|
||||
std::vector<struct iovec> iovs(send_info.block_count * (send_info.headers ? 2 : 1));
|
||||
int iov_idx = 0;
|
||||
for (size_t i = 0; i < send_info.block_count; i++) {
|
||||
msgs[i].msg_len = 0;
|
||||
@@ -584,7 +616,11 @@ namespace platf {
|
||||
}
|
||||
|
||||
union {
|
||||
#ifdef __FreeBSD__
|
||||
char buf[std::max(CMSG_SPACE(sizeof(struct in_addr)), CMSG_SPACE(sizeof(struct in6_pktinfo)))];
|
||||
#else
|
||||
char buf[std::max(CMSG_SPACE(sizeof(struct in_pktinfo)), CMSG_SPACE(sizeof(struct in6_pktinfo)))];
|
||||
#endif
|
||||
struct cmsghdr alignment;
|
||||
} cmbuf;
|
||||
|
||||
@@ -608,6 +644,18 @@ namespace platf {
|
||||
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
||||
memcpy(CMSG_DATA(pktinfo_cm), &pktInfo, sizeof(pktInfo));
|
||||
} else {
|
||||
#ifdef __FreeBSD__
|
||||
// FreeBSD uses IP_SENDSRCADDR instead of IP_PKTINFO
|
||||
struct sockaddr_in saddr_v4 = to_sockaddr(send_info.source_address.to_v4(), 0);
|
||||
struct in_addr srcAddr = saddr_v4.sin_addr;
|
||||
|
||||
cmbuflen += CMSG_SPACE(sizeof(srcAddr));
|
||||
|
||||
pktinfo_cm->cmsg_level = IPPROTO_IP;
|
||||
pktinfo_cm->cmsg_type = IP_SENDSRCADDR;
|
||||
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(srcAddr));
|
||||
memcpy(CMSG_DATA(pktinfo_cm), &srcAddr, sizeof(srcAddr));
|
||||
#else
|
||||
struct in_pktinfo pktInfo;
|
||||
|
||||
struct sockaddr_in saddr_v4 = to_sockaddr(send_info.source_address.to_v4(), 0);
|
||||
@@ -620,6 +668,7 @@ namespace platf {
|
||||
pktinfo_cm->cmsg_type = IP_PKTINFO;
|
||||
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
||||
memcpy(CMSG_DATA(pktinfo_cm), &pktInfo, sizeof(pktInfo));
|
||||
#endif
|
||||
}
|
||||
|
||||
struct iovec iovs[2];
|
||||
@@ -753,6 +802,10 @@ namespace platf {
|
||||
// reset SO_PRIORITY back to 0.
|
||||
//
|
||||
// 6 is the highest priority that can be used without SYS_CAP_ADMIN.
|
||||
#ifdef __FreeBSD__
|
||||
// FreeBSD doesn't support SO_PRIORITY, so we skip this
|
||||
BOOST_LOG(debug) << "SO_PRIORITY not supported on FreeBSD, skipping traffic priority setting";
|
||||
#else
|
||||
int priority = data_type == qos_data_type_e::audio ? 6 : 5;
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) == 0) {
|
||||
// Reset SO_PRIORITY to 0 when QoS is disabled
|
||||
@@ -760,6 +813,7 @@ namespace platf {
|
||||
} else {
|
||||
BOOST_LOG(error) << "Failed to set SO_PRIORITY: "sv << errno;
|
||||
}
|
||||
#endif
|
||||
|
||||
return std::make_unique<qos_t>(sockfd, reset_options);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
#include <future>
|
||||
#include <queue>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
// lib includes
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
#include <openssl/err.h>
|
||||
@@ -520,6 +525,9 @@ namespace stream {
|
||||
// for other communications to the client. This is necessary to ensure
|
||||
// proper routing on multi-homed hosts.
|
||||
auto local_address = platf::from_sockaddr((sockaddr *) &peer->localAddress.address);
|
||||
if (local_address.empty()) {
|
||||
BOOST_LOG(warning) << "Couldn't get local address for control connection"sv;
|
||||
}
|
||||
session_p->localAddress = boost::asio::ip::make_address(local_address);
|
||||
|
||||
BOOST_LOG(debug) << "Control local address ["sv << local_address << ']';
|
||||
@@ -1709,6 +1717,23 @@ namespace stream {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
// Enable IP_RECVDSTADDR for FreeBSD to receive destination address for IPv4
|
||||
{
|
||||
int on = 1;
|
||||
if (setsockopt(ctx.video_sock.native_handle(), IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)) < 0) {
|
||||
BOOST_LOG(warning) << "Failed to set IP_RECVDSTADDR on video socket";
|
||||
}
|
||||
}
|
||||
// Enable IPV6_RECVPKTINFO for IPv6
|
||||
if (address_family == net::af_e::BOTH) {
|
||||
int on = 1;
|
||||
if (setsockopt(ctx.video_sock.native_handle(), IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)) < 0) {
|
||||
BOOST_LOG(warning) << "Failed to set IPV6_RECVPKTINFO on video socket";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set video socket send buffer size (SO_SENDBUF) to 1MB
|
||||
try {
|
||||
ctx.video_sock.set_option(boost::asio::socket_base::send_buffer_size(1024 * 1024));
|
||||
@@ -1730,6 +1755,23 @@ namespace stream {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
// Enable IP_RECVDSTADDR for FreeBSD to receive destination address for IPv4
|
||||
{
|
||||
int on = 1;
|
||||
if (setsockopt(ctx.audio_sock.native_handle(), IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)) < 0) {
|
||||
BOOST_LOG(warning) << "Failed to set IP_RECVDSTADDR on audio socket";
|
||||
}
|
||||
}
|
||||
// Enable IPV6_RECVPKTINFO for IPv6
|
||||
if (address_family == net::af_e::BOTH) {
|
||||
int on = 1;
|
||||
if (setsockopt(ctx.audio_sock.native_handle(), IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)) < 0) {
|
||||
BOOST_LOG(warning) << "Failed to set IPV6_RECVPKTINFO on audio socket";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ctx.audio_sock.bind(udp::endpoint(protocol, audio_port), ec);
|
||||
if (ec) {
|
||||
BOOST_LOG(fatal) << "Couldn't bind Audio server to port ["sv << audio_port << "]: "sv << ec.message();
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
#define TRAY_ICON_PLAYING WEB_DIR "images/sunshine-playing.ico"
|
||||
#define TRAY_ICON_PAUSING WEB_DIR "images/sunshine-pausing.ico"
|
||||
#define TRAY_ICON_LOCKED WEB_DIR "images/sunshine-locked.ico"
|
||||
#elif defined(__linux__) || defined(linux) || defined(__linux)
|
||||
#elif defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__)
|
||||
#define TRAY_ICON SUNSHINE_TRAY_PREFIX "-tray"
|
||||
#define TRAY_ICON_PLAYING SUNSHINE_TRAY_PREFIX "-playing"
|
||||
#define TRAY_ICON_PAUSING SUNSHINE_TRAY_PREFIX "-pausing"
|
||||
|
||||
+2
-2
@@ -897,7 +897,7 @@ namespace video {
|
||||
H264_ONLY | PARALLEL_ENCODING | ALWAYS_REPROBE | YUV444_SUPPORT
|
||||
};
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__)
|
||||
encoder_t vaapi {
|
||||
"vaapi"sv,
|
||||
std::make_unique<encoder_platform_formats_avcodec>(
|
||||
@@ -1032,7 +1032,7 @@ namespace video {
|
||||
&quicksync,
|
||||
&amdvce,
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__)
|
||||
&vaapi,
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
|
||||
+1
-1
@@ -221,7 +221,7 @@ namespace video {
|
||||
extern encoder_t quicksync;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__)
|
||||
extern encoder_t vaapi;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -12,6 +12,10 @@ const props = defineProps({
|
||||
<slot name="windows"></slot>
|
||||
</template>
|
||||
|
||||
<template v-if="$slots.freebsd && platform === 'freebsd'">
|
||||
<slot name="freebsd"></slot>
|
||||
</template>
|
||||
|
||||
<template v-if="$slots.linux && platform === 'linux'">
|
||||
<slot name="linux"></slot>
|
||||
</template>
|
||||
|
||||
@@ -331,7 +331,7 @@
|
||||
<div class="form-text" v-if="platform === 'windows'"><b>{{ $t('apps.env_qres_example') }}</b>
|
||||
<pre>cmd /C <{{ $t('apps.env_qres_path') }}>\QRes.exe /X:%SUNSHINE_CLIENT_WIDTH% /Y:%SUNSHINE_CLIENT_HEIGHT% /R:%SUNSHINE_CLIENT_FPS%</pre>
|
||||
</div>
|
||||
<div class="form-text" v-else-if="platform === 'linux'"><b>{{ $t('apps.env_xrandr_example') }}</b>
|
||||
<div class="form-text" v-else-if="platform === 'freebsd' || platform === 'linux'"><b>{{ $t('apps.env_xrandr_example') }}</b>
|
||||
<pre>sh -c "xrandr --output HDMI-1 --mode \"${SUNSHINE_CLIENT_WIDTH}x${SUNSHINE_CLIENT_HEIGHT}\" --rate ${SUNSHINE_CLIENT_FPS}"</pre>
|
||||
</div>
|
||||
<div class="form-text" v-else-if="platform === 'macos'"><b>{{ $t('apps.env_displayplacer_example') }}</b>
|
||||
@@ -442,8 +442,8 @@
|
||||
if (resp) {
|
||||
fetch("./api/apps/" + id, {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
}).then((r) => {
|
||||
if (r.status === 200) document.location.reload();
|
||||
|
||||
@@ -305,7 +305,7 @@
|
||||
return el.id !== "vt" && el.id !== "vaapi";
|
||||
});
|
||||
}
|
||||
if (this.platform === "linux") {
|
||||
if (this.platform === "freebsd" || this.platform === "linux") {
|
||||
this.tabs = this.tabs.filter((el) => {
|
||||
return el.id !== "amd" && el.id !== "qsv" && el.id !== "vt";
|
||||
});
|
||||
|
||||
@@ -64,6 +64,10 @@ const config = ref(props.config)
|
||||
<select id="capture" class="form-select" v-model="config.capture">
|
||||
<option value="">{{ $t('_common.autodetect') }}</option>
|
||||
<PlatformLayout :platform="platform">
|
||||
<template #freebsd>
|
||||
<option value="wlr">wlroots</option>
|
||||
<option value="x11">X11</option>
|
||||
</template>
|
||||
<template #linux>
|
||||
<option value="nvfbc">NvFBC</option>
|
||||
<option value="wlr">wlroots</option>
|
||||
@@ -90,6 +94,9 @@ const config = ref(props.config)
|
||||
<option value="quicksync">Intel QuickSync</option>
|
||||
<option value="amdvce">AMD AMF/VCE</option>
|
||||
</template>
|
||||
<template #freebsd>
|
||||
<option value="vaapi">VA-API</option>
|
||||
</template>
|
||||
<template #linux>
|
||||
<option value="nvenc">NVIDIA NVENC</option>
|
||||
<option value="vaapi">VA-API</option>
|
||||
|
||||
@@ -30,6 +30,10 @@ const config = ref(props.config)
|
||||
<template #windows>
|
||||
<pre>tools\audio-info.exe</pre>
|
||||
</template>
|
||||
<template #freebsd>
|
||||
<pre>pacmd list-sinks | grep "name:"</pre>
|
||||
<pre>pactl info | grep Source</pre>
|
||||
</template>
|
||||
<template #linux>
|
||||
<pre>pacmd list-sinks | grep "name:"</pre>
|
||||
<pre>pactl info | grep Source</pre>
|
||||
|
||||
@@ -28,12 +28,18 @@ const config = ref(props.config)
|
||||
<option value="auto">{{ $t('_common.auto') }}</option>
|
||||
|
||||
<PlatformLayout :platform="platform">
|
||||
<template #freebsd>
|
||||
<option value="ds5">{{ $t("config.gamepad_ds5") }}</option>
|
||||
<option value="switch">{{ $t("config.gamepad_switch") }}</option>
|
||||
<option value="xone">{{ $t("config.gamepad_xone") }}</option>
|
||||
</template>
|
||||
|
||||
<template #linux>
|
||||
<option value="ds5">{{ $t("config.gamepad_ds5") }}</option>
|
||||
<option value="switch">{{ $t("config.gamepad_switch") }}</option>
|
||||
<option value="xone">{{ $t("config.gamepad_xone") }}</option>
|
||||
</template>
|
||||
|
||||
|
||||
<template #windows>
|
||||
<option value="ds4">{{ $t('config.gamepad_ds4') }}</option>
|
||||
<option value="x360">{{ $t('config.gamepad_x360') }}</option>
|
||||
|
||||
@@ -23,6 +23,16 @@ const config = ref(props.config)
|
||||
{{ $t('config.adapter_name_desc_windows') }}<br>
|
||||
<pre>tools\dxgi-info.exe</pre>
|
||||
</template>
|
||||
<template #freebsd>
|
||||
{{ $t('config.adapter_name_desc_linux_1') }}<br>
|
||||
<pre>ls /dev/dri/renderD* # {{ $t('config.adapter_name_desc_linux_2') }}</pre>
|
||||
<pre>
|
||||
vainfo --display drm --device /dev/dri/renderD129 | \
|
||||
grep -E "((VAProfileH264High|VAProfileHEVCMain|VAProfileHEVCMain10).*VAEntrypointEncSlice)|Driver version"
|
||||
</pre>
|
||||
{{ $t('config.adapter_name_desc_linux_3') }}<br>
|
||||
<i>VAProfileH264High : VAEntrypointEncSlice</i>
|
||||
</template>
|
||||
<template #linux>
|
||||
{{ $t('config.adapter_name_desc_linux_1') }}<br>
|
||||
<pre>ls /dev/dri/renderD* # {{ $t('config.adapter_name_desc_linux_2') }}</pre>
|
||||
|
||||
@@ -241,6 +241,8 @@ function addRemappingEntry() {
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #freebsd>
|
||||
</template>
|
||||
<template #linux>
|
||||
</template>
|
||||
<template #macos>
|
||||
|
||||
@@ -30,6 +30,16 @@ const outputNamePlaceholder = (props.platform === 'windows') ? '{de9bb7e2-186e-5
|
||||
<b> }</b>
|
||||
</pre>
|
||||
</template>
|
||||
<template #freebsd>
|
||||
<pre style="white-space: pre-line;">
|
||||
Info: Detecting displays
|
||||
Info: Detected display: DVI-D-0 (id: 0) connected: false
|
||||
Info: Detected display: HDMI-0 (id: 1) connected: true
|
||||
Info: Detected display: DP-0 (id: 2) connected: true
|
||||
Info: Detected display: DP-1 (id: 3) connected: false
|
||||
Info: Detected display: DVI-D-1 (id: 4) connected: false
|
||||
</pre>
|
||||
</template>
|
||||
<template #linux>
|
||||
<pre style="white-space: pre-line;">
|
||||
Info: Detecting displays
|
||||
|
||||
@@ -126,6 +126,12 @@ namespace test_utils {
|
||||
#define IS_MACOS false
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#define IS_FREEBSD true
|
||||
#else
|
||||
#define IS_FREEBSD false
|
||||
#endif
|
||||
|
||||
struct PlatformTestSuite: testing::Test {
|
||||
static void SetUpTestSuite() {
|
||||
ASSERT_FALSE(platf_deinit);
|
||||
|
||||
@@ -13,7 +13,7 @@ struct MouseHIDTest: PlatformTestSuite, testing::WithParamInterface<util::point_
|
||||
// the alternative `platf::abs_mouse` method seem to work better during tests,
|
||||
// but I'm not sure about real work
|
||||
GTEST_SKIP() << "TODO Windows";
|
||||
#elif __linux__
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
// TODO: Inputtino waiting https://github.com/games-on-whales/inputtino/issues/6 is resolved.
|
||||
GTEST_SKIP() << "TODO Inputtino";
|
||||
#endif
|
||||
@@ -88,7 +88,7 @@ TEST_P(MouseHIDTest, AbsMoveInputTest) {
|
||||
65535,
|
||||
65535
|
||||
};
|
||||
#elif __linux__
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
platf::touch_port_t abs_port {
|
||||
0,
|
||||
0,
|
||||
|
||||
@@ -32,7 +32,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
&video::amdvce,
|
||||
&video::quicksync,
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
&video::vaapi,
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
|
||||
Reference in New Issue
Block a user