Skip to main content

convert_to_yuv_mt

Function convert_to_yuv_mt 

Source
pub(crate) fn convert_to_yuv_mt(
    src: &[u8],
    src_stride: u32,
    width: usize,
    height: usize,
    rgba_input: bool,
    i444: bool,
    full_range: bool,
    bt601: bool,
    y_buf: &mut [u8],
    u_buf: &mut [u8],
    v_buf: &mut [u8],
    strides: (usize, usize),
    bands: usize,
) -> Result<(), YuvError>
Expand description

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.

Why the band split exists. Color conversion is a non-trivial slice of per-frame CPU, and a whole-frame session (OpenH264, or a session of another codec) would otherwise convert its entire image on one thread and stall the frame there. Splitting into horizontal bands spreads that conversion over the rayon pool. The cut is horizontal because YUV planes are row-major, so a horizontal boundary yields contiguous, non-overlapping plane sub-slices with no per-row seam bookkeeping.

  1. Plane strides: strides gives the Y and chroma row pitches of the output planes (tightly packed for the session’s own buffers, padded for an AVFrame); the chroma planes are width wide for 4:4:4 (i444 == true) or width / 2 for 4:2:0. rgba_input selects the source byte order and i444 the subsampling; full_range selects the signal range, Full for the 4:4:4 stream x264 and x265 declare and Limited for everything else. The matrix is BT.709, whose primaries and transfer the sRGB desktop source already carries, unless bt601 marks a codec whose bitstream can name no other matrix (VP8). Every encoder declares the matrix it was fed. All four yuv crate routines run in the Fast conversion mode.
  2. Band split: band_h is height / bands floored to an even number and at least 2 rows (a band under 2 rows is not worth a task). Keeping band boundaries even ensures a 4:2:0 chroma pair never straddles a seam. When bands <= 1 or the whole image fits one band, the conversion runs on the calling thread in place.
  3. Parallel bands: otherwise src and the three output planes are carved into contiguous per-band sub-slices (chroma rows scaled by uv_rows — full height for 4:4:4, half for 4:2:0) and converted on the pool of bands threads (on_band_pool), whose workers already exist, so a frame spawns no thread. The final band absorbs any leftover rows, taking all remaining rows whenever fewer than band_h + 2 are left. The first error wins.