Skip to main content

Module software

Module software 

Source
Expand description

The CPU path: striped JPEG and whole-frame software H.264 (libx264 or OpenH264, by build), with per-region change detection. The CPU encode path: JPEG through turbojpeg in horizontal stripes, and H.264 through the build’s software encoder — libx264 with the gpl feature, Cisco OpenH264 without it (software_encoder) — as one whole-frame session.

JPEG frames are split into stripes coded in parallel via rayon; each stripe is hashed against the previous frame for change detection, and only dirty stripes are sent, statelessly. H.264 is one region covering the frame, its encoder kept across frames for inter-prediction, and both libraries emit the same wire framing. Both run the same per-region send and cleanup decision (encode_cpu).

Structs§

Coded 🔒
A frame x264 coded: its bits, the quantizer it was planned or held at, whether it was a key frame, and whether it was held (hold_quantizer).
EncodedStripe
One encoded stripe: the compressed bytes plus geometry and identity metadata.
FrameTiming
When a frame was captured and when its encode began and ended, as CLOCK_MONOTONIC nanoseconds, so a consumer can attribute a frame’s age to the host rather than the network or the decoder. An encoder leaves them zero; the capture that ran it stamps every stripe of the frame.
H264EncoderWrapper
One long-lived libx264 session for a frame, holding the raw x264_t handle alongside a mirror of its live parameters so the encoder can be retuned per frame instead of rebuilt.
InputLayout 🔒
Where each plane of an NV12 picture lies in its buffer: stride bytes a row, the first pixel offset bytes in, the buffer size bytes.
LastKey 🔒
A key frame’s first attempt (H264EncoderWrapper::aim_key): its bits, the quantizer it was planned or held at, the rate factor it was coded under, and whether it was held there.
Nv12Planes
A frame’s 8-bit 4:2:0 picture as NV12, a luma plane and an interleaved chroma one, laid out as an x264 session encodes it in place (x264_param_input_layout): each plane stride bytes a row within a buffer padded and aligned as x264’s own frames are, which x264 reads without copying it and writes the padding of. Tightly packed where the build has no x264, whose OpenH264 session takes no such picture.
StripeState
Everything one region of the frame must remember between frames: its reused buffers, its own live encoder, and the motion / paint-over / damage bookkeeping that drives its send decision.

Enums§

Input 🔒
The planes of a picture handed to x264: 4:2:0 or 4:4:4 planes of either depth, each its stride in bytes, or an 8-bit 4:2:0 picture as NV12.

Constants§

