chore(licensing): LGPL FFmpeg swap, third-party notices, attribution hygiene
The MIT OR Apache-2.0 SOURCE license is clean (audit found no copied copyleft); the
gaps were all binary-distribution (Layer-2). This makes the shipped artifacts honest:
- Windows host + client: bundled FFmpeg BtbN gpl-shared -> lgpl-shared (AMF/QSV/decode
unaffected; the GPL-only x264/x265 were never used), and ship the FFmpeg LGPL notice
+ license text in the installer + MSIX (licenses/).
- THIRD-PARTY-NOTICES.txt generated + bundled into installer/MSIX/deb/rpm. Offline
generator (scripts/gen-third-party-notices.{py,sh}) + cargo-about config (about.toml/
.hbs) with a permissive-only accepted-license allow-list as a copyleft regression gate.
- Reword the win32u GPU-preference hook comments to reflect independent reimplementation
(no Apollo/Sunshine GPL-3.0 source copied).
- README dual-license + inbound=outbound contributor clause + non-affiliation trademark
disclaimer; new CONTRIBUTING.md.
- LICENSE files into the standalone driver + vk-layer workspaces; deb copyright holder
aligned to "unom and the punktfunk contributors".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,8 +24,9 @@
|
||||
# GPU backends: the host builds with --features nvenc,amf-qsv = all three vendors in one installer.
|
||||
# - NVENC (NVIDIA, direct SDK): the only link need is nvencodeapi.lib, synthesised from a 2-export
|
||||
# .def with llvm-dlltool (no GPU/SDK at build time).
|
||||
# - AMF/QSV (AMD/Intel, libavcodec): link-imports the FFmpeg libs from FFMPEG_DIR (the BtbN gpl-shared
|
||||
# - AMF/QSV (AMD/Intel, libavcodec): link-imports the FFmpeg libs from FFMPEG_DIR (the BtbN lgpl-shared
|
||||
# tree the client uses; includes the *_amf/*_qsv encoders) and bundles its DLLs into the installer.
|
||||
# lgpl-shared (not gpl-shared) keeps those bundled DLLs LGPL (we never use the GPL-only x264/x265).
|
||||
# CI never launches the exe, so no GPU is needed here — this is build + Windows clippy coverage only.
|
||||
name: windows-host
|
||||
|
||||
@@ -80,7 +81,7 @@ jobs:
|
||||
# (pwsh Out-File utf8 = no BOM, unlike Windows PowerShell 5.1 — keeps the first line clean).
|
||||
"CARGO_TARGET_DIR=C:\t" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
||||
"CARGO_WORKSPACE_DIR=$env:GITHUB_WORKSPACE" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
||||
# FFMPEG_DIR: the same BtbN gpl-shared x64 tree the Windows CLIENT links against (provisioned
|
||||
# FFMPEG_DIR: the same BtbN lgpl-shared x64 tree the Windows CLIENT links against (provisioned
|
||||
# by scripts/ci/setup-windows-runner.ps1). The host's AMD/Intel AMF/QSV encode backend
|
||||
# (--features amf-qsv) link-imports avcodec/avutil/swscale from it; pack-host-installer.ps1
|
||||
# then bundles its bin\*.dll into the installer. LIBCLANG_PATH is in the runner daemon env.
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# Contributing to punktfunk
|
||||
|
||||
Thanks for your interest in contributing!
|
||||
|
||||
## Licensing of contributions (inbound = outbound)
|
||||
|
||||
punktfunk is dual-licensed under **MIT OR Apache-2.0**.
|
||||
|
||||
> Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in
|
||||
> the work by you, as defined in the Apache-2.0 license, shall be dual licensed as **MIT OR
|
||||
> Apache-2.0**, without any additional terms or conditions.
|
||||
|
||||
By opening a pull request you agree to license your contribution under these terms. This is the
|
||||
standard Rust-ecosystem "inbound = outbound" model; it keeps the project's licensing unambiguous
|
||||
(including the Apache-2.0 §5 contributor patent grant) and any future relicensing clean. You retain
|
||||
the copyright to your contributions.
|
||||
|
||||
### Do not paste copyleft (or otherwise incompatibly-licensed) code
|
||||
|
||||
The single thing that could poison the permissive license is **copied source from a copyleft
|
||||
project**. Several adjacent projects (Sunshine, Apollo, Moonlight) are GPL-3.0. You may study them
|
||||
and reimplement a *technique*, protocol, or wire format — those are not copyrightable — but **never
|
||||
paste their code**, and do not translate a GPL implementation line-by-line. When a comment credits
|
||||
prior art, make clear it is an independent reimplementation, not a copy. The same applies to any
|
||||
third party's code under a license incompatible with MIT/Apache.
|
||||
|
||||
If you add a new third-party dependency, it must be permissive (MIT / Apache-2.0 / BSD / ISC / Zlib /
|
||||
Unicode-3.0 / etc.). `about.toml` holds the accepted-license allow-list; regenerate the attribution
|
||||
file with `scripts/gen-third-party-notices.sh` when the dependency tree changes.
|
||||
|
||||
## Before you push
|
||||
|
||||
```sh
|
||||
cargo fmt --all --check
|
||||
cargo clippy --workspace --all-targets -- -D warnings
|
||||
cargo test --workspace
|
||||
```
|
||||
|
||||
Generated artifacts are checked in and CI fails on drift: `include/punktfunk_core.h` (cbindgen) and
|
||||
`api/openapi.json` (`cargo run -p punktfunk-host -- openapi`). Match the surrounding code's comment
|
||||
density and naming. Commit messages end with the `Co-Authored-By` trailer (see `git log`).
|
||||
|
||||
See [`CLAUDE.md`](CLAUDE.md) for the full build/test/run guide and design invariants.
|
||||
@@ -155,4 +155,31 @@ tools/ latency-probe · loss-harness (measurement)
|
||||
|
||||
## License
|
||||
|
||||
MIT OR Apache-2.0.
|
||||
Licensed under either of
|
||||
|
||||
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||
<https://www.apache.org/licenses/LICENSE-2.0>)
|
||||
- MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/licenses/MIT>)
|
||||
|
||||
at your option — `SPDX-License-Identifier: MIT OR Apache-2.0`.
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in
|
||||
the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
|
||||
additional terms or conditions. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||
|
||||
### Third-party components
|
||||
|
||||
punktfunk's own source is MIT/Apache-2.0. Shipped binaries additionally link third-party components
|
||||
under their own (permissive) licenses — see [`THIRD-PARTY-NOTICES.txt`](THIRD-PARTY-NOTICES.txt)
|
||||
(regenerate with `scripts/gen-third-party-notices.sh`). The Windows host and client builds also
|
||||
bundle FFmpeg under the **LGPL v2.1+** (dynamically linked, replaceable DLLs; the license text and
|
||||
notice ship in the installed `licenses/` folder).
|
||||
|
||||
### Trademarks
|
||||
|
||||
punktfunk is an independent project and is **not affiliated with, endorsed by, or sponsored by**
|
||||
NVIDIA, Microsoft, Sony, Valve, or the Moonlight project. "GameStream", "Moonlight", "Xbox",
|
||||
"DualSense", "DualShock", and "PlayStation" are trademarks of their respective owners and are used
|
||||
here only to describe interoperability.
|
||||
|
||||
+16154
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
THIRD-PARTY SOFTWARE NOTICES
|
||||
============================================================================
|
||||
|
||||
punktfunk (https://git.unom.io/unom/punktfunk) is licensed under MIT OR Apache-2.0.
|
||||
The binaries it ships statically/dynamically link the third-party Rust crates below.
|
||||
Each is distributed under its own permissive license; full texts follow.
|
||||
Generated by `cargo about generate about.hbs` (see about.toml) — do not edit by hand.
|
||||
|
||||
Overview:
|
||||
{{#each overview}}
|
||||
{{name}} ({{id}}): {{count}} crate(s)
|
||||
{{/each}}
|
||||
|
||||
{{#each licenses}}
|
||||
----------------------------------------------------------------------------
|
||||
{{name}} ({{id}})
|
||||
Used by:
|
||||
{{#each used_by}} - {{crate.name}} {{crate.version}}{{#if crate.repository}} ({{crate.repository}}){{/if}}
|
||||
{{/each}}
|
||||
----------------------------------------------------------------------------
|
||||
{{text}}
|
||||
|
||||
{{/each}}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
# cargo-about config — full-fidelity third-party license harvest for CI.
|
||||
#
|
||||
# cargo install cargo-about
|
||||
# cargo about generate about.hbs > THIRD-PARTY-NOTICES.txt # (or use scripts/gen-third-party-notices.sh)
|
||||
#
|
||||
# `accepted` is the allow-list of SPDX licenses permitted in the dependency tree. CI fails if a crate
|
||||
# carries anything not listed here — which is exactly the regression guard we want against a copyleft
|
||||
# dependency silently entering the linked set. All entries
|
||||
# below are permissive / attribution-only; deliberately NO GPL/LGPL/AGPL/MPL-link/SSPL/EPL.
|
||||
#
|
||||
# The dependency-free fallback is scripts/gen-third-party-notices.py (reads the cargo registry cache),
|
||||
# which is what produced the committed baseline when cargo-about is unavailable offline.
|
||||
|
||||
accepted = [
|
||||
"MIT",
|
||||
"MIT-0",
|
||||
"Apache-2.0",
|
||||
"Apache-2.0 WITH LLVM-exception",
|
||||
"BSD-2-Clause",
|
||||
"BSD-3-Clause",
|
||||
"ISC",
|
||||
"Zlib",
|
||||
"0BSD",
|
||||
"BSL-1.0",
|
||||
"Unicode-3.0",
|
||||
"Unicode-DFS-2016",
|
||||
"CDLA-Permissive-2.0",
|
||||
"CC0-1.0",
|
||||
"Unlicense",
|
||||
"WTFPL",
|
||||
"OpenSSL",
|
||||
]
|
||||
|
||||
# cbindgen is MPL-2.0 but it is a BUILD-ONLY codegen tool that never links into a shipped artifact
|
||||
# (its generated header is not a derivative work), so it is excluded from the notices rather than
|
||||
# accepted as a linked license.
|
||||
ignore-build-dependencies = true
|
||||
ignore-dev-dependencies = true
|
||||
|
||||
# r-efi offers an LGPL-2.1-or-later arm but is tri-licensed; take a permissive arm. (It is also
|
||||
# UEFI-target-gated out of every shipped build.)
|
||||
[r-efi.clarify]
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[ring.clarify]
|
||||
license = "MIT AND ISC AND OpenSSL"
|
||||
|
||||
[aws-lc-sys.clarify]
|
||||
license = "ISC AND Apache-2.0 AND MIT AND BSD-3-Clause AND OpenSSL"
|
||||
@@ -76,11 +76,29 @@ foreach ($f in $required) {
|
||||
Copy-Item $src (Join-Path $layout $f) -Force
|
||||
}
|
||||
|
||||
# FFmpeg runtime DLLs (the exe link-imports the decode set; copy them all — small and correct)
|
||||
# FFmpeg runtime DLLs (the exe link-imports the decode set; copy them all — small and correct).
|
||||
# These are unmodified BtbN *lgpl-shared* builds, linked dynamically (replaceable DLLs) — FFmpeg is
|
||||
# used under the LGPL v2.1+; the license text + notice ship in licenses\ below.
|
||||
$ff = Get-ChildItem -Path $FfmpegBin -Filter *.dll -ErrorAction SilentlyContinue
|
||||
if (-not $ff) { throw "no FFmpeg DLLs in $FfmpegBin" }
|
||||
$ff | ForEach-Object { Copy-Item $_.FullName (Join-Path $layout $_.Name) -Force }
|
||||
|
||||
# license/attribution payload (MSIX has no installer EULA page, so ship them as files): FFmpeg's LGPL
|
||||
# notice + license text, the project's own MIT/Apache texts, and the generated third-party notices.
|
||||
$licDir = Join-Path $layout 'licenses'
|
||||
New-Item -ItemType Directory -Force -Path $licDir | Out-Null
|
||||
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..\..')).Path
|
||||
Copy-Item (Join-Path $repoRoot 'packaging\windows\licenses\FFmpeg-LGPL-NOTICE.txt') $licDir -Force -ErrorAction SilentlyContinue
|
||||
foreach ($n in @('THIRD-PARTY-NOTICES.txt', 'LICENSE-MIT', 'LICENSE-APACHE')) {
|
||||
$p = Join-Path $repoRoot $n
|
||||
if (Test-Path $p) { Copy-Item $p $licDir -Force }
|
||||
}
|
||||
$ffRoot = Split-Path $FfmpegBin -Parent
|
||||
foreach ($lic in @('LICENSE.txt', 'LICENSE', 'COPYING.LGPLv2.1', 'COPYING.LGPLv3', 'COPYING.txt')) {
|
||||
$p = Join-Path $ffRoot $lic
|
||||
if (Test-Path $p) { Copy-Item $p $licDir -Force }
|
||||
}
|
||||
|
||||
# tile/store assets
|
||||
Copy-Item (Join-Path $assets '*') (Join-Path $layout 'Assets') -Force
|
||||
|
||||
|
||||
@@ -217,6 +217,7 @@ bytemuck = { version = "1.19", features = ["derive"] }
|
||||
# nvEncodeAPI64.dll) on the linker path. Build the GPU host with `--features nvenc`.
|
||||
nvenc = ["dep:nvidia-video-codec-sdk"]
|
||||
# AMD/Intel hardware encode on Windows (AMF/QSV via ffmpeg-next). OFF by default: it needs a
|
||||
# `FFMPEG_DIR` (BtbN gpl-shared, includes `*_amf`/`*_qsv`) at build time and bundles the FFmpeg
|
||||
# DLLs at runtime. Build the all-vendor GPU host with `--features nvenc,amf-qsv`.
|
||||
# `FFMPEG_DIR` (BtbN lgpl-shared — includes `*_amf`/`*_qsv`; the GPL-only x264/x265 are never used,
|
||||
# so the LGPL build suffices and keeps the bundled DLLs LGPL, not GPL) at build time and bundles the
|
||||
# FFmpeg DLLs at runtime. Build the all-vendor GPU host with `--features nvenc,amf-qsv`.
|
||||
amf-qsv = ["dep:ffmpeg-next"]
|
||||
|
||||
@@ -188,7 +188,8 @@ pub(crate) unsafe fn make_device(
|
||||
let device = device.context("null D3D11 device")?;
|
||||
let context = context.context("null D3D11 context")?;
|
||||
|
||||
// Apollo-style GPU scheduling hardening (Sunshine display_base.cpp:599-709). Our capture+encode
|
||||
// GPU scheduling hardening — the same approach Sunshine/Apollo use, reimplemented here via the
|
||||
// documented D3DKMT/DXGI APIs (no GPL source copied). Our capture+encode
|
||||
// shares the GPU with the streamed game; when the game saturates the GPU our process is starved of
|
||||
// GPU time slices, so NVENC sits near-idle yet `lock_bitstream` waits ~20 ms for our context to be
|
||||
// scheduled — capping the stream (~47 fps measured at 5K@240) and stuttering. Per-frame copy/convert
|
||||
@@ -197,7 +198,7 @@ pub(crate) unsafe fn make_device(
|
||||
// GPU thread priority and a 1-frame latency cap.
|
||||
elevate_process_gpu_priority();
|
||||
if let Ok(dxgi_dev) = device.cast::<IDXGIDevice>() {
|
||||
// Apollo's absolute max GPU thread priority (0x4000001E); fall back to relative +7.
|
||||
// The absolute max GPU thread priority (0x4000001E; the same value Sunshine/Apollo use); fall back to relative +7.
|
||||
if dxgi_dev.SetGPUThreadPriority(0x4000_001E).is_err()
|
||||
&& dxgi_dev.SetGPUThreadPriority(7).is_err()
|
||||
{
|
||||
@@ -291,7 +292,8 @@ unsafe fn d3dkmt_set_scheduling_priority_class(
|
||||
Some(f(process, prio))
|
||||
}
|
||||
|
||||
/// Apollo-style GPU scheduling-priority hardening (Sunshine `display_base.cpp:599-709`). On a
|
||||
/// GPU scheduling-priority hardening — the same approach as Sunshine/Apollo, independently
|
||||
/// implemented via the documented D3DKMT APIs (no GPL source copied). On a
|
||||
/// GPU-saturated game our capture+encode process is starved of GPU time slices — NVENC sits ~idle but
|
||||
/// `lock_bitstream` waits ~20 ms for our context to be scheduled. Elevating the PROCESS GPU scheduling
|
||||
/// priority class (the strong cross-process lever — far more effective than `SetGPUThreadPriority`
|
||||
@@ -532,7 +534,9 @@ const ES_DISPLAY_REQUIRED: u32 = 0x0000_0002;
|
||||
|
||||
/// Replacement for `win32u.dll!NtGdiDdDDIGetCachedHybridQueryValue`: always report
|
||||
/// `D3DKMT_GPU_PREFERENCE_STATE_UNSPECIFIED` (3). We fully replace the function (never call the
|
||||
/// original), so no trampoline is needed. (Ported verbatim from Apollo's MinHook hook.)
|
||||
/// original), so no trampoline is needed. (Independent reimplementation of the same technique Apollo
|
||||
/// uses: Apollo installs its hook via the MinHook library; this is an original inline byte-patch and
|
||||
/// copies no Apollo/GPL source.)
|
||||
unsafe extern "system" fn hybrid_query_hook(gpu_preference: *mut u32) -> i32 {
|
||||
HYBRID_HOOK_HITS.fetch_add(1, Ordering::Relaxed);
|
||||
if gpu_preference.is_null() {
|
||||
@@ -542,7 +546,8 @@ unsafe extern "system" fn hybrid_query_hook(gpu_preference: *mut u32) -> i32 {
|
||||
0 // STATUS_SUCCESS
|
||||
}
|
||||
|
||||
/// Apollo's win32u GPU-preference hook, ported. On a HYBRID-GPU box DXGI resolves a GPU preference
|
||||
/// The win32u GPU-preference hook (the same technique Apollo applies, reimplemented here from the
|
||||
/// documented DDI — no GPL source copied). On a HYBRID-GPU box DXGI resolves a GPU preference
|
||||
/// (registry + power settings + the hybrid-adapter DDI) and REPARENTS outputs onto the chosen render
|
||||
/// GPU — which constantly invalidates Desktop Duplication (DXGI_ERROR_ACCESS_LOST 0x887A0026, the
|
||||
/// freeze/churn observed on the RTX 4090 + AMD iGPU box; `SET_RENDER_ADAPTER` is ignored there). Faking
|
||||
@@ -555,7 +560,7 @@ pub(crate) fn install_gpu_pref_hook() {
|
||||
// SAFETY: this one-time hook install only touches a region it has just validated.
|
||||
// `LoadLibraryA("win32u.dll")` + `GetProcAddress("NtGdiDdDDIGetCachedHybridQueryValue")` yield the
|
||||
// live base of the real exported function, so `target` is a valid executable code pointer to at
|
||||
// least the 12 bytes the patch overwrites (an x64 prologue, per Apollo's verified hook). The two
|
||||
// least the 12 bytes the patch overwrites (an x64 prologue). The two
|
||||
// `ptr::copy_nonoverlapping`s each move exactly 12 bytes between the 12-byte stack arrays
|
||||
// (`patch`/`readback`) and `target`, which `VirtualProtect(target, 12, PAGE_EXECUTE_READWRITE, …)`
|
||||
// has just made writable (and is restored to `old` after) — source and dest never overlap (stack
|
||||
|
||||
@@ -121,7 +121,8 @@ fn real_main() -> Result<()> {
|
||||
punktfunk_core::ABI_VERSION
|
||||
);
|
||||
|
||||
// Install Apollo's win32u GPU-preference hook BEFORE anything touches DXGI (the SudoVDA
|
||||
// Install the win32u GPU-preference hook (same technique as Apollo, reimplemented — no GPL source
|
||||
// copied) BEFORE anything touches DXGI (the virtual-display
|
||||
// render-adapter selection creates a DXGI factory during virtual-display setup, well before
|
||||
// capture). On a hybrid-GPU box this stops DXGI from reparenting the virtual output off the
|
||||
// capture GPU — the ACCESS_LOST churn fix. Idempotent (Once); harmless on non-hybrid boxes.
|
||||
|
||||
@@ -43,6 +43,10 @@ install -Dm0644 scripts/99-punktfunk-client-net.conf \
|
||||
install -Dm0644 LICENSE-MIT "$DOCDIR/LICENSE-MIT"
|
||||
install -Dm0644 LICENSE-APACHE "$DOCDIR/LICENSE-APACHE"
|
||||
install -Dm0644 README.md "$DOCDIR/README.md"
|
||||
# Third-party crate attributions (regenerate with scripts/gen-third-party-notices.sh).
|
||||
if [ -f THIRD-PARTY-NOTICES.txt ]; then
|
||||
install -Dm0644 THIRD-PARTY-NOTICES.txt "$DOCDIR/THIRD-PARTY-NOTICES.txt"
|
||||
fi
|
||||
|
||||
cat > "$DOCDIR/copyright" <<EOF
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
@@ -50,7 +54,7 @@ Upstream-Name: punktfunk
|
||||
Source: https://git.unom.io/unom/punktfunk
|
||||
|
||||
Files: *
|
||||
Copyright: punktfunk contributors
|
||||
Copyright: unom and the punktfunk contributors
|
||||
License: MIT or Apache-2.0
|
||||
Dual-licensed. Full texts in /usr/share/doc/$PKG/LICENSE-MIT and
|
||||
/usr/share/doc/$PKG/LICENSE-APACHE.
|
||||
|
||||
@@ -68,6 +68,10 @@ install -Dm0644 api/openapi.json "$SHAREDIR/openapi.json"
|
||||
install -Dm0644 LICENSE-MIT "$DOCDIR/LICENSE-MIT"
|
||||
install -Dm0644 LICENSE-APACHE "$DOCDIR/LICENSE-APACHE"
|
||||
install -Dm0644 README.md "$DOCDIR/README.md"
|
||||
# Third-party crate attributions (regenerate with scripts/gen-third-party-notices.sh).
|
||||
if [ -f THIRD-PARTY-NOTICES.txt ]; then
|
||||
install -Dm0644 THIRD-PARTY-NOTICES.txt "$DOCDIR/THIRD-PARTY-NOTICES.txt"
|
||||
fi
|
||||
|
||||
# Debian copyright + changelog (cheap, keeps the package well-formed).
|
||||
cat > "$DOCDIR/copyright" <<EOF
|
||||
@@ -76,7 +80,7 @@ Upstream-Name: punktfunk
|
||||
Source: https://git.unom.io/unom/punktfunk
|
||||
|
||||
Files: *
|
||||
Copyright: punktfunk contributors
|
||||
Copyright: unom and the punktfunk contributors
|
||||
License: MIT or Apache-2.0
|
||||
Dual-licensed. Full texts in /usr/share/doc/$PKG/LICENSE-MIT and
|
||||
/usr/share/doc/$PKG/LICENSE-APACHE.
|
||||
|
||||
@@ -261,7 +261,7 @@ install -Dm0644 web/web.env.example %{buildroot}%{_datadir}/punkt
|
||||
%endif
|
||||
|
||||
%files
|
||||
%license LICENSE-MIT LICENSE-APACHE
|
||||
%license LICENSE-MIT LICENSE-APACHE THIRD-PARTY-NOTICES.txt
|
||||
%doc README.md design/implementation-plan.md packaging/README.md
|
||||
%{_bindir}/punktfunk-host
|
||||
%{_udevrulesdir}/60-punktfunk.rules
|
||||
@@ -276,7 +276,7 @@ install -Dm0644 web/web.env.example %{buildroot}%{_datadir}/punkt
|
||||
%{_datadir}/%{name}/*
|
||||
|
||||
%files client
|
||||
%license LICENSE-MIT LICENSE-APACHE
|
||||
%license LICENSE-MIT LICENSE-APACHE THIRD-PARTY-NOTICES.txt
|
||||
%{_bindir}/punktfunk-client
|
||||
%{_datadir}/applications/io.unom.Punktfunk.desktop
|
||||
%{_udevrulesdir}/70-punktfunk-client.rules
|
||||
@@ -284,7 +284,7 @@ install -Dm0644 web/web.env.example %{buildroot}%{_datadir}/punkt
|
||||
|
||||
%if %{with web}
|
||||
%files web
|
||||
%license LICENSE-MIT LICENSE-APACHE
|
||||
%license LICENSE-MIT LICENSE-APACHE THIRD-PARTY-NOTICES.txt
|
||||
%{_bindir}/punktfunk-web-server
|
||||
%dir %{_datadir}/punktfunk-web
|
||||
%{_datadir}/punktfunk-web/.output
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or Derivative
|
||||
Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2026 unom
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 unom
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,41 @@
|
||||
FFmpeg — third-party component notice
|
||||
=====================================
|
||||
|
||||
This product bundles unmodified shared libraries from the FFmpeg project
|
||||
(avcodec / avutil / avformat / swscale / swresample and their dependencies) as
|
||||
separate dynamic-link libraries (DLLs). punktfunk uses them only for hardware
|
||||
video encode (AMD AMF / Intel QSV) on the host and hardware/software video
|
||||
decode on the client.
|
||||
|
||||
License
|
||||
-------
|
||||
The bundled FFmpeg libraries are distributed under the GNU Lesser General Public
|
||||
License (LGPL), version 2.1 or later. The bundled builds are the "lgpl-shared"
|
||||
configuration — they do NOT include any GPL-licensed components (notably they do
|
||||
not include libx264 or libx265; punktfunk does not use them). The full text of
|
||||
the LGPL accompanies this notice (see the COPYING.LGPLv2.1 / LICENSE files in
|
||||
this directory; if absent, see https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html).
|
||||
|
||||
How punktfunk complies (dynamic linking)
|
||||
----------------------------------------
|
||||
punktfunk links FFmpeg only dynamically: the FFmpeg DLLs are shipped as separate
|
||||
files alongside the application and are not statically combined into the
|
||||
punktfunk executable. You may replace these DLLs with your own ABI-compatible
|
||||
build of FFmpeg, which satisfies LGPL section 6 (the right to relink the work
|
||||
against a modified version of the library).
|
||||
|
||||
Source code
|
||||
-----------
|
||||
The bundled binaries are unmodified builds produced by the BtbN/FFmpeg-Builds
|
||||
project. The exact source for the FFmpeg release used is available from:
|
||||
|
||||
* FFmpeg project source: https://ffmpeg.org/download.html (release n7.1)
|
||||
* Exact build recipe: https://github.com/BtbN/FFmpeg-Builds
|
||||
|
||||
A copy of the corresponding FFmpeg source for the version shipped here is
|
||||
available on request from the punktfunk maintainers (https://git.unom.io/unom/punktfunk).
|
||||
|
||||
Trademark
|
||||
---------
|
||||
FFmpeg is a trademark of Fabrice Bellard, originator of the FFmpeg project.
|
||||
punktfunk is not affiliated with or endorsed by the FFmpeg project.
|
||||
@@ -132,12 +132,25 @@ Copy-Item -LiteralPath $hostEnvSrc -Destination $hostEnv -Force
|
||||
Copy-Item -LiteralPath $readmeSrc -Destination $readme -Force
|
||||
Copy-Item -LiteralPath $iss -Destination $issLocal -Force
|
||||
|
||||
# License/attribution payload bundled into {app}\licenses: the project's own MIT/Apache texts and the
|
||||
# generated third-party crate notices. The FFmpeg LGPL notice + license text are added to this same
|
||||
# dir below when the AMF/QSV FFmpeg DLLs are bundled. (THIRD-PARTY-NOTICES.txt is committed; CI may
|
||||
# regenerate it via scripts/gen-third-party-notices.sh before packaging.)
|
||||
$licStage = Join-Path $OutDir 'licenses'
|
||||
New-Item -ItemType Directory -Force -Path $licStage | Out-Null
|
||||
foreach ($n in @('LICENSE-MIT', 'LICENSE-APACHE', 'THIRD-PARTY-NOTICES.txt')) {
|
||||
$p = Join-Path $repoRoot $n
|
||||
if (Test-Path $p) { Copy-Item $p -Destination $licStage -Force }
|
||||
else { Write-Warning "license payload missing (skipped): $p" }
|
||||
}
|
||||
|
||||
$defines = @(
|
||||
"/DMyAppVersion=$Version",
|
||||
"/DBinDir=$TargetDir",
|
||||
"/DOutputDir=$OutDir",
|
||||
"/DHostEnv=$hostEnv",
|
||||
"/DReadme=$readme"
|
||||
"/DReadme=$readme",
|
||||
"/DLicensesDir=$licStage"
|
||||
)
|
||||
|
||||
# --- build (from source) + stage the pf-vdisplay virtual-display driver -----------------------
|
||||
@@ -179,7 +192,7 @@ if (-not $NoDriver) {
|
||||
# --- stage the FFmpeg shared DLLs (AMD/Intel AMF/QSV build) ------------------------------------
|
||||
# A host built with --features amf-qsv link-imports avcodec/avutil/swscale/... so the shared DLLs
|
||||
# MUST sit next to the exe (it won't start otherwise). Bundle them from $FfmpegDir\bin - the same
|
||||
# BtbN gpl-shared tree the build linked against. A nvenc/software-only build doesn't import them, so
|
||||
# BtbN lgpl-shared tree the build linked against. A nvenc/software-only build doesn't import them, so
|
||||
# this is a harmless extra there; skipped entirely when $FfmpegDir is unset.
|
||||
$ffmpegBinSrc = if ($FfmpegDir) { Join-Path $FfmpegDir 'bin' } else { $null }
|
||||
if ($ffmpegBinSrc -and (Test-Path $ffmpegBinSrc)) {
|
||||
@@ -190,6 +203,16 @@ if ($ffmpegBinSrc -and (Test-Path $ffmpegBinSrc)) {
|
||||
$dlls | ForEach-Object { Copy-Item $_.FullName -Destination $ffmpegStage -Force }
|
||||
$defines += "/DFfmpegBin=$ffmpegStage"
|
||||
Write-Host "bundling $($dlls.Count) FFmpeg DLL(s) from $ffmpegBinSrc"
|
||||
# LGPL compliance: add FFmpeg's own license text (preserved in the BtbN tree root) + our
|
||||
# attribution notice to the {app}\licenses payload so the conveyed installer carries the
|
||||
# LGPLv2.1+ terms. FFmpeg is linked dynamically (separate, user-replaceable DLLs), which
|
||||
# satisfies the LGPL relink requirement.
|
||||
Copy-Item (Join-Path $here 'licenses\FFmpeg-LGPL-NOTICE.txt') -Destination $licStage -Force -ErrorAction SilentlyContinue
|
||||
foreach ($lic in @('LICENSE.txt', 'LICENSE', 'COPYING.LGPLv2.1', 'COPYING.LGPLv3', 'COPYING.txt')) {
|
||||
$p = Join-Path $FfmpegDir $lic
|
||||
if (Test-Path $p) { Copy-Item $p -Destination (Join-Path $licStage "FFmpeg-$lic") -Force }
|
||||
}
|
||||
Write-Host "added FFmpeg license/notice to $licStage"
|
||||
}
|
||||
}
|
||||
else { Write-Host "no FFMPEG_DIR\bin -> installer built WITHOUT FFmpeg DLLs (nvenc/software-only host)" }
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or Derivative
|
||||
Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2026 unom
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 unom
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -102,10 +102,17 @@ Name: "startservice"; Description: "Start the punktfunk host service now (also s
|
||||
Source: "{#BinDir}\punktfunk-host.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "{#HostEnv}"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "{#Readme}"; DestDir: "{app}"; DestName: "README.txt"; Flags: ignoreversion
|
||||
#ifdef LicensesDir
|
||||
; License/attribution payload -> {app}\licenses: the project's MIT/Apache texts, the generated
|
||||
; THIRD-PARTY-NOTICES (permissive crate attributions), and (on an amf-qsv build) the FFmpeg LGPL
|
||||
; notice + license text. Staged by pack-host-installer.ps1.
|
||||
Source: "{#LicensesDir}\*"; DestDir: "{app}\licenses"; Flags: ignoreversion
|
||||
#endif
|
||||
#ifdef WithFfmpeg
|
||||
; FFmpeg shared DLLs (avcodec/avutil/swscale/...) laid down next to the exe - the AMD/Intel
|
||||
; (AMF/QSV) encode backend link-imports them, so the exe won't start without them. NVENC/software-
|
||||
; only builds simply omit this block.
|
||||
; only builds simply omit this block. These are unmodified BtbN *lgpl-shared* builds, linked
|
||||
; dynamically (replaceable DLLs) - FFmpeg is used under the LGPL v2.1+; see {app}\licenses.
|
||||
Source: "{#FfmpegBin}\*.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
#endif
|
||||
#ifdef WithWeb
|
||||
|
||||
@@ -102,22 +102,35 @@ if (Test-Path $rustup) {
|
||||
& $rustup target add aarch64-pc-windows-msvc
|
||||
} else { Write-Warning "rustup not found - install rustup then re-run (needed for the aarch64 target)." }
|
||||
|
||||
$ffArm = "C:\Users\Public\ffmpeg-arm64"
|
||||
if (-not (Test-Path (Join-Path $ffArm 'lib\avcodec.lib'))) {
|
||||
# BtbN winarm64 shared, FFmpeg 7.x (avcodec-61) to match the x64 tree's ABI. MSVC-linkable .lib
|
||||
# import libs + headers + bin\*.dll — exactly what ffmpeg-sys-next + pack-msix.ps1 consume.
|
||||
Write-Host "==> fetching ARM64 FFmpeg (BtbN winarm64 shared)"
|
||||
$ffUrl = 'https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-n7.1-latest-winarm64-gpl-shared-7.1.zip'
|
||||
$ffZip = "C:\Users\Public\ffmpeg-arm64.zip"
|
||||
$ffTmp = "C:\Users\Public\ffmpeg-arm64-extract"
|
||||
Invoke-WebRequest -Uri $ffUrl -OutFile $ffZip -UseBasicParsing
|
||||
if (Test-Path $ffTmp) { Remove-Item -Recurse -Force $ffTmp }
|
||||
Expand-Archive -Path $ffZip -DestinationPath $ffTmp -Force # BtbN zips have one top-level folder
|
||||
$inner = Get-ChildItem $ffTmp -Directory | Select-Object -First 1
|
||||
if (Test-Path $ffArm) { Remove-Item -Recurse -Force $ffArm }
|
||||
Move-Item -Path $inner.FullName -Destination $ffArm
|
||||
Remove-Item -Force $ffZip; Remove-Item -Recurse -Force $ffTmp -ErrorAction SilentlyContinue
|
||||
# FFmpeg shared trees for the host (amf-qsv encode) + clients (decode). We use BtbN **lgpl-shared**
|
||||
# builds: the AMD/Intel AMF + Intel QSV encoders, swscale, and the HEVC decoder are all present in the
|
||||
# LGPL build, and punktfunk never calls the GPL-only encoders (x264/x265 — software encode is the
|
||||
# separate BSD-2 openh264 crate; NVENC is the direct NVIDIA SDK). lgpl-shared keeps the bundled DLLs
|
||||
# LGPL-2.1+ (dynamic linking satisfies the relink duty) rather than GPL, so the shipped installer/MSIX
|
||||
# stay consistent with punktfunk's MIT OR Apache-2.0 posture.
|
||||
# MIGRATION: a runner previously provisioned with the old *gpl-shared* trees must be re-provisioned —
|
||||
# delete C:\Users\Public\ffmpeg and C:\Users\Public\ffmpeg-arm64, then re-run this script.
|
||||
function Get-BtbnFfmpeg {
|
||||
param([string]$Dir, [string]$ZipTag) # ZipTag: 'win64' (x64) or 'winarm64' (ARM64 cross tree)
|
||||
if (Test-Path (Join-Path $Dir 'lib\avcodec.lib')) { return }
|
||||
# FFmpeg 7.x (avcodec-61); MSVC-linkable .lib import libs + headers + bin\*.dll — exactly what
|
||||
# ffmpeg-sys-next + pack-host-installer.ps1 + pack-msix.ps1 consume. The extracted top-level folder
|
||||
# also carries FFmpeg's own LICENSE/COPYING text, preserved in $Dir for the packagers to bundle.
|
||||
Write-Host "==> fetching FFmpeg ($ZipTag, BtbN lgpl-shared)"
|
||||
$url = "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-n7.1-latest-$ZipTag-lgpl-shared-7.1.zip"
|
||||
$zip = "$Dir.zip"; $tmp = "$Dir-extract"
|
||||
Invoke-WebRequest -Uri $url -OutFile $zip -UseBasicParsing
|
||||
if (Test-Path $tmp) { Remove-Item -Recurse -Force $tmp }
|
||||
Expand-Archive -Path $zip -DestinationPath $tmp -Force # BtbN zips have one top-level folder
|
||||
$inner = Get-ChildItem $tmp -Directory | Select-Object -First 1
|
||||
if (Test-Path $Dir) { Remove-Item -Recurse -Force $Dir }
|
||||
Move-Item -Path $inner.FullName -Destination $Dir
|
||||
Remove-Item -Force $zip; Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue
|
||||
}
|
||||
# x64 host+client tree (the workflow's default FFMPEG_DIR = C:\Users\Public\ffmpeg) and the ARM64 cross
|
||||
# tree (the aarch64 leg points FFMPEG_DIR at C:\Users\Public\ffmpeg-arm64).
|
||||
Get-BtbnFfmpeg -Dir "C:\Users\Public\ffmpeg" -ZipTag 'win64'
|
||||
Get-BtbnFfmpeg -Dir "C:\Users\Public\ffmpeg-arm64" -ZipTag 'winarm64'
|
||||
|
||||
# Inno Setup (ISCC.exe) for the host installer build (windows-host.yml). pack-host-installer.ps1
|
||||
# locates it at its fixed Program Files path, so it need not be on PATH — just present.
|
||||
|
||||
Executable
+134
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate THIRD-PARTY-NOTICES.txt for the Rust workspace.
|
||||
|
||||
Offline, dependency-free attribution generator. It reads `cargo metadata`, then for every
|
||||
third-party crate (everything that is NOT a first-party workspace member) it pulls the crate's
|
||||
*actual* LICENSE/COPYING/NOTICE text out of the local cargo registry cache (or the in-tree
|
||||
vendored source for path deps), deduplicates identical license texts, and emits a single
|
||||
notices file: a per-crate manifest followed by the verbatim license texts.
|
||||
|
||||
This satisfies the binary-distribution attribution duty for the permissive (MIT/BSD/ISC/Zlib/
|
||||
Apache/Unicode/etc.) crates linked into shipped punktfunk artifacts. `cargo about` (see
|
||||
about.toml) produces an equivalent, network-augmented result in CI; this is the dependency-free
|
||||
fallback that also runs locally and is committed as a baseline.
|
||||
|
||||
Usage: python3 scripts/gen-third-party-notices.py [--out THIRD-PARTY-NOTICES.txt]
|
||||
"""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
LICENSE_GLOBS = ("license", "licence", "copying", "notice", "unlicense", "copyright")
|
||||
|
||||
|
||||
def find_license_files(pkg_dir):
|
||||
out = []
|
||||
try:
|
||||
names = sorted(os.listdir(pkg_dir))
|
||||
except OSError:
|
||||
return out
|
||||
for n in names:
|
||||
low = n.lower()
|
||||
if any(low == g or low.startswith(g + ".") or low.startswith(g + "-") or g in low for g in LICENSE_GLOBS):
|
||||
p = os.path.join(pkg_dir, n)
|
||||
if os.path.isfile(p):
|
||||
try:
|
||||
with open(p, "r", encoding="utf-8", errors="replace") as f:
|
||||
txt = f.read().strip()
|
||||
if txt:
|
||||
out.append((n, txt))
|
||||
except OSError:
|
||||
pass
|
||||
return out
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--out", default="THIRD-PARTY-NOTICES.txt")
|
||||
ap.add_argument("--manifest", default="Cargo.toml")
|
||||
args = ap.parse_args()
|
||||
|
||||
meta = json.loads(subprocess.check_output(
|
||||
["cargo", "metadata", "--format-version", "1", "--offline", "--manifest-path", args.manifest],
|
||||
text=True))
|
||||
ws_members = set(meta.get("workspace_members", []))
|
||||
|
||||
pkgs = []
|
||||
for p in meta["packages"]:
|
||||
if p["id"] in ws_members:
|
||||
continue # first-party (covered by the root LICENSE-MIT / LICENSE-APACHE)
|
||||
pkgs.append(p)
|
||||
pkgs.sort(key=lambda p: (p["name"].lower(), p["version"]))
|
||||
|
||||
# Group license texts: text-hash -> {text, name, crates[]}
|
||||
texts = {}
|
||||
no_text = []
|
||||
for p in pkgs:
|
||||
pkg_dir = os.path.dirname(p["manifest_path"])
|
||||
files = find_license_files(pkg_dir)
|
||||
label = f'{p["name"]} {p["version"]}'
|
||||
if not files:
|
||||
no_text.append(p)
|
||||
continue
|
||||
for fname, txt in files:
|
||||
h = hashlib.sha256(txt.encode("utf-8", "replace")).hexdigest()
|
||||
ent = texts.setdefault(h, {"text": txt, "filename": fname, "crates": set()})
|
||||
ent["crates"].add(label)
|
||||
|
||||
lines = []
|
||||
w = lines.append
|
||||
w("THIRD-PARTY SOFTWARE NOTICES")
|
||||
w("=" * 76)
|
||||
w("")
|
||||
w("punktfunk (https://git.unom.io/unom/punktfunk) is licensed under MIT OR Apache-2.0.")
|
||||
w("The binaries it ships statically/dynamically link the third-party Rust crates listed")
|
||||
w("below. Each is distributed under its own permissive license; the full license texts")
|
||||
w("follow the manifest. This file is generated by scripts/gen-third-party-notices.py")
|
||||
w("(or `cargo about`, see about.toml) — do not edit by hand.")
|
||||
w("")
|
||||
w(f"Total third-party crates: {len(pkgs)}")
|
||||
w("")
|
||||
w("-" * 76)
|
||||
w("MANIFEST (crate version — SPDX license — source)")
|
||||
w("-" * 76)
|
||||
for p in pkgs:
|
||||
lic = p.get("license") or (("file: " + p["license_file"]) if p.get("license_file") else "UNKNOWN")
|
||||
repo = p.get("repository") or ""
|
||||
w(f' {p["name"]} {p["version"]} — {lic}' + (f' — {repo}' if repo else ""))
|
||||
w("")
|
||||
|
||||
if no_text:
|
||||
w("-" * 76)
|
||||
w("Crates whose package did not embed a license file (SPDX + source only)")
|
||||
w("-" * 76)
|
||||
for p in no_text:
|
||||
lic = p.get("license") or "UNKNOWN"
|
||||
repo = p.get("repository") or ""
|
||||
w(f' {p["name"]} {p["version"]} — {lic}' + (f' — {repo}' if repo else ""))
|
||||
w("")
|
||||
|
||||
w("=" * 76)
|
||||
w("FULL LICENSE TEXTS (deduplicated)")
|
||||
w("=" * 76)
|
||||
# Stable order: by first crate name covered.
|
||||
for h, ent in sorted(texts.items(), key=lambda kv: sorted(kv[1]["crates"])[0].lower()):
|
||||
crates = ", ".join(sorted(ent["crates"]))
|
||||
w("")
|
||||
w("-" * 76)
|
||||
w(f"The following license ({ent['filename']}) applies to: {crates}")
|
||||
w("-" * 76)
|
||||
w(ent["text"])
|
||||
w("")
|
||||
|
||||
text = "\n".join(lines) + "\n"
|
||||
with open(args.out, "w", encoding="utf-8") as f:
|
||||
f.write(text)
|
||||
print(f"wrote {args.out}: {len(pkgs)} crates, {len(texts)} distinct license texts, "
|
||||
f"{len(no_text)} without embedded text", file=sys.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
# Regenerate THIRD-PARTY-NOTICES.txt for the Rust workspace.
|
||||
#
|
||||
# Prefers `cargo about` (full, network-augmented license harvest; see about.toml) and falls back to
|
||||
# the dependency-free offline generator (scripts/gen-third-party-notices.py, reads the cargo registry
|
||||
# cache). Run this when the dependency tree changes; CI also runs it before packaging.
|
||||
#
|
||||
# Usage: scripts/gen-third-party-notices.sh [output-file]
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
OUT="${1:-THIRD-PARTY-NOTICES.txt}"
|
||||
|
||||
if command -v cargo-about >/dev/null 2>&1; then
|
||||
echo "==> cargo about generate -> $OUT" >&2
|
||||
cargo about generate about.hbs --output-file "$OUT"
|
||||
else
|
||||
echo "==> cargo-about not installed; using offline fallback" >&2
|
||||
echo " (install the full generator with: cargo install cargo-about)" >&2
|
||||
python3 scripts/gen-third-party-notices.py --out "$OUT"
|
||||
fi
|
||||
echo "==> wrote $OUT" >&2
|
||||
Reference in New Issue
Block a user