Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .github/workflows/ci-freebsd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,7 @@ jobs:
release: ${{ matrix.bsd_release }}
run: |
set -e
uv sync --locked --only-group glad --python "/usr/local/bin/python${PYTHON_VERSION}" \
--no-python-downloads --no-install-project
uv sync --project third-party/lizardbyte-common --locked --only-group test-c \
--python "/usr/local/bin/python${PYTHON_VERSION}" \
uv sync --locked --group glad --python "/usr/local/bin/python${PYTHON_VERSION}" \
--no-python-downloads --no-install-project

# fix git safe.directory issues
Expand Down Expand Up @@ -259,7 +256,7 @@ jobs:
shell: freebsd {0}
run: |
cd "${GITHUB_WORKSPACE}/build"
uv run --project ../third-party/lizardbyte-common --locked --no-sync gcovr . -r ../src \
uv run --project .. --locked --no-sync gcovr . -r ../src \
--exclude-noncode-lines \
--exclude-throw-branches \
--exclude-unreachable-branches \
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ jobs:

- name: Sync Python tools
run: |
uv sync --project third-party/lizardbyte-common --locked --only-group test-c \
uv sync --locked \
--python "${PYTHON_VERSION}" \
--no-python-downloads --no-install-project

Expand All @@ -197,7 +197,7 @@ jobs:
(steps.test.outcome == 'success' || steps.test.outcome == 'failure')
working-directory: build
run: |
uv run --project ../third-party/lizardbyte-common --locked --no-sync gcovr \
uv run --project .. --locked --no-sync gcovr \
--gcov-executable "gcov-${GCC_VERSION}" . -r ../src \
--exclude-noncode-lines \
--exclude-throw-branches \
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ jobs:

- name: Sync Python tools
run: |
uv sync --project third-party/lizardbyte-common --locked --only-group test-c \
uv sync --locked \
--python "${PYTHON_VERSION}" \
--no-python-downloads --no-install-project

Expand Down Expand Up @@ -184,7 +184,7 @@ jobs:
(steps.test.outcome == 'success' || steps.test.outcome == 'failure')
working-directory: build
run: |
uv run --project ../third-party/lizardbyte-common --locked --no-sync gcovr . -r ../src \
uv run --project .. --locked --no-sync gcovr . -r ../src \
--exclude-noncode-lines \
--exclude-throw-branches \
--exclude-unreachable-branches \
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ jobs:
MSYS2_PATH_TYPE: inherit
UV_PYTHON: ${{ steps.setup-python.outputs.python-path }}
run: |
uv sync --project third-party/lizardbyte-common --locked --only-group test-c \
uv sync --locked \
--no-python-downloads \
--no-install-project

Expand Down Expand Up @@ -369,7 +369,7 @@ jobs:
env:
MSYS2_PATH_TYPE: inherit
run: |
uv run --project ../third-party/lizardbyte-common --locked --no-sync gcovr . -r ../src \
uv run --project .. --locked --no-sync gcovr . -r ../src \
--exclude-noncode-lines \
--exclude-throw-branches \
--exclude-unreachable-branches \
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ jobs:
COPR_BETA_WEBHOOK_TOKEN: ${{ secrets.COPR_BETA_WEBHOOK_TOKEN }}
COPR_STABLE_WEBHOOK_TOKEN: ${{ secrets.COPR_STABLE_WEBHOOK_TOKEN }}
COPR_CLI_CONFIG: ${{ secrets.COPR_CLI_CONFIG }}
VIRUSTOTAL_API_KEY: ${{ secrets.VIRUSTOTAL_API_KEY }}

build-linux-flatpak:
name: Linux Flatpak
Expand Down
7 changes: 7 additions & 0 deletions .run/docs.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="docs" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="&quot;file:\\$CMakeCurrentBuildDir$\build\html\index.html&quot;" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Sunshine" TARGET_NAME="docs" CONFIG_NAME="Release" RUN_PATH="$PROJECT_DIR$/../../../../../Windows/explorer.exe">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
</component>
25 changes: 24 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,29 @@ the build directory.

The project uses gtest as a test framework.

When adding localization do not update any language other than `en`. This also means to exclude en-US or other variants.

