in src/convert_image/neon.rs [420:509]
fn rgb_nv12<const SAMPLER: usize, const DEPTH: usize, const COLORIMETRY: usize>(
width: u32,
height: u32,
_last_src_plane: usize,
src_strides: &[usize],
src_buffers: &[&[u8]],
last_dst_plane: usize,
dst_strides: &[usize],
dst_buffers: &mut [&mut [u8]],
) -> bool {
// Degenerate case, trivially accept
if width == 0 || height == 0 {
return true;
}
// Check there are sufficient strides and buffers
if src_strides.is_empty()
|| src_buffers.is_empty()
|| last_dst_plane >= dst_strides.len()
|| last_dst_plane >= dst_buffers.len()
{
return false;
}
let w = width as usize;
let h = height as usize;
let ch = h / 2;
let rgb_stride = DEPTH * w;
// Compute actual strides
let src_stride = compute_stride(src_strides[0], rgb_stride);
let dst_strides = (
compute_stride(dst_strides[0], w),
compute_stride(dst_strides[last_dst_plane], w),
);
// Ensure there is sufficient data in the buffers according
// to the image dimensions and computed strides
let src_buffer = &src_buffers[0];
if last_dst_plane == 0 && dst_buffers[last_dst_plane].len() < dst_strides.0 * h {
return false;
}
let (y_plane, uv_plane) = if last_dst_plane == 0 {
dst_buffers[last_dst_plane].split_at_mut(dst_strides.0 * h)
} else {
let (y_plane, uv_plane) = dst_buffers.split_at_mut(last_dst_plane);
(&mut *y_plane[0], &mut *uv_plane[0])
};
if out_of_bounds(src_buffer.len(), src_stride, h - 1, rgb_stride)
|| out_of_bounds(y_plane.len(), dst_strides.0, h - 1, w)
|| out_of_bounds(uv_plane.len(), dst_strides.1, ch - 1, w)
{
return false;
}
// Process vector part and scalar one
let vector_part = lower_multiple_of_pot(w, RGB_TO_YUV_WAVES);
let scalar_part = w - vector_part;
if vector_part > 0 {
unsafe {
rgb_to_nv12_neon::<SAMPLER, DEPTH, COLORIMETRY>(
vector_part,
h,
src_stride,
src_buffer,
dst_strides,
&mut (y_plane, uv_plane),
);
}
}
if scalar_part > 0 {
let x = vector_part;
let sx = x * DEPTH;
x86::rgb_to_nv12::<SAMPLER, DEPTH, COLORIMETRY>(
scalar_part,
h,
src_stride,
&src_buffer[sx..],
dst_strides,
&mut (&mut y_plane[x..], &mut uv_plane[x..]),
);
}
true
}