diff --git a/examples/live.rs b/examples/live.rs index afb2ad1..53ad1d9 100644 --- a/examples/live.rs +++ b/examples/live.rs @@ -50,12 +50,19 @@ fn main() -> anyhow::Result<()> { const WIDTH: usize = 288; const HEIGHT: usize = 384; - let fourcc_repr = [ - b'Y', // | 0b10000000 - b'1', b'6', - b' ', // Note: not using b' ' | 0x80, (V4L2_PIX_FMT_Y16_BE) - // because VID_S_FMT ioctl returns EINVAL, so just swap the bytes here - ]; + let greyscale = !args.temperature || args.red_cutoff.is_none(); + let fourcc_repr = if greyscale { + [ + b'Y', // | 0b10000000 + b'1', b'6', + b' ', // Note: not using b' ' | 0x80, (V4L2_PIX_FMT_Y16_BE) + // because VID_S_FMT ioctl returns EINVAL, so just swap the bytes here + ] + } else { + // RGB32 is 4 bytes R, G, B, A + [b'R', b'G', b'B', b'4'] + }; + let bytes_per_pixel = if greyscale { 2 } else { 4 }; let fourcc = v4l::format::FourCC { repr: fourcc_repr }; let mut out = v4l::Device::with_path(output)?; // To find the fourcc code, use v4l2-ctl --list-formats-out /dev/video0 @@ -72,9 +79,13 @@ fn main() -> anyhow::Result<()> { // get a packet and print its bytes const PACKET_LEN: usize = 6972; + // input is grayscale 16 bits per pixel const FRAME_LEN: usize = WIDTH * HEIGHT * 2; let mut frame = [0u8; FRAME_LEN]; let mut len = 0; + let output_frame_len = WIDTH * HEIGHT * bytes_per_pixel; + let mut swapped_vec = vec![0u8; output_frame_len]; + let swapped = &mut swapped_vec; while let Ok(p) = cap.next_packet() { let data = p.data; if data.len() != PACKET_LEN { @@ -93,21 +104,26 @@ fn main() -> anyhow::Result<()> { if len == FRAME_LEN { // swap the bytes, we are using LE, not BE, 16 bit grayscale // possibly limitation of current v4l2loopback or v4l rust wrapper or libv4l2 - let mut swapped = [0u8; FRAME_LEN]; for i in 0..FRAME_LEN / 2 { let mut pixel = u16::from_be_bytes([frame[i * 2], frame[i * 2 + 1]]); - if args.temperature { - pixel = pixel_to_celcius(pixel); - if let Some(cutoff) = args.red_cutoff { - pixel = if pixel > (256.0 * cutoff) as u16 { - 50000 - } else { - 0 - } + if greyscale { + if args.temperature { + pixel = pixel_to_celcius(pixel); } + let pixel_swapped = pixel.to_le_bytes(); + swapped[i * 2..i * 2 + 2].copy_from_slice(&pixel_swapped); + } else { + pixel = pixel_to_celcius(pixel); + let cutoff = args.red_cutoff.unwrap(); + let r = if pixel > (256.0 * cutoff) as u16 { + 255 + } else { + 0 + }; + let g = frame[i * 2]; + let b = frame[i * 2 + 1]; + swapped[i * 4..i * 4 + 4].copy_from_slice(&[0, r, g, b]); } - let pixel_swapped = pixel.to_le_bytes(); - swapped[i * 2..i * 2 + 2].copy_from_slice(&pixel_swapped); } out.write_all(&swapped[..])?; }