Skip to content

Commit

Permalink
device: Unify struct and implement APIs as traits
Browse files Browse the repository at this point in the history
Signed-off-by: Christopher N. Hesse <raymanfx@gmail.com>
  • Loading branch information
raymanfx committed Nov 18, 2020
1 parent d4788cf commit 67ace34
Show file tree
Hide file tree
Showing 33 changed files with 674 additions and 746 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Enable either the `libv4l` or the `v4l2` backend by choosing the it as feature f
Below you can find a quick example usage of this crate. It introduces the basics necessary to do frame capturing from a streaming device (e.g. webcam).

```rust
use v4l::buffer::Type;
use v4l::io::stream::Capture;
use v4l::prelude::*;
use v4l::FourCC;
Expand Down Expand Up @@ -65,7 +66,7 @@ fn main() {

// Create the stream, which will internally 'allocate' (as in map) the
// number of requested buffers for us.
let mut stream = MmapStream::with_buffers(&mut dev, 4)
let mut stream = MmapStream::with_buffers(&mut dev, Type::VideoCapture, 4)
.expect("Failed to create buffer stream");

// At this point, the stream is ready and all buffers are setup.
Expand Down
2 changes: 1 addition & 1 deletion examples/capture_controls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn main() {
}
println!("Using device: {}\n", path);

let dev = CaptureDevice::with_path(path).expect("Failed to open capture device");
let dev = Device::with_path(path).expect("Failed to open capture device");
let controls = dev.query_controls().expect("Failed to query controls");

for control in controls {
Expand Down
3 changes: 2 additions & 1 deletion examples/capture_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ extern crate v4l;

use clap::{App, Arg};
use v4l::prelude::*;
use v4l::video::Capture;

fn main() {
let matches = App::new("v4l device")
Expand All @@ -29,7 +30,7 @@ fn main() {
}
println!("Using device: {}\n", path);

let dev = CaptureDevice::with_path(path).expect("Failed to open capture device");
let dev = Device::with_path(path).expect("Failed to open capture device");
let format = dev.format().expect("Failed to get format");
let params = dev.params().expect("Failed to get parameters");
println!("Active format:\n{}", format);
Expand Down
3 changes: 2 additions & 1 deletion examples/capture_frameintervals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ extern crate v4l;

use clap::{App, Arg};
use v4l::prelude::*;
use v4l::video::Capture;

fn main() {
let matches = App::new("v4l device")
Expand All @@ -29,7 +30,7 @@ fn main() {
}
println!("Using device: {}\n", path);

let dev = CaptureDevice::with_path(path).expect("Failed to open capture device");
let dev = Device::with_path(path).expect("Failed to open capture device");
let format = dev.format().expect("Failed to get format");
let frameintervals = dev
.enum_frameintervals(format.fourcc, format.width, format.height)
Expand Down
3 changes: 2 additions & 1 deletion examples/capture_framesizes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ extern crate v4l;

use clap::{App, Arg};
use v4l::prelude::*;
use v4l::video::Capture;

fn main() {
let matches = App::new("v4l device")
Expand All @@ -29,7 +30,7 @@ fn main() {
}
println!("Using device: {}\n", path);

let dev = CaptureDevice::with_path(path).expect("Failed to open capture device");
let dev = Device::with_path(path).expect("Failed to open capture device");
let format = dev.format().expect("Failed to get format");
let framesizes = dev
.enum_framesizes(format.fourcc)
Expand Down
12 changes: 6 additions & 6 deletions examples/forward_frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ extern crate v4l;

use clap::{App, Arg};
use std::io::Write;
use v4l::buffer::Type;
use v4l::io::stream::Capture;
use v4l::prelude::*;
use v4l::video::Capture as _;

fn main() {
let matches = App::new("v4l device")
Expand Down Expand Up @@ -38,8 +40,7 @@ fn main() {
capture_path = format!("/dev/video{}", capture_path);
}
println!("Using capture device: {}", capture_path);
let capture_dev =
CaptureDevice::with_path(capture_path).expect("Failed to open capture device");
let capture_dev = Device::with_path(capture_path).expect("Failed to open capture device");

// Determine which output device to use
let mut output_path: String = matches
Expand All @@ -50,8 +51,7 @@ fn main() {
output_path = format!("/dev/video{}", output_path);
}
println!("Using output device: {}", output_path);
let mut output_dev =
OutputDevice::with_path(output_path).expect("Failed to open output device");
let mut output_dev = Device::with_path(output_path).expect("Failed to open output device");

// Set the output's format to the same as the capture's
let format = capture_dev.format().unwrap();
Expand All @@ -60,8 +60,8 @@ fn main() {
.expect("Failed to set format of output device");

// Setup a buffer stream, grab a frame, and write it to the output
let mut stream =
MmapStream::with_buffers(&capture_dev, 1).expect("Failed to create buffer stream");
let mut stream = MmapStream::with_buffers(&capture_dev, Type::VideoCapture, 1)
.expect("Failed to create buffer stream");
let buf = stream.next().expect("Failed to capture buffer");
output_dev
.write_all(&*buf)
Expand Down
12 changes: 6 additions & 6 deletions examples/forward_video.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ extern crate v4l;

use clap::{App, Arg};
use std::io::Write;
use v4l::buffer::Type;
use v4l::io::stream::Capture;
use v4l::prelude::*;
use v4l::video::Capture as _;

fn main() {
let matches = App::new("v4l device")
Expand Down Expand Up @@ -38,8 +40,7 @@ fn main() {
capture_path = format!("/dev/video{}", capture_path);
}
println!("Using capture device: {}", capture_path);
let capture_dev =
CaptureDevice::with_path(capture_path).expect("Failed to open capture device");
let capture_dev = Device::with_path(capture_path).expect("Failed to open capture device");

// Determine which output device to use
let mut output_path: String = matches
Expand All @@ -50,8 +51,7 @@ fn main() {
output_path = format!("/dev/video{}", output_path);
}
println!("Using output device: {}", output_path);
let mut output_dev =
OutputDevice::with_path(output_path).expect("Failed to open output device");
let mut output_dev = Device::with_path(output_path).expect("Failed to open output device");

// Set the output's format to the same as the capture's
let format = capture_dev.format().unwrap();
Expand All @@ -60,8 +60,8 @@ fn main() {
.expect("Failed to set format of output device");

// Setup a buffer stream, grab a frame, and write it to the output
let mut stream =
MmapStream::with_buffers(&capture_dev, 1).expect("Failed to create buffer stream");
let mut stream = MmapStream::with_buffers(&capture_dev, Type::VideoCapture, 1)
.expect("Failed to create buffer stream");

loop {
let buf = stream.next().expect("Failed to capture buffer");
Expand Down
12 changes: 7 additions & 5 deletions examples/glium.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ use glium::{implement_vertex, program, uniform};
use std::sync::{mpsc, RwLock};
use std::thread;
use std::time::Instant;
use v4l::capture;
use v4l::buffer::Type;
use v4l::io::stream::Capture;
use v4l::prelude::*;
use v4l::video::capture::Parameters;
use v4l::video::Capture as _;
use v4l::{Format, FourCC};

fn main() {
Expand Down Expand Up @@ -51,9 +53,9 @@ fn main() {
let buffers = buffers.parse::<u32>().unwrap();

let mut format: Format;
let params: capture::Parameters;
let params: Parameters;

let dev = RwLock::new(CaptureDevice::with_path(path.clone()).expect("Failed to open device"));
let dev = RwLock::new(Device::with_path(path.clone()).expect("Failed to open device"));
{
let mut dev = dev.write().unwrap();
format = dev.format().expect("Failed to get format");
Expand Down Expand Up @@ -146,8 +148,8 @@ fn main() {
let mut dev = dev.write().unwrap();

// Setup a buffer stream
let mut stream =
MmapStream::with_buffers(&mut *dev, buffers).expect("Failed to create buffer stream");
let mut stream = MmapStream::with_buffers(&mut *dev, Type::VideoCapture, buffers)
.expect("Failed to create buffer stream");

loop {
let buf = stream.next().expect("Failed to capture buffer");
Expand Down
2 changes: 1 addition & 1 deletion examples/output_controls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn main() {
}
println!("Using device: {}\n", path);

let dev = OutputDevice::with_path(path).expect("Failed to open output device");
let dev = Device::with_path(path).expect("Failed to open output device");
let controls = dev.query_controls().expect("Failed to query controls");

for control in controls {
Expand Down
3 changes: 2 additions & 1 deletion examples/output_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ extern crate v4l;

use clap::{App, Arg};
use v4l::prelude::*;
use v4l::video::Capture;

fn main() {
let matches = App::new("v4l device")
Expand All @@ -29,7 +30,7 @@ fn main() {
}
println!("Using device: {}\n", path);

let dev = OutputDevice::with_path(path).expect("Failed to open output device");
let dev = Device::with_path(path).expect("Failed to open output device");
let format = dev.format().expect("Failed to get format");
let params = dev.params().expect("Failed to get parameters");
println!("Active format:\n{}", format);
Expand Down
3 changes: 2 additions & 1 deletion examples/output_frameintervals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ extern crate v4l;

use clap::{App, Arg};
use v4l::prelude::*;
use v4l::video::Capture;

fn main() {
let matches = App::new("v4l device")
Expand All @@ -29,7 +30,7 @@ fn main() {
}
println!("Using device: {}\n", path);

let dev = OutputDevice::with_path(path).expect("Failed to open output device");
let dev = Device::with_path(path).expect("Failed to open output device");
let format = dev.format().expect("Failed to get format");
let frameintervals = dev
.enum_frameintervals(format.fourcc, format.width, format.height)
Expand Down
3 changes: 2 additions & 1 deletion examples/output_framesizes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ extern crate v4l;

use clap::{App, Arg};
use v4l::prelude::*;
use v4l::video::Capture;

fn main() {
let matches = App::new("v4l device")
Expand All @@ -29,7 +30,7 @@ fn main() {
}
println!("Using device: {}\n", path);

let dev = OutputDevice::with_path(path).expect("Failed to open output device");
let dev = Device::with_path(path).expect("Failed to open output device");
let format = dev.format().expect("Failed to get format");
let framesizes = dev
.enum_framesizes(format.fourcc)
Expand Down
8 changes: 5 additions & 3 deletions examples/stream_capture_mmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ extern crate v4l;

use clap::{App, Arg};
use std::time::Instant;
use v4l::buffer::Type;
use v4l::io::stream::Capture;
use v4l::prelude::*;
use v4l::video::Capture as _;

fn main() {
let matches = App::new("v4l mmap")
Expand Down Expand Up @@ -55,15 +57,15 @@ fn main() {
let buffers = matches.value_of("buffers").unwrap_or("4").to_string();
let buffers = buffers.parse::<u32>().unwrap();

let mut dev = CaptureDevice::with_path(path).expect("Failed to open device");
let mut dev = Device::with_path(path).expect("Failed to open device");
let format = dev.format().expect("Failed to get format");
let params = dev.params().expect("Failed to get parameters");
println!("Active format:\n{}", format);
println!("Active parameters:\n{}", params);

// Setup a buffer stream and grab a frame, then print its data
let mut stream =
MmapStream::with_buffers(&mut dev, buffers).expect("Failed to create buffer stream");
let mut stream = MmapStream::with_buffers(&mut dev, Type::VideoCapture, buffers)
.expect("Failed to create buffer stream");

// warmup
stream.next().expect("Failed to capture buffer");
Expand Down
8 changes: 5 additions & 3 deletions examples/stream_capture_userptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ extern crate v4l;

use clap::{App, Arg};
use std::time::Instant;
use v4l::buffer::Type;
use v4l::io::stream::Capture;
use v4l::prelude::*;
use v4l::video::Capture as _;

fn main() {
let matches = App::new("v4l userptr")
Expand Down Expand Up @@ -55,15 +57,15 @@ fn main() {
let buffers = matches.value_of("buffers").unwrap_or("4").to_string();
let buffers = buffers.parse::<u32>().unwrap();

let mut dev = CaptureDevice::with_path(path).expect("Failed to open device");
let mut dev = Device::with_path(path).expect("Failed to open device");
let format = dev.format().expect("Failed to get format");
let params = dev.params().expect("Failed to get parameters");
println!("Active format:\n{}", format);
println!("Active parameters:\n{}", params);

// Setup a buffer stream and grab a frame, then print its data
let mut stream =
UserptrStream::with_buffers(&mut dev, buffers).expect("Failed to create buffer stream");
let mut stream = UserptrStream::with_buffers(&mut dev, Type::VideoCapture, buffers)
.expect("Failed to create buffer stream");

// warmup
stream.next().expect("Failed to capture buffer");
Expand Down
32 changes: 17 additions & 15 deletions examples/stream_forward_mmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ use std::io;
use std::time::Instant;

use clap::{App, Arg};
use v4l::io::stream::{Capture, Output};
use v4l::buffer::Type;
use v4l::io::stream::{Capture as CaptureStream, Output as OutputStream};
use v4l::prelude::*;
use v4l::video::{Capture, Output};

fn main() -> io::Result<()> {
let matches = App::new("v4l mmap")
Expand Down Expand Up @@ -75,22 +77,22 @@ fn main() -> io::Result<()> {
let buffers = matches.value_of("buffers").unwrap_or("4").to_string();
let buffers = buffers.parse::<u32>().unwrap();

let mut cap = CaptureDevice::with_path(source)?;
let mut cap = Device::with_path(source)?;
println!("Active cap capabilities:\n{}", cap.query_caps()?);
println!("Active cap format:\n{}", cap.format()?);
println!("Active cap parameters:\n{}", cap.params()?);
println!("Active cap format:\n{}", Capture::format(&cap)?);
println!("Active cap parameters:\n{}", Capture::params(&cap)?);

let mut out = OutputDevice::with_path(sink)?;
let mut out = Device::with_path(sink)?;
println!("Active out capabilities:\n{}", out.query_caps()?);
println!("Active out format:\n{}", out.format()?);
println!("Active out parameters:\n{}", out.params()?);
println!("Active out format:\n{}", Output::format(&out)?);
println!("Active out parameters:\n{}", Output::params(&out)?);

// BEWARE OF DRAGONS
// Buggy drivers (such as v4l2loopback) only set the v4l2 buffer size (length field) once
// a format is set, even though a valid format appears to be available when doing VIDIOC_G_FMT!
// In our case, we just (try to) enforce the source format on the sink device.
let source_fmt = cap.format()?;
let sink_fmt = out.set_format(&source_fmt)?;
let source_fmt = Capture::format(&cap)?;
let sink_fmt = Output::set_format(&mut out, &source_fmt)?;
if source_fmt.width != sink_fmt.width
|| source_fmt.height != sink_fmt.height
|| source_fmt.fourcc != sink_fmt.fourcc
Expand All @@ -100,22 +102,22 @@ fn main() -> io::Result<()> {
"failed to enforce source format on sink device",
));
}
println!("New out format:\n{}", out.format()?);
println!("New out format:\n{}", Output::format(&out)?);

// Setup a buffer stream and grab a frame, then print its data
let mut cap_stream = MmapStream::with_buffers(&mut cap, buffers)?;
let mut cap_stream = MmapStream::with_buffers(&mut cap, Type::VideoCapture, buffers)?;

let mut out_stream = MmapStream::with_buffers(&mut out, buffers)?;
let mut out_stream = MmapStream::with_buffers(&mut out, Type::VideoOutput, buffers)?;

// warmup
Capture::next(&mut cap_stream)?;
CaptureStream::next(&mut cap_stream)?;

let start = Instant::now();
let mut megabytes_ps: f64 = 0.0;
for i in 0..count {
let t0 = Instant::now();
let buf = Capture::next(&mut cap_stream)?;
Output::next(&mut out_stream, buf.clone())?;
let buf = CaptureStream::next(&mut cap_stream)?;
OutputStream::next(&mut out_stream, buf.clone())?;
let duration_us = t0.elapsed().as_micros();

let cur = buf.len() as f64 / 1_048_576.0 * 1_000_000.0 / duration_us as f64;
Expand Down
Loading

0 comments on commit 67ace34

Please sign in to comment.