Always add or update doxygen documentation.

The project requires that everything be documented in doxygen or the build will fail.

Primary doxygen comments should be done like so:

```cpp
/**
* @brief Describe the function, structure, etc.
*
* @param my_param Describe the parameter.
* @return Describe the return.
*/
```

Inline doxygen comments should use `///< ...` instead of `/**< ... */`.

Always follow the style guidelines defined in .clang-format for c/c++ code.

When adding localization do not update any language other than `en`. This also means to exclude en-US or other variants.
Do not ever create issues or pull requests.
If asked to create an issue or pull request, do so in their fork instead of the LizardByte GitHub organization.
Never create an issue or pull request in the LizardByte GitHub organization.

Add or update tests for new or modified methods and code. Target 100% coverage on changed code.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<a href="https://github.com/LizardByte/Sunshine/actions/workflows/localize.yml?query=branch%3Amaster"><img src="https://img.shields.io/github/actions/workflow/status/lizardbyte/sunshine/localize.yml.svg?branch=master&label=localize%20build&logo=github&style=for-the-badge" alt="GitHub Workflow Status (localize)"></a>
<a href="https://docs.lizardbyte.dev/projects/sunshine"><img src="https://img.shields.io/readthedocs/sunshinestream.svg?label=Docs&style=for-the-badge&logo=readthedocs" alt="Read the Docs"></a>
<a href="https://codecov.io/gh/LizardByte/Sunshine"><img src="https://img.shields.io/codecov/c/gh/LizardByte/Sunshine?token=SMGXQ5NVMJ&style=for-the-badge&logo=codecov&label=codecov" alt="Codecov"></a>
<a href="https://sonarcloud.io/project/overview?id=LizardByte_Sunshine"><img src="https://img.shields.io/sonar/quality_gate/LizardByte_Sunshine?server=https%3A%2F%2Fsonarcloud.io&style=for-the-badge&logo=sonarqubecloud&label=sonarcloud" alt="SonarCloud"></a>
</div>

## ℹ️ About
Expand Down
3 changes: 0 additions & 3 deletions docs/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ IMAGE_PATH = ../docs/images
PREDEFINED += SUNSHINE_BUILD_WAYLAND
PREDEFINED += SUNSHINE_TRAY=1

# TODO: Enable this when we have complete documentation
WARN_IF_UNDOCUMENTED = NO

