Skip to content

Commit

Permalink
rust: add pipeline video (#714)
Browse files Browse the repository at this point in the history
Signed-off-by: Ric Li <[email protected]>
  • Loading branch information
ricmli authored Jan 26, 2024
1 parent 1049aec commit db51136
Show file tree
Hide file tree
Showing 20 changed files with 574 additions and 361 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/ecosystem.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ jobs:
- name: Build Rust binding
run: |
cd rust/
cargo build --verbose
cargo clippy
cargo clippy --all-targets
cargo build --all-targets --verbose
cd imtl-sys
cargo build --verbose
cargo test --verbose
1 change: 1 addition & 0 deletions include/st20_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ enum st20_fmt {
ST20_FMT_YUV_420_8BIT, /**< 8-bit YUV 4:2:0 */
ST20_FMT_YUV_420_10BIT, /**< 10-bit YUV 4:2:0 */
ST20_FMT_YUV_420_12BIT, /**< 12-bit YUV 4:2:0 */
ST20_FMT_YUV_420_16BIT, /**< 16-bit YUV 4:2:0 */
ST20_FMT_RGB_8BIT, /**< 8-bit RGB */
ST20_FMT_RGB_10BIT, /**< 10-bit RGB */
ST20_FMT_RGB_12BIT, /**< 12-bit RGB */
Expand Down
6 changes: 1 addition & 5 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "imtl-rs"
version = "0.1.2"
version = "0.1.3"
edition = "2021"

[lib]
Expand All @@ -22,7 +22,3 @@ ctrlc = "3.4.2"
memmap2 = "0.9.3"
clap = { version = "4.4.13", features = ["derive"] }
sdl2 = "0.36.0"

[features]
convert = ["imtl-sys/convert"]
pipeline = ["imtl-sys/pipeline"]
9 changes: 8 additions & 1 deletion rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Add this to your `Cargo.toml`:

```toml
[dependencies]
imtl = "0.1.2"
imtl = "0.1.3"
```

## Example
Expand All @@ -28,3 +28,10 @@ cargo run --example video-rx -- --display --width 1920 --height 1080 --fps 30 --
# Check more options with --help
cargo run --example video-rx -- --help
```

USe pipeline API for internal color format conversion by adding '--input_format' for Tx and '--output_format' for Rx.

```bash
cargo run --example video-tx -- --yuv 422p10le.yuv --width 1920 --height 1080 --fps 30 --format yuv_422_10bit --input-format YUV422PLANAR10LE
cargo run --example video-rx -- --display --width 1920 --height 1080 --fps 30 --format yuv_422_10bit --output-format UYVY
```
41 changes: 24 additions & 17 deletions rust/examples/video-rx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ use sdl2::render::{Canvas, Texture};
use sdl2::video::Window;
use std::io::Write;
use std::net::Ipv4Addr;
use std::str::FromStr;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;

use imtl::mtl::{Flags, LogLevel, MtlBuilder};
use imtl::netdev::*;
use imtl::session::RtpSessionBuilder;
use imtl::video::{Fps, TransportFmt, VideoRxBuilder};
use imtl::video::{Fps, FrameFmt, TransportFmt, VideoRxBuilder};

/// Simple program to use IMTL to receive raw YUV frame and save the latest one to file
#[derive(Parser, Debug)]
Expand Down Expand Up @@ -43,24 +42,28 @@ struct Args {
height: u32,

/// Framerate
#[arg(long, default_value_t = String::from("60"))]
fps: String,
#[arg(long, default_value_t = Fps::P60)]
fps: Fps,

/// Pipeline output format
#[arg(long)]
output_format: Option<FrameFmt>,

/// Transport format
#[arg(long, default_value_t = String::from("yuv_422_10bit"))]
format: String,
#[arg(long, default_value_t = TransportFmt::Yuv422_10bit)]
format: TransportFmt,

/// Name of the YUV file
#[arg(long)]
yuv: Option<String>,

/// Enable display window, only for 'yuv_422_8bit' format
/// Enable display window, only support for 'UYVY' output/transport format
#[arg(long, default_value_t = false)]
display: bool,

/// Log level
#[arg(short, long, default_value_t = String::from("info"))]
log_level: String,
#[arg(short, long, default_value_t = LogLevel::Info)]
log_level: LogLevel,
}

fn main() -> Result<()> {
Expand Down Expand Up @@ -98,16 +101,13 @@ fn main() -> Result<()> {
let mtl = MtlBuilder::default()
.net_devs(net_devs)
.flags(flags)
.log_level(LogLevel::from_str(&args.log_level)?)
.log_level(args.log_level)
.build()
.unwrap()
.init()
.context("Failed to init mtl")?;

let net_dev0 = mtl.net_devs()[0].clone();

let session = RtpSessionBuilder::default()
.net_dev(net_dev0)
.ip(args.ip)
.port(args.port)
.payload_type(112u8)
Expand All @@ -116,11 +116,13 @@ fn main() -> Result<()> {
.context("Failed to add rtp session")?;

let mut video_rx = VideoRxBuilder::default()
.netdev_id(0)
.rtp_session(session)
.width(args.width)
.height(args.height)
.fps(Fps::from_str(&args.fps)?)
.t_fmt(TransportFmt::from_str(&args.format)?)
.fps(args.fps)
.output_fmt(args.output_format)
.t_fmt(args.format)
.build()
.unwrap()
.create(&mtl)
Expand Down Expand Up @@ -149,15 +151,20 @@ fn main() -> Result<()> {
)?);
}

let frame = vec![0u8; video_rx.frame_size()];
let frame_size = if let Some(output_format) = args.output_format {
output_format.frame_size(args.width, args.height)?
} else {
video_rx.frame_size()
};
let frame = vec![0u8; frame_size];

while running.load(Ordering::SeqCst) {
match video_rx.fill_new_frame(&frame) {
Ok(_) => {
if let (Some(ref mut texture), Some(ref mut canvas)) = (&mut texture, &mut canvas) {
texture.update(None, &frame, args.width as usize * 2)?;
canvas.clear();
canvas.copy(&texture, None, None).unwrap();
canvas.copy(texture, None, None).unwrap();
canvas.present();
}
}
Expand Down
41 changes: 24 additions & 17 deletions rust/examples/video-tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ use sdl2::pixels::PixelFormatEnum;
use sdl2::render::{Canvas, Texture};
use sdl2::video::Window;
use std::net::Ipv4Addr;
use std::str::FromStr;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;

use imtl::mtl::{Flags, LogLevel, MtlBuilder};
use imtl::netdev::*;
use imtl::session::RtpSessionBuilder;
use imtl::video::{Fps, TransportFmt, VideoTxBuilder};
use imtl::video::{Fps, FrameFmt, TransportFmt, VideoTxBuilder};

/// Simple program to use IMTL to send raw YUV frame from file
#[derive(Parser, Debug)]
Expand Down Expand Up @@ -42,12 +41,16 @@ struct Args {
height: u32,

/// Framerate
#[arg(long, default_value_t = String::from("60"))]
fps: String,
#[arg(long, default_value_t = Fps::P60)]
fps: Fps,

/// Pipeline input format
#[arg(long)]
input_format: Option<FrameFmt>,

/// Transport format
#[arg(long, default_value_t = String::from("yuv_422_10bit"))]
format: String,
#[arg(long, default_value_t = TransportFmt::Yuv422_10bit)]
format: TransportFmt,

/// Name of the YUV file
#[arg(long)]
Expand All @@ -58,8 +61,8 @@ struct Args {
display: bool,

/// Log level
#[arg(short, long, default_value_t = String::from("info"))]
log_level: String,
#[arg(short, long, default_value_t = LogLevel::Info)]
log_level: LogLevel,
}

fn main() -> Result<()> {
Expand Down Expand Up @@ -96,16 +99,13 @@ fn main() -> Result<()> {
let mtl = MtlBuilder::default()
.net_devs(net_devs)
.flags(flags)
.log_level(LogLevel::from_str(&args.log_level)?)
.log_level(args.log_level)
.build()
.unwrap()
.init()
.context("Failed to init mtl")?;

let net_dev0 = mtl.net_devs()[0].clone();

let session = RtpSessionBuilder::default()
.net_dev(net_dev0)
.ip(args.ip)
.port(args.port)
.payload_type(112u8)
Expand All @@ -114,11 +114,13 @@ fn main() -> Result<()> {
.context("Failed to add rtp session")?;

let mut video_tx = VideoTxBuilder::default()
.netdev_id(0)
.rtp_session(session)
.width(args.width)
.height(args.height)
.fps(Fps::from_str(&args.fps)?)
.t_fmt(TransportFmt::from_str(&args.format)?)
.fps(args.fps)
.input_fmt(args.input_format)
.t_fmt(args.format)
.build()
.unwrap()
.create(&mtl)
Expand Down Expand Up @@ -148,7 +150,12 @@ fn main() -> Result<()> {
)?);
}

let frames = yuv_file.chunks_exact(video_tx.frame_size());
let frame_size = if let Some(input_format) = args.input_format {
input_format.frame_size(args.width, args.height)?
} else {
video_tx.frame_size()
};
let frames = yuv_file.chunks_exact(frame_size);
if frames.len() == 0 {
bail!("No frames in file");
}
Expand All @@ -159,9 +166,9 @@ fn main() -> Result<()> {
match video_tx.fill_next_frame(frame) {
Ok(_) => {
if let (Some(ref mut texture), Some(ref mut canvas)) = (&mut texture, &mut canvas) {
texture.update(None, &frame, args.width as usize * 2)?;
texture.update(None, frame, args.width as usize * 2)?;
canvas.clear();
canvas.copy(&texture, None, None).unwrap();
canvas.copy(texture, None, None).unwrap();
canvas.present();
}
frame = frames.next().unwrap();
Expand Down
4 changes: 0 additions & 4 deletions rust/imtl-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,3 @@ rand = "0.8.5"
[build-dependencies]
bindgen = "0.69.1"
pkg-config = "0.3.27"

[features]
convert = []
pipeline = []
24 changes: 0 additions & 24 deletions rust/imtl-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,4 @@ fn main() {
bindings
.write_to_file(out_path.join("mtl_bindings.rs"))
.expect("Couldn't write bindings!");

if cfg!(feature = "convert") {
let bindings = bindgen::Builder::default()
.header("wrapper_convert.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.expect("Unable to generate bindings");

bindings
.write_to_file(out_path.join("mtl_convert_bindings.rs"))
.expect("Couldn't write bindings!");
}

if cfg!(feature = "pipeline") {
let bindings = bindgen::Builder::default()
.header("wrapper_pipeline.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.expect("Unable to generate bindings");

bindings
.write_to_file(out_path.join("mtl_pipeline_bindings.rs"))
.expect("Couldn't write bindings!");
}
}
47 changes: 0 additions & 47 deletions rust/imtl-sys/src/convert.rs

This file was deleted.

6 changes: 0 additions & 6 deletions rust/imtl-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@

include!(concat!(env!("OUT_DIR"), "/mtl_bindings.rs"));

#[cfg(feature = "convert")]
pub mod convert;

#[cfg(feature = "pipeline")]
pub mod pipeline;

#[cfg(test)]
mod tests {
use super::*;
Expand Down
1 change: 0 additions & 1 deletion rust/imtl-sys/src/pipeline.rs

This file was deleted.

4 changes: 3 additions & 1 deletion rust/imtl-sys/wrapper.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <mtl/mtl_api.h>
#include <mtl/st20_api.h>
#include <mtl/st_api.h>
#include <mtl/st_api.h>
#include <mtl/st_convert_api.h>
#include <mtl/st_pipeline_api.h>
1 change: 0 additions & 1 deletion rust/imtl-sys/wrapper_convert.h

This file was deleted.

1 change: 0 additions & 1 deletion rust/imtl-sys/wrapper_pipeline.h

This file was deleted.

Loading

0 comments on commit db51136

Please sign in to comment.