CBR_VBV_FRAMES
Frames of the target a constant-rate x264 session is given as its buffer where the caller names no video_vbv_multiplier. x264’s row-level control prices each row against a slice’s share of the buffer, so in the frame and a half the other encoders take it coded a moving 1080p window on a 2560x1600 screen at half its target: 1.95 Mbit/s of 4 at 30.4 dB, 2.96 in four frames, 3.52 at 34.6 dB in eight, 3.68 in fifteen, with no latency lost on a LAN (6.2 ms to draw and decode at 1.5 frames, 5.5 at 8). Eight frames hold a frame’s worst case to 133 ms of the rate at 60 fps, where fifteen added queue on a slow link for 4% more of the target.
CLEANUP_STAGGER_FRAMES 🔒
The frames the JPEG stripes’ cleanups of one still screen are spread over (encode_cpu).
CLEANUP_VBV_FRAMES 🔒
Frames of the target a constant-rate x264 session is given as its buffer while its cleanup runs through the rate control, or CLEANUP_FRAME_S of its rate where that is more: in the session’s buffer of a frame and a half x264’s row-level control prices a still screen’s whole residual against the buffer and coarsens the rows it names a fine quantizer for, so a screen of text at 2 Mbit/s at 1080p sat at 31 dB while the quantizer x264 planned read 19; in four it reached 46 dB in five seconds with no frame over a budget and a half. A row finer than its reference is priced at its whole intra cost against a slice’s share of the buffer: at 60 fps four frames held a 1080p page at 0.5 Mbit/s at quantizer 30 and 25-35 dB, or at 51 after a scroll, where 0.2 s reached 55.7 dB in 30 s.
JPEG_COMPRESSOR 🔒
Reused libjpeg-turbo compressor kept per worker thread to avoid paying a tjInitCompress/tjDestroy round trip for every stripe of every frame.
KEY_STEPS 🔒
Quantizer steps a halving of a capped CRF’s key frame is taken to need where it is aimed into the bucket’s room (H264EncoderWrapper::aim_key, fit_key), an encode at most aimed: text keeps 17 steps a halving between quantizers 12 and 35 (10.1 to 4.1 Mbit at 1280x720) where the quantizer’s own scale says 6, so an aim of 6 lands a second attempt past the room.
MAX_POOLED_BANDS 🔒
The most bands a conversion keeps a pool for (on_band_pool); more run on rayon’s global pool. A session converts in as many bands as its encode threads, eight at most (session::threads_up_to).
MAX_STRIPES 🔒
Most stripes a JPEG frame is cut into, whatever the encoder host’s core count.
MAX_STRIPE_CAPACITY
Upper bound on the horizontal stripes the CPU encoder splits a frame into, so the persistent per-stripe state vector can be reserved to a fixed capacity once, up front.
MIN_STRIPE_HEIGHT 🔒
No JPEG stripe is shorter than this many rows.
OWED_FINER 🔒
Quantizer steps finer than the paint-over one a capped CRF codes a block owed its paint-over at (ledger::BlockLedger::refresh_owed): a refinement’s, and two more, the predicted frame over a coarser picture landing short of it: a 720p page under a 4 Mbit/s peak came to 48.1 dB at one more and 49.4 at two, where the uncapped session’s paint-over leaves it at 48.5.
X264_REFRESH_FINER 🔒
Quality index steps finer than the session’s own a capped CRF refreshes its coarse blocks at (ledger::BlockLedger::refresh), one past ledger::REFRESH_FINER: refreshing a 720p page of text it coded at quantizer 51, x264 came to 37.7 dB three steps finer, 0.9 dB under the uncapped session’s on one to three slice threads, and to 38.5-38.6 four steps finer, within 0.3 dB of it on any, for 3 % more bytes. The uncapped session’s own picture moves with its slice threads (37.9-38.8 dB) rather than with the quantizers its scroll ends at, which are coarser than the refresh’s (26-29 against 22).
YUV10_SHIFT 🔒
The fixed-point scale of the 10-bit conversion’s coefficients.

Statics§

X264_OPEN_CLOSE_LOCK 🔒
Process-global lock that serializes libx264 encoder open/close, because those calls are not thread-safe yet several captures in one process open their sessions concurrently.

Functions§