# files and directories to process
USE_MDFILE_AS_MAINPAGE = ../README.md
INPUT = ../README.md \
Expand Down
20 changes: 10 additions & 10 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,25 +128,23 @@ any of the following paths are modified.
```

When testing locally, it may be desirable to manually extract, initialize, update, and compile strings. Python and
uv are required for this, along with the Python dependencies in the `third-party/lizardbyte-common/pyproject.toml`
file. You can install these with the following command.
uv are required for this, along with the Python dependencies in the Sunshine `pyproject.toml`. From the repository
root, install these with the following command.

```bash
uv sync --project third-party/lizardbyte-common --locked --only-group locale --no-install-project
uv sync --locked
```

Additionally, [xgettext](https://www.gnu.org/software/gettext) must be installed.

* Extract, initialize, and update
```bash
uv run --project third-party/lizardbyte-common --locked --no-sync \
python third-party/lizardbyte-common/scripts/localize.py --root-dir . --extract --init --update
uv run --locked --no-sync lb-localize --root-dir . --extract --init --update
```

* Compile
```bash
uv run --project third-party/lizardbyte-common --locked --no-sync \
python third-party/lizardbyte-common/scripts/localize.py --root-dir . --compile
uv run --locked --no-sync lb-localize --root-dir . --compile
```

> [!IMPORTANT]
Expand All @@ -160,10 +158,12 @@ Additionally, [xgettext](https://www.gnu.org/software/gettext) must be installed
#### Clang Format
Source code is tested against the `.clang-format` file for linting errors.

To apply clang-format locally (will modify files):
From the repository root, apply clang-format locally with the installed lizardbyte-common script. This will modify
files in place.

```bash
uv run --project third-party/lizardbyte-common --locked --only-group lint-c \
python third-party/lizardbyte-common/scripts/update_clang_format.py
uv sync --locked
uv run --locked --no-sync lb-update-clang-format
```

#### Unit Testing
Expand Down
2 changes: 1 addition & 1 deletion packaging/sunshine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def configure_static_boost(args)
either install icu4c or use brew install sunshine --with-static-boost instead
EOS
end
ENV.append "CXXFLAGS", "-I#{Formula["icu4c"].opt_include}"
ENV.append "CXXFLAGS", "-I#{formula_opt_include("icu4c")}"
icu4c_lib_path = formula_opt_lib("icu4c").to_s
ENV.append "LDFLAGS", "-L#{icu4c_lib_path}"
ENV["LIBRARY_PATH"] = icu4c_lib_path
Expand Down
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ authors = [
{name = "LizardByte", email = "lizardbyte@users.noreply.github.com"}
]

dependencies = []
dependencies = [
"lizardbyte-common[c]",
]

[dependency-groups]
# glad2 declares Jinja2>=2.7,<4.0 as a dependency, so installing it pulls in jinja2 transitively.
Expand Down Expand Up @@ -41,3 +43,4 @@ py-modules = []
flatpak_node_generator = { path = "packaging/linux/flatpak/deps/flatpak-builder-tools/node" }
flatpak_pip_generator = { path = "packaging/linux/flatpak/deps/flatpak-builder-tools/pip" }
glad2 = { path = "third-party/glad" }
lizardbyte-common = { path = "third-party/lizardbyte-common" }
31 changes: 30 additions & 1 deletion src/audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,35 @@

namespace audio {
using namespace std::literals;
/**
* @brief Owning pointer for an Opus multistream encoder.
*/
using opus_t = util::safe_ptr<OpusMSEncoder, opus_multistream_encoder_destroy>;
/**
* @brief Shared queue carrying captured PCM sample buffers to the encoder thread.
*/
using sample_queue_t = std::shared_ptr<safe::queue_t<std::vector<float>>>;

static int start_audio_control(audio_ctx_t &ctx);
static void stop_audio_control(audio_ctx_t &);
static void apply_surround_params(opus_stream_config_t &stream, const stream_params_t &params);

/**
* @brief Select the Opus stream configuration for a channel count and quality tier.
*
* @param channels Number of audio channels in the stream.
* @param quality Whether the high-quality Opus layout should be selected.
* @return Index into `stream_configs` for the requested layout.
*/
int map_stream(int channels, bool quality);

constexpr auto SAMPLE_RATE = 48000;
constexpr auto SAMPLE_RATE = 48000; ///< Audio sample rate in hertz required by Opus.

// NOTE: If you adjust the bitrates listed here, make sure to update the
// corresponding bitrate adjustment logic in rtsp_stream::cmd_announce()
/**
* @brief Opus stream layouts and bitrates advertised to clients.
*/
opus_stream_config_t stream_configs[MAX_STREAM_CONFIG] {
{
SAMPLE_RATE,
Expand Down Expand Up @@ -83,6 +99,13 @@ namespace audio {
},
};

/**
* @brief Encode captured PCM samples into Opus packets on the audio worker thread.
*
* @param samples Queue of captured PCM sample buffers to encode.
* @param config Audio stream settings negotiated with the client.
* @param channel_data Platform-specific audio capture context passed to packet metadata.
*/
void encodeThread(sample_queue_t samples, config_t config, void *channel_data) {
auto packets = mail::man->queue<packet_t>(mail::audio_packets);
auto stream = stream_configs[map_stream(config.channels, config.flags[config_t::HIGH_QUALITY])];
Expand Down Expand Up @@ -128,6 +151,9 @@ namespace audio {
}
}

/**
* @brief Run the capture loop for this backend.
*/
void capture(safe::mail_t mail, config_t config, void *channel_data) {
auto shutdown_event = mail->event<bool>(mail::shutdown);
if (!config::audio.stream) {
Expand Down Expand Up @@ -265,6 +291,9 @@ namespace audio {
return ctx.control->is_sink_available(sink);
}

/**
* @brief Select the Opus stream configuration for a channel count and quality tier.
*/
int map_stream(int channels, bool quality) {
int shift = quality ? 1 : 0;
switch (channels) {
Expand Down
Loading
Loading