From b392c82ba98947442f2087685587b9df387392c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 11 Aug 2017 17:59:05 +0300 Subject: [PATCH] Use gstreamer-video API in appsrc example and make frame generation a bit more efficient --- Cargo.lock | 1 + examples/Cargo.toml | 1 + examples/src/bin/appsrc.rs | 41 ++++++++++++++++++++------------------ 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 67ab4b14e..470596304 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,6 +114,7 @@ dependencies = [ "gstreamer-app 0.1.0", "gstreamer-audio 0.1.0", "gstreamer-player 0.1.0", + "gstreamer-video 0.1.0", "gtk 0.1.3 (git+https://github.com/gtk-rs/gtk)", "send-cell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 4a4074a86..9acd7705b 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -8,6 +8,7 @@ glib = { version = "0.1.3", git = "https://github.com/gtk-rs/glib" } gstreamer = { path = "../gstreamer" } gstreamer-app = { path = "../gstreamer-app" } gstreamer-audio = { path = "../gstreamer-audio" } +gstreamer-video = { path = "../gstreamer-video" } gstreamer-player = { path = "../gstreamer-player", optional = true } gtk = { version = "0.1.3", git = "https://github.com/gtk-rs/gtk", features = ["v3_6"] } gio = { version = "0.1.3", git = "https://github.com/gtk-rs/gio" } diff --git a/examples/src/bin/appsrc.rs b/examples/src/bin/appsrc.rs index 174f4665e..fc4cf5824 100644 --- a/examples/src/bin/appsrc.rs +++ b/examples/src/bin/appsrc.rs @@ -2,6 +2,7 @@ extern crate gstreamer as gst; use gst::*; extern crate gstreamer_app as gst_app; use gst_app::*; +extern crate gstreamer_video as gst_video; extern crate glib; @@ -30,15 +31,13 @@ fn create_pipeline() -> Result<(Pipeline, AppSrc), utils::ExampleError> { let appsrc = src.clone() .dynamic_cast::() .expect("Source element is expected to be an appsrc!"); - appsrc.set_caps(&Caps::new_simple( - "video/x-raw", - &[ - ("format", &"BGRx"), - ("width", &(WIDTH as i32)), - ("height", &(HEIGHT as i32)), - ("framerate", &Fraction::new(2, 1)), - ], - )); + + let info = gst_video::VideoInfo::new(gst_video::VideoFormat::Bgrx, WIDTH as u32, HEIGHT as u32) + .fps(Fraction::new(2, 1)) + .build() + .unwrap(); + + appsrc.set_caps(&info.to_caps().unwrap()); appsrc.set_property_format(Format::Time); appsrc.set_max_bytes(1); appsrc.set_property_block(true); @@ -53,21 +52,25 @@ fn main_loop() -> Result<(), utils::ExampleError> { for i in 0..100 { println!("Producing frame {}", i); - // TODO: This is not very efficient - let mut vec = Vec::with_capacity(WIDTH * HEIGHT * 4); let r = if i % 2 == 0 { 0 } else { 255 }; let g = if i % 3 == 0 { 0 } else { 255 }; let b = if i % 5 == 0 { 0 } else { 255 }; - for _ in 0..(WIDTH * HEIGHT) { - vec.push(b); - vec.push(g); - vec.push(r); - vec.push(0); - } + let mut buffer = gst::Buffer::with_size(WIDTH * HEIGHT * 4).unwrap(); + { + let buffer = buffer.get_mut().unwrap(); + buffer.set_pts(i * 500_000_000); - let mut buffer = Buffer::from_vec(vec).expect("Unable to create a Buffer"); - buffer.get_mut().unwrap().set_pts(i * 500_000_000); + let mut data = buffer.map_writable().unwrap(); + + for p in data.as_mut_slice().chunks_mut(4) { + assert_eq!(p.len(), 4); + p[0] = b; + p[1] = g; + p[2] = r; + p[3] = 0; + } + } if appsrc.push_buffer(buffer) != FlowReturn::Ok { break;