acknowledge_reference
Every consumer holds frame frame_id, or where not held was sent it: OpenH264 confirms the long-term reference it marked there. x264 keeps none.
band_heights 🔒
The rows of each band a conversion of height rows splits into for up to bands threads (convert_to_yuv_mt): height / bands floored to an even number and at least 2, the last band taking the rest wherever fewer than a band and 2 rows would be left after it. One band where bands <= 1 or the image fits one.
cleanup_vbv_kbit 🔒
The buffer, in kbit, of an x264 session at bitrate_kbps while it is cleaned up (CLEANUP_VBV_FRAMES).
compute_stripe_geometries 🔒
Divide height into n contiguous regions as (y_start, height), by codec.
convert_to_nv12_mt 🔒
Convert a packed buffer, B,G,R,A or with rgba_input R,G,B,A, to 8-bit 4:2:0 BT.709 limited range as NV12, a luma plane and an interleaved chroma one strides bytes a row, the picture x264 encodes in place (Nv12Planes), in the bands convert_to_yuv_mt splits it into. Its samples are the ones convert_to_yuv_mt writes to I420, the chroma interleaved.
convert_to_yuv10_mt 🔒
Convert a packed BGRA/RGBA buffer to planar 10-bit YUV (4:2:0 or 4:4:4) in 16-bit samples, for the software encoders’ 10-bit sessions, across up to bands threads as convert_to_yuv_mt splits them.
convert_to_yuv_mt 🔒
Convert a packed BGRA/RGBA buffer to planar YUV (4:2:0 or 4:4:4) for the software H.264 encoders, spreading the conversion across up to bands threads so it never bottlenecks a frame.
encode_cpu
The CPU path’s per-frame entry point: decide per region whether it needs sending, and encode those as JPEG stripes across the rayon pool or as one H.264 frame through the build’s software encoder (libx264 or OpenH264).
encode_cpu_from
encode_cpu with the frame’s picture already converted (planes): an 8-bit 4:2:0 x264 session encodes it in place and leaves raw_pixels unread, which a capture converting straight from the screen’s memory never wrote. x264 reads the picture through the next encode (held_input).
fast_hash 🔒
Fast, non-cryptographic 64-bit content hash used only for in-memory change detection.
h264_bit_depth
The bits per sample the software H.264 session codes settings at: 10 where they ask for it and the build’s libx264 opens such a session, else 8.
held_input
The picture the software H.264 session still reads after its last encode returned (H264EncoderWrapper::held_input), which its owner leaves unchanged: None for any other session.
invalidate_reference
Leave frame frame_id and every frame after it out of the software H.264 session’s predictions: x264 through its reference window, OpenH264 from a long-term reference every consumer holds. False when the encoder cannot, and the caller codes a key frame instead.
ledger_frame 🔒
One frame of a region’s ledger, the region at rows y to y + height: the rectangles of changed that reach it, in its own coordinates, read with whether it changed (dirty) and whether its hash saw it change (observed, BlockLedger::frame_reported).
on_band_pool 🔒
Run convert, a conversion’s parallel bands, on a pool of bands threads: one a band count, built the first time a conversion asks for it and kept for the process.
qp_offset 🔒
What libx264 adds to a quantizer above 8 bits: its quantizer bounds, a frame’s forced quantizer, and the one it reports are all on a scale that starts six below zero for every bit past eight, while the rate factor is not. Added going in and taken off coming out, so a session’s quantizers mean what they do at 8 bits whatever its depth.
rate_control 🔒
The (bitrate_kbps, vbv_kbit) the software H.264 encoder is programmed with: the CBR target, with a buffer of CBR_VBV_FRAMES unless video_vbv_multiplier names one, or the peak of a CRF a positive video_vbv_multiplier caps. An uncapped CRF gets a buffer of 0.
release_input
Stop the software H.264 session reading the picture it holds (held_input).
stripe_count
How many horizontal regions a frame of height is split into, which is the choice of how much encode parallelism to spend on it.
stripes_at_once 🔒
Whether a frame’s n JPEG stripes are coded at once across the rayon pool, or one after another on the encode thread: one region, or a session without cpu_encode_threading, takes no other.
stripes_held_still
Whether a frame that holds still codes the software H.264 session at the paint-over quality instead of its own (encode_cpu): at a constant quality, where its cleanup falls due, its burst is held, or it keeps the quality it was cleaned up at. A constant rate holds none there.
stripes_hold_quantizer
Whether the software H.264 session holds its cleanup at the quantizer asked for: libx264 does under either rate control, and OpenH264 moves its quantizer only at a constant quality (Openh264Encoder::update_qp), so a session that holds none is cleaned up through its rate control (encode_cpu), never by a key frame, which that would starve.
x264_frame_rate 🔒
The rate an x264 session is opened at: the capture’s, or 30 frames per second where it names less than one.
x264_input_layout 🔒
The planes an 8-bit 4:2:0 x264 session of width x height encodes in place, which the library lays out for the CPU it runs on; None where the linked x264 is not patched to.
yuv10_coefficients 🔒
The BT.709 coefficients that take 8-bit R, G, B to 10-bit Y, Cb, Cr at full_range or limited range, scaled by 1 << YUV10_SHIFT: a row each for Y, Cb, and Cr, then the luma offset. The chroma offset is the 10-bit midpoint at either range.