encoded_video_ingest (sderosa)#1048
Draft
stephen-derosa wants to merge 15 commits intomainfrom
Draft
Conversation
Introduce a video track source that accepts pre-encoded frames and a matching WebRTC encoder that forwards them unchanged, bypassing real encoding while preserving RTP, pacing, and congestion control. Per-track routing uses VideoFrame::id() as a side channel plus a global EncodedSourceRegistry. A LazyVideoEncoder picks between the passthrough and the real encoder on the first Encode() call. Single-layer only; callers manage simulcast with multiple sources.
Rust wrapper around webrtc-sys::EncodedVideoTrackSource. Adds the Encoded variant to RtcVideoSource, VideoCodec/EncodedFrameInfo types, and an EncodedVideoSourceObserver trait for keyframe-request callbacks from the C++ side. PeerConnectionFactory gains create_video_track_from_encoded_source.
Dispatch RtcVideoSource::Encoded through the new PCF path in LocalVideoTrack, and normalize TrackPublishOptions for encoded sources in LocalParticipant::publish_track — simulcast is forced off and the codec is pinned to the source's codec, with warnings on override.
Protobuf: * NewVideoSourceRequest.encoded_options + VideoSourceType.Encoded * CaptureEncodedVideoFrame request/response * EncodedVideoSourceEvent (keyframe requested, target bitrate) * VideoSourceInfo.encoded_source_id Server wires the new variant through FfiVideoSource, forwards observer callbacks to FfiEvent, and rejects capture_frame on encoded sources.
Encoded track source now scans incoming frames for SPS/PPS (H.264) or VPS/SPS/PPS (H.265), caches the latest seen set, and prepends them to any keyframe that arrives without inline params. This makes hardware encoders and camera feeds that only emit parameter sets on stream start usable as-is, without requiring producers to replicate them on every IDR. Producers still get a clear warning if the very first keyframe has no parameter sets and the cache is empty. The caller-supplied has_sps_pps flag becomes a hint only; the scanner is the source of truth so double-prepending is impossible. Also fix a stale `src->get()` reference left over from the SetRates refactor in PassthroughVideoEncoder::Encode.
d8c2cb1 to
286e052
Compare
9324761 to
9619309
Compare
Contributor
No changeset foundThis PR modifies the following packages but doesn't include a changeset: Directly changed:
Click here to create a changeset The link pre-populates a changeset file with If this change doesn't require a version bump, add the |
theomonnom
reviewed
Apr 29, 2026
…he same local publish synchronization
Contributor
|
This project involves API design and changes, and might touch lots of code. |
Contributor
|
I would think the team will need to align on the API designs and architecture. |
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.
Overview
This PR adds encoded video ingest support, allowing callers to publish pre-compressed video frames through a VIDEO_SOURCE_ENCODED source instead of sending raw frames through WebRTC’s normal encoder path.
It introduces the FFI/protobuf surface for creating encoded video sources and pushing encoded access units, wires those sources into WebRTC using a passthrough encoder, and forwards encoder-side feedback such as keyframe requests and target bitrate changes. For H.264/H.265, the native source also caches parameter sets and prepends them to keyframes when needed.
This solves the need to ingest externally encoded video without decoding and re-encoding it inside the SDK. To reproduce the original limitation, attempt to publish an already-encoded H.264/H.265/VPx/AV1 stream through the existing raw video source APIs; the SDK only accepted raw video frames and would route them through normal encoding.
Breaking changes
None.
MSRV
No MSRV changes.
Testing
Added/updated tests for:
Async
No changes to the runtime model were made, it uses the existing livekit video track mechanisms.
API Exampls
There are two producer APIs: the helper TCP ingest API for common “external encoder over TCP” workflows, and the base encoded source API for applications that already own demuxing, frame boundaries, and encoder control.
Helper API: EncodedTcpIngest
Use EncodedTcpIngest when the producer sends an encoded stream over TCP, for example from GStreamer.
Base API: NativeEncodedVideoSource
Use the base API when the application already has complete encoded access units and wants to push them directly.
Using the EncodedTcpIngest handles is a more complete tool for the user.