-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathoutput-write.rs
More file actions
98 lines (82 loc) · 2.5 KB
/
output-write.rs
File metadata and controls
98 lines (82 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//! Writes test data to a video output device.
//!
//! Uses the [`std::io::Write`] implementation of [`linuxvideo::VideoOutputDevice`].
use std::{
env,
io::Write,
path::Path,
thread,
time::{Duration, Instant},
};
use itertools::Itertools;
use linuxvideo::{
format::{PixFormat, Pixelformat},
CapabilityFlags, Device,
};
const WIDTH: u32 = 1920;
const HEIGHT: u32 = 1080;
const PIXFMT: Pixelformat = Pixelformat::ABGR32;
const RED: [u8; 4] = [0, 0, 0xff, 0xff];
const GREEN: [u8; 4] = [0, 0xff, 0, 0xff];
const BLUE: [u8; 4] = [0xff, 0, 0, 0xff];
const TRANSPARENT: [u8; 4] = [0, 0xff, 0xff, 120];
fn main() -> linuxvideo::Result<()> {
let mut args = env::args_os().skip(1);
let path = match args.next() {
Some(path) => path,
None => {
println!("usage: write <device>");
std::process::exit(1);
}
};
let device = Device::open(Path::new(&path))?;
if !device
.capabilities()?
.device_capabilities()
.contains(CapabilityFlags::VIDEO_OUTPUT)
{
panic!("cannot write data: selected device does not support `VIDEO_OUTPUT` capability");
}
let mut output = device.video_output(PixFormat::new(WIDTH, HEIGHT, PIXFMT))?;
let fmt = output.format();
println!("set format: {:?}", fmt);
if fmt.pixelformat() != PIXFMT {
panic!("driver does not support the requested parameters");
}
let mut image = (0..fmt.height())
.cartesian_product(0..fmt.width())
.flat_map(|(y, x)| {
if x == y {
RED
} else if x < 5 || x > fmt.width() - 5 {
GREEN
} else if y < 5 || y > fmt.height() - 5 {
BLUE
} else {
TRANSPARENT
}
})
.collect::<Vec<_>>();
assert_eq!(
image.len(),
fmt.width() as usize * fmt.height() as usize * 4
);
assert!(image.len() <= fmt.size_image() as usize);
image.resize(fmt.size_image() as usize, 0xff);
println!("output started");
let mut frames = 0;
let mut time = Instant::now();
loop {
output.write(&image)?;
frames += 1;
print!(".");
std::io::stdout().flush().ok();
if time.elapsed() >= Duration::from_secs(1) {
println!(" {} FPS", frames);
time = Instant::now();
frames = 0;
}
// This can run at 170000 FPS, so sleep a bit to limit that.
thread::sleep(Duration::from_millis(5));
}
}