Skip to content

video: pause encoding while nobody is watching - #61

Merged
Rust-KVM merged 1 commit into
devfrom
claude/video-idle-without-viewer
Oct 12, 2026
Merged

Rust-KVM merged 1 commit into
devfrom
claude/video-idle-without-viewer

Conversation

@Rust-KVM

Copy link
Copy Markdown
Owner

Requested by 4c · project thread

Summary

Before: the pipeline encoded 4K60 continuously even with nobody connected; idle, rustkvm_app used ~56% of a core, ~46% of it in the encoder's output thread, for frames that were thrown away.

After: encoding pauses while no session is watching and resumes, with a forced keyframe, when a viewer's video track is attached.

How

  • pipeline.rs: a valve in front of the encoder, starting closed, in forward-sticky-events mode so caps still reach the encoder and video state, dynamic GOP and snapshots keep working. The screenshot probe moves to the valve's input so snapshots work while paused.
  • video.rs / webrtc.rs: attaching a session's video track opens the valve; detaching the last one closes it; a restarted pipeline picks up the current state.
  • docs/api.md: rustkvm_video_frames_total now counts only frames encoded for a viewer.

Testing

  • cargo +nightly fmt --all (CI)
  • cargo +nightly clippy --workspace --release --all-targets -- -D warnings (CI)
  • cargo +nightly test --workspace (CI)
  • Frontend touched: not applicable
  • Tested on an RK3588 device: a build with all three video branches (fast first frame, idle without viewer, H.264 High profile) was deployed to the NanoPC-T6 (health ok, 4K60, no WARN/ERROR at startup). First frame, timed from PeerConnection creation to the first keyframe: cold connects 131 and 101 ms; reconnect after a takeover ×6: 162, 102, 132, 105, 152, 113 ms.

Checklist

  • No #[allow(...)] suppressions and no new unwrap() / expect() in production paths
  • Hot paths stay zero-copy; periodic loops use MissedTickBehavior::Delay
  • Shared protocol types live in rkvm-proto
  • RPC method set changed → not applicable
  • Module tree or build invariants changed → not applicable

Part of a set of three video PRs (#60 and the H.264 High profile PR); merges onto dev together with them without conflicts.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PbdzY6PfT28goR4BhqdsXR


Generated by Claude Code

The pipeline encoded 4K60 continuously even with no session attached;
with no viewer rustkvm_app used ~56% of a core, ~46% of it in the
encoder's output thread, all for frames that were thrown away.

Put a valve in front of the encoder. It starts closed, opens when a
session's video track is attached (with a forced keyframe so the viewer
can decode immediately) and closes when the last one detaches; a
restarted pipeline picks up the current state. The valve forwards
sticky events, so the encoder stays negotiated and video state, the
dynamic GOP and the screenshot probe (moved to the valve's input) keep
working while paused. rustkvm_video_frames_total now only counts frames
encoded for a viewer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation area: video GStreamer, MPP encoding, WebRTC media labels Oct 12, 2026
@Rust-KVM Rust-KVM self-assigned this Oct 12, 2026
@Rust-KVM
Rust-KVM merged commit 4d665dd into dev Oct 12, 2026
8 checks passed
@Rust-KVM
Rust-KVM deleted the claude/video-idle-without-viewer branch October 12, 2026 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: video GStreamer, MPP encoding, WebRTC media documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants