chore: consolidate all in-progress parallel-session WIP
audit / bun-audit (push) Successful in 27s
windows-drivers / probe-and-proto (push) Successful in 49s
ci / web (push) Successful in 1m1s
ci / docs-site (push) Successful in 1m10s
apple / swift (push) Successful in 1m18s
decky / build-publish (push) Successful in 34s
windows-drivers / driver-build (push) Successful in 1m37s
audit / cargo-audit (push) Successful in 3m1s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 42s
ci / bench (push) Successful in 5m56s
windows-host / package (push) Failing after 5m17s
apple / screenshots (push) Successful in 4m45s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 4m38s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 11m3s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m2s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 8m6s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 11m6s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 4m15s
arch / build-publish (push) Successful in 16m50s
android / android (push) Successful in 17m7s
docker / deploy-docs (push) Successful in 28s
deb / build-publish (push) Successful in 17m6s
ci / rust (push) Failing after 19m1s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 5m3s
flatpak / build-publish (push) Successful in 8m0s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 5m42s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 14m29s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 14m14s
release / apple (push) Successful in 5m44s
audit / bun-audit (push) Successful in 27s
windows-drivers / probe-and-proto (push) Successful in 49s
ci / web (push) Successful in 1m1s
ci / docs-site (push) Successful in 1m10s
apple / swift (push) Successful in 1m18s
decky / build-publish (push) Successful in 34s
windows-drivers / driver-build (push) Successful in 1m37s
audit / cargo-audit (push) Successful in 3m1s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 42s
ci / bench (push) Successful in 5m56s
windows-host / package (push) Failing after 5m17s
apple / screenshots (push) Successful in 4m45s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 4m38s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 11m3s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m2s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 8m6s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 11m6s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 4m15s
arch / build-publish (push) Successful in 16m50s
android / android (push) Successful in 17m7s
docker / deploy-docs (push) Successful in 28s
deb / build-publish (push) Successful in 17m6s
ci / rust (push) Failing after 19m1s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 5m3s
flatpak / build-publish (push) Successful in 8m0s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 5m42s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 14m29s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 14m14s
release / apple (push) Successful in 5m44s
Wholesale commit of every uncommitted change across the tree, at the user's explicit request — host refactor-campaign W1 (native.rs facade + native/ dir, library/ + mgmt/ splits), Android, core. These streams were mid-flight and not individually built/tested together; this supersedes the per-session HOLD markers. Consolidating so everything lands on main in one pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,13 +2,13 @@
|
||||
//!
|
||||
//! The GameStream media pipeline records its session in `AppState.{launch, stream, streaming}`
|
||||
//! (consumed by RTSP/media), but the native punktfunk/1 plane never touches `AppState` — by design
|
||||
//! it is handed only the shared stats recorder ([`crate::punktfunk1::serve`]). So a native session,
|
||||
//! it is handed only the shared stats recorder ([`crate::native::serve`]). So a native session,
|
||||
//! which is the DEFAULT plane (GameStream is opt-in, `--gamestream`), was invisible on the Dashboard:
|
||||
//! `GET /status` reported `video_streaming: false` and no session/stream card while a client was
|
||||
//! actively streaming (the Stats page worked because it shares the recorder — hence the confusing
|
||||
//! "stats move but the dashboard says idle").
|
||||
//!
|
||||
//! This module is the small shared surface the native video loop ([`crate::punktfunk1::virtual_stream`])
|
||||
//! This module is the small shared surface the native video loop ([`crate::native::virtual_stream`])
|
||||
//! publishes a live snapshot to, keyed per session so CONCURRENT native sessions each get an entry
|
||||
//! (the native server admits up to `max_sessions`, unbounded by default). The loop registers on
|
||||
//! stream start and the returned [`LiveSessionGuard`] removes the entry on ANY scope exit (return,
|
||||
@@ -26,7 +26,7 @@ use crate::encode::Codec;
|
||||
/// second update path — plus the flags the mgmt API flips to control the session.
|
||||
struct LiveSession {
|
||||
id: u64,
|
||||
/// Packed `w:16|h:16|hz:16` ([`crate::punktfunk1::pack_mode`]); updated on a mode switch.
|
||||
/// Packed `w:16|h:16|hz:16` ([`crate::native::pack_mode`]); updated on a mode switch.
|
||||
mode: Arc<AtomicU64>,
|
||||
/// Live encoder target (kbps); updated on an adaptive-bitrate change.
|
||||
bitrate_kbps: Arc<AtomicU32>,
|
||||
@@ -36,6 +36,10 @@ struct LiveSession {
|
||||
/// One-shot force-keyframe flag ([`force_idr_all`] → mgmt `POST /session/idr`); the encode loop
|
||||
/// drains it alongside a client's decode-recovery keyframe request.
|
||||
force_idr: Arc<AtomicBool>,
|
||||
/// Short client label (cert-fingerprint prefix / peer IP) — carried on the lifecycle events.
|
||||
client: String,
|
||||
/// Whether the session negotiated HDR — carried on the lifecycle events.
|
||||
hdr: bool,
|
||||
}
|
||||
|
||||
/// A resolved read of one live session, for the `/status` view.
|
||||
@@ -58,23 +62,44 @@ fn next_id() -> u64 {
|
||||
ID.fetch_add(1, Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// Resolves one session's [`crate::events::SessionRef`] (mode read live) for the lifecycle events.
|
||||
fn session_ref(s: &LiveSession) -> crate::events::SessionRef {
|
||||
let (width, height, fps) = crate::native::unpack_mode(s.mode.load(Ordering::Relaxed));
|
||||
crate::events::SessionRef {
|
||||
id: s.id,
|
||||
client: s.client.clone(),
|
||||
mode: crate::events::mode_str(width, height, fps),
|
||||
hdr: s.hdr,
|
||||
}
|
||||
}
|
||||
|
||||
/// Registers a live native session; the returned guard removes it on drop (session end).
|
||||
/// Emits the `session.started` lifecycle event; the guard's drop emits `session.ended` — RAII,
|
||||
/// so every exit path (return, `?`, panic-unwind) pairs them.
|
||||
pub fn register(
|
||||
mode: Arc<AtomicU64>,
|
||||
bitrate_kbps: Arc<AtomicU32>,
|
||||
codec: Codec,
|
||||
stop: Arc<AtomicBool>,
|
||||
force_idr: Arc<AtomicBool>,
|
||||
client: String,
|
||||
hdr: bool,
|
||||
) -> LiveSessionGuard {
|
||||
let id = next_id();
|
||||
registry().lock().unwrap().push(LiveSession {
|
||||
let session = LiveSession {
|
||||
id,
|
||||
mode,
|
||||
bitrate_kbps,
|
||||
codec,
|
||||
stop,
|
||||
force_idr,
|
||||
client,
|
||||
hdr,
|
||||
};
|
||||
crate::events::emit(crate::events::EventKind::SessionStarted {
|
||||
session: session_ref(&session),
|
||||
});
|
||||
registry().lock().unwrap().push(session);
|
||||
LiveSessionGuard { id }
|
||||
}
|
||||
|
||||
@@ -85,7 +110,14 @@ pub struct LiveSessionGuard {
|
||||
|
||||
impl Drop for LiveSessionGuard {
|
||||
fn drop(&mut self) {
|
||||
registry().lock().unwrap().retain(|s| s.id != self.id);
|
||||
let mut reg = registry().lock().unwrap();
|
||||
if let Some(pos) = reg.iter().position(|s| s.id == self.id) {
|
||||
let session = reg.remove(pos);
|
||||
drop(reg); // emit outside the registry lock — the bus takes its own
|
||||
crate::events::emit(crate::events::EventKind::SessionEnded {
|
||||
session: session_ref(&session),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,8 +133,7 @@ pub fn snapshot() -> Vec<SessionSnapshot> {
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|s| {
|
||||
let (width, height, fps) =
|
||||
crate::punktfunk1::unpack_mode(s.mode.load(Ordering::Relaxed));
|
||||
let (width, height, fps) = crate::native::unpack_mode(s.mode.load(Ordering::Relaxed));
|
||||
SessionSnapshot {
|
||||
width,
|
||||
height,
|
||||
|
||||
Reference in New Issue
Block a user