mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2025-01-03 05:48:43 +00:00
Add simple appsrc example
This commit is contained in:
parent
23ef3c1f08
commit
dc640249ef
3 changed files with 102 additions and 0 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -84,6 +84,7 @@ dependencies = [
|
|||
"futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib 0.1.3 (git+https://github.com/gtk-rs/glib)",
|
||||
"gstreamer 0.1.0",
|
||||
"gstreamer-app 0.1.0",
|
||||
"gtk 0.1.3 (git+https://github.com/gtk-rs/gtk)",
|
||||
"tokio-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
|
|
@ -6,6 +6,7 @@ authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
|||
[dependencies]
|
||||
glib = { version = "0.1.3", git = "https://github.com/gtk-rs/glib" }
|
||||
gstreamer = { path = "../gstreamer" }
|
||||
gstreamer-app = { path = "../gstreamer-app" }
|
||||
gtk = { version = "0.1.3", git = "https://github.com/gtk-rs/gtk" }
|
||||
futures = "0.1"
|
||||
tokio-core = "0.1"
|
||||
|
|
100
examples/src/bin/appsrc.rs
Normal file
100
examples/src/bin/appsrc.rs
Normal file
|
@ -0,0 +1,100 @@
|
|||
extern crate gstreamer as gst;
|
||||
use gst::*;
|
||||
extern crate gstreamer_app as gst_app;
|
||||
use gst_app::*;
|
||||
|
||||
extern crate glib;
|
||||
use glib::*;
|
||||
|
||||
use std::u64;
|
||||
use std::thread;
|
||||
|
||||
const WIDTH: usize = 320;
|
||||
const HEIGHT: usize = 240;
|
||||
|
||||
fn main() {
|
||||
gst::init().unwrap();
|
||||
|
||||
let pipeline = gst::Pipeline::new(None);
|
||||
let src = gst::ElementFactory::make("appsrc", None).unwrap();
|
||||
let videoconvert = gst::ElementFactory::make("videoconvert", None).unwrap();
|
||||
let sink = gst::ElementFactory::make("autovideosink", None).unwrap();
|
||||
|
||||
pipeline.add_many(&[&src, &videoconvert, &sink]).unwrap();
|
||||
gst::Element::link_many(&[&src, &videoconvert, &sink]).unwrap();
|
||||
|
||||
let appsrc = src.clone().dynamic_cast::<AppSrc>().unwrap();
|
||||
appsrc.set_caps(&Caps::new_simple(
|
||||
"video/x-raw",
|
||||
&[
|
||||
(&"format", &"BGRx"),
|
||||
(&"width", &(WIDTH as i32)),
|
||||
(&"height", &(HEIGHT as i32)),
|
||||
(&"framerate", &Fraction::new(2, 1)),
|
||||
],
|
||||
));
|
||||
appsrc.set_property_format(Format::Time);
|
||||
appsrc.set_max_bytes(1);
|
||||
appsrc.set_property_block(true);
|
||||
|
||||
thread::spawn(move || {
|
||||
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..(320 * 240) {
|
||||
vec.push(b);
|
||||
vec.push(g);
|
||||
vec.push(r);
|
||||
vec.push(0);
|
||||
}
|
||||
|
||||
let mut buffer = Buffer::from_vec(vec).unwrap();
|
||||
buffer.get_mut().unwrap().set_pts(i * 500_000_000);
|
||||
|
||||
if appsrc.push_buffer(buffer) != FlowReturn::Ok {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
appsrc.end_of_stream();
|
||||
});
|
||||
|
||||
assert_ne!(
|
||||
pipeline.set_state(gst::State::Playing),
|
||||
gst::StateChangeReturn::Failure
|
||||
);
|
||||
|
||||
let bus = pipeline.get_bus().unwrap();
|
||||
|
||||
loop {
|
||||
let msg = match bus.timed_pop(u64::MAX) {
|
||||
None => break,
|
||||
Some(msg) => msg,
|
||||
};
|
||||
|
||||
match msg.view() {
|
||||
MessageView::Eos(..) => break,
|
||||
MessageView::Error(err) => {
|
||||
println!(
|
||||
"Error from {}: {} ({:?})",
|
||||
msg.get_src().get_path_string(),
|
||||
err.get_error(),
|
||||
err.get_debug()
|
||||
);
|
||||
break;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
assert_ne!(
|
||||
pipeline.set_state(gst::State::Null),
|
||||
gst::StateChangeReturn::Failure
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue