Commit graph

13 commits

Author SHA1 Message Date
Breadway
b792743626 daemon: use matches! for the link-local host-replace check
Silences clippy::match_like_matches_macro; same logic, no behavior change.
2026-08-15 22:34:21 +08:00
Breadway
7fb1934d52 cast: don't drop the io loop on a single bad message, and don't let a scopeless link-local IPv6 clobber a working host
The receiver-status io loop treated any read error as a dead connection,
so one malformed/unexpected message (e.g. a MEDIA_STATUS missing a field
the struct requires) tore down the whole control channel for the rest of
the session even though the RTP stream was fine. Only end the loop on
Io/Tls/Dns errors now; log and keep going on Serialization/Parsing/etc.

mDNS resolves a single physical Cast device once per local address it
has, so the same device id can show up with a private IPv4 host and
again with a link-local IPv6 host. A bare fe80:: address has no zone id
attached, so connecting to it fails outright -- don't let it replace an
already-usable host in the device map just because it resolved more
recently.
2026-08-15 22:34:21 +08:00
Breadway
696e3f540f gitignore: ignore graphify-out/ knowledge-graph cache
graphify-out/ is local tool output (AST cache, query index, graph.json)
regenerated on demand and never meant to be committed.
2026-08-15 22:34:21 +08:00
Breadway
14274856a3 daemon: preserve full anyhow context chain in IPC error replies
e.to_string() on an anyhow::Error only prints the outermost .context()
message; the underlying cause (why connect_app/build_pipeline/etc.
actually failed) was being silently dropped before it ever reached the
GUI or bread event log. Use "{e:#}" instead.
2026-08-15 22:34:21 +08:00
Breadway
5b49955e33 Fix Cast Streaming teardown crash, bitrate collapse, and HLS latency
Three independent problems found by reading the mirroring paths end to end.

1. Segfault on Cast session teardown. CastStreamSender::SchedulePoll
   self-reschedules every 100ms with a raw `this` and was never cancelled,
   so the one task that can be scheduled to run *after* an already-queued
   teardown task would dereference the just-reset `environment` unique_ptr
   (Environment::task_runner() dereferences a member immediately) --- a hard
   null deref on openscreen's TaskRunner thread. TaskRunnerImpl's shutdown
   has an explicit flushing phase and PlatformClientPosix::ShutDown()'s quit
   task queues behind whatever is already pending, so this is a race the
   teardown path can lose. Latch a `shutting_down` atomic before posting
   teardown and check it in the poll and in every other posted task.

2. Encoder bitrate collapsing to the floor within seconds. The control loop
   set `target = 0.85 * estimate` once a second unconditionally. openscreen's
   BandwidthEstimator deliberately under-estimates capacity whenever the
   transmit rate is below it and documents the required TCP-like response;
   multiplying the target by <=0.85 every second instead walks 4000 kbps past
   1500 in ~6s and pins it at the floor on a healthy LAN. Replaced with
   proper AIMD (hold on a zero/unknown estimate, back off below it, probe up
   10%/s otherwise), clamped to 1000..8000 kbps, with unit tests.

3. DLNA/HLS latency. Segment length is max(target-duration, GOP), so
   target-duration=2 with a 2s GOP gave 2s segments, ~6s of renderer buffer,
   plus 3 segments of stale video waited for before handover. 1s segments
   (GOP halved to make that reachable), shorter playlist, and wait for 2
   segments instead of 3.

Also hardened two paths into openscreen's fatal OSP_CHECK on strictly
increasing RTP timestamps: pull_encoded_frame no longer substitutes 0 for a
missing PTS (it skips the buffer), and facade.cc drops non-monotonic capture
times at the FFI boundary. Either could previously abort the daemon outright.

CastMirrorSession now owns the Arc<CastStreamSender> instead of leaving its
lifetime to whichever detached pump thread dropped the last clone, so the
blocking FFI destroy happens at a defined point in stop() with the pump
joins ordered around it.
2026-08-15 22:34:21 +08:00
Breadway
9c6fc61f53 Track AGENTS.md
All checks were successful
check / check (push) Successful in 2m37s
2026-08-15 22:03:30 +08:00
Breadway
d1dd98a889 docs: describe the shipped bakery product and single-trunk releases
All checks were successful
check / check (push) Successful in 1m12s
README still called the GTK picker and mirroring pipeline stubs. Both
are built: breadcastd discovers Cast and DLNA devices and owns the
session; breadcast is the GTK picker. Install is bakery; this is not
on the BOS ISO.

CONTRIBUTING now follows the ecosystem single-trunk main + RC-tag
model. Leftover dev/beta CI workflows are documented, not rewritten.
bread-theme and bread-utils already pin bread-ecosystem v0.7.1.
2026-08-15 21:38:38 +08:00
bbff5f951c Merge pull request 'ci: build on bread-ecosystem's shared Arch container' (#2) from feature/shared-ci into main
Reviewed-on: #2
2026-08-05 20:09:43 +08:00
Breadway
3d27ddf677 ci: build on bread-ecosystem's shared Arch container
All checks were successful
check / check (push) Successful in 3m27s
Route dev/beta/release build steps through ci/build.sh, pinned to
bread-ecosystem@147cfbb, instead of installing toolchain/libraries
directly on the bare runner. Adds ci/deps.txt for the build-time-only
packages breadcast needs beyond the shared image's base set (jsoncpp
and libcrypto for breadcast-caststream-sys's build.rs; gstreamer and
gst-plugins-base-libs for the gstreamer-app/-video sys crates) --
deliberately excludes bakery.toml's runtime-only plugin deps
(pipewire/bad/hlssink3/va), which are loaded dynamically by name and
never linked at compile time. Also adds check.yml to run clippy/test
on feature/fix branches ahead of a release build, matching breadpad's
already-migrated pattern.
2026-08-05 19:16:28 +08:00
ca98021f68 Merge pull request 'dev' (#1) from dev into main
Reviewed-on: #1
2026-08-03 09:40:06 +08:00
Breadway
1dd63e1fd5 can't be bothered writing a commit message
Some checks failed
dev release / build (push) Failing after 1m43s
2026-08-03 09:17:59 +08:00
Breadway
8c745d18e0 Implement Cast Streaming mirroring, DLNA casting, daemon+GUI, and breadd integration
Some checks failed
dev release / build (push) Failing after 12s
Builds out the full v1 scope: a vendored+patched openscreen subset for
low-latency Cast Streaming (Mirroring receiver 0F5096E8) alongside the
existing Cast V2/HLS and new DLNA/AVTransport casting paths, breadcastd's
Idle/Casting state machine with a private IPC socket, the breadcast GTK4
popup as a thin IPC client, and bread.cast.*/bread.command.cast.* breadd
integration (device discovery, start/stop, mirroring lifecycle events).
Also adds bakery/systemd/Forgejo CI packaging.

Validated end-to-end against a real Chromecast/Google TV: negotiated
Cast Streaming session, live pipeline playback, and daemon+GUI click-to-cast/
stop through the actual popup.
2026-08-03 09:07:21 +08:00
Breadway
887c29002f init 2026-07-29 10:56:37 +08:00