Feature/egress h264 passthrough#1295
Open
curruwilla wants to merge 6 commits into
Open
Conversation
Adds an enable_video_passthrough deployment flag (default false). When set, track composite and participant egress with HLS segment output no longer force VideoDecoding/VideoEncoding at request time: the request becomes a pass-through candidate if it subscribes to at most one video track and carries no video encoding options (preset or advanced). Any file, stream, or image output, and any input codec that does not match the output codec at subscription time, falls back to the default decode+encode pipeline with an informative log. With the flag off, behavior is byte-for-byte identical to before. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
In pass-through mode there is no local encoder, so the GstForceKeyUnit events emitted by splitmuxsink (send-keyframe-requests=true) at segment boundaries died unanswered. The keyframe probe now installs an upstream event probe on the parser src pad when video decoding is disabled and bridges those events to the appwriter's existing PLI path, reusing its 1s throttle rather than adding a second one. Both the event receipt and the actual PLI send are logged with nanosecond timestamps so the egress->SFU->publisher keyframe delay can be measured in staging. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Without a decoder, the input-selector + videotestsrc fallback does not exist in pass-through mode: a muted or disconnected publisher stops the buffer flow and splitmuxsink stalls, freezing the HLS playlist and the viewer's player. The selector machinery is now also built in pass-through mode, operating on the encoded H.264 stream, with the videotestsrc replaced by a freeze injector: an auxiliary appsrc that caches the last keyframe seen on the real track and re-pushes it (2fps, do-timestamp PTS) while the fallback pad is selected. Since every injected frame is an IDR, splitmuxsink keeps cutting segments at the nominal duration while frozen. Switching uses the existing mute/unmute/removed callbacks - the appwriter's inactivity path (jitter buffer latency) already acts as the sample watchdog, and unmute re-selects the track pad, dropping delta frames until the PLI-requested keyframe arrives. A secondary stall detector (2x segment duration) logs if data stops without any mute event firing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#EXTINF entries already carry the measured duration of each closed fragment, so variable-length segments were mostly handled. But EXT-X-TARGETDURATION was declared as the nominal segment duration, and in pass-through mode real segments regularly exceed it (keyframe boundaries depend on the publisher GOP + PLI round trip), violating the HLS spec requirement that no segment's rounded duration exceed the declared target. Pass-through playlists now declare 2x the nominal duration, and any segment that still exceeds the declared target logs a warning. Audited remaining SegmentDuration uses: splitmuxsink max-size-time (split threshold, intentional), x264 vbv-buf-capacity (encoder path only), and upload queue sizing - none assume fixed real durations. Player note documented in README: window sizing by segment count (hls.js liveSyncDurationCount) sees slightly variable latency. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Failure-focused staging scenarios for the pass-through feature: without a decoder there is no loss concealment, so a corrupted bitstream reaches h264parse/mpegtsmux directly and must degrade gracefully. - publish.sh: synthetic OBS-like publisher (pre-encoded H.264, fixed 2s GOP + Opus) over WHIP bypass, with pause/resume/stop for mute and disconnect scenarios - egress.sh: participant egress with HLS output; --transcode adds a preset to force the decode+encode fallback on the same deployment - netem.sh: port-scoped packet loss on loopback (publisher<->ingress and SFU<->egress legs) - measure-cpu.sh: container + per-handler CPU sampling to CSV for the 30-minute pass-through vs transcode comparison - check-avsync.sh: per-segment audio/video first-PTS offset (transcoded audio vs pass-through video drift detection) README maps each script to the five scenarios and their pass criteria. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.