forked from mirrors/gstreamer-rs
Move gtksink example to GtkApplication
And have an example for using GTK objects from closures that require Send
This commit is contained in:
parent
c9423471b0
commit
0dcf9c2be7
3 changed files with 67 additions and 11 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -100,6 +100,7 @@ name = "examples"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gio 0.1.3 (git+https://github.com/gtk-rs/gio)",
|
||||||
"glib 0.1.3 (git+https://github.com/gtk-rs/glib)",
|
"glib 0.1.3 (git+https://github.com/gtk-rs/glib)",
|
||||||
"gstreamer 0.1.0",
|
"gstreamer 0.1.0",
|
||||||
"gstreamer-app 0.1.0",
|
"gstreamer-app 0.1.0",
|
||||||
|
|
|
@ -7,7 +7,8 @@ authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
||||||
glib = { version = "0.1.3", git = "https://github.com/gtk-rs/glib" }
|
glib = { version = "0.1.3", git = "https://github.com/gtk-rs/glib" }
|
||||||
gstreamer = { path = "../gstreamer" }
|
gstreamer = { path = "../gstreamer" }
|
||||||
gstreamer-app = { path = "../gstreamer-app" }
|
gstreamer-app = { path = "../gstreamer-app" }
|
||||||
gtk = { version = "0.1.3", git = "https://github.com/gtk-rs/gtk" }
|
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" }
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
tokio-core = "0.1"
|
tokio-core = "0.1"
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,48 @@ use gst::*;
|
||||||
extern crate glib;
|
extern crate glib;
|
||||||
use glib::*;
|
use glib::*;
|
||||||
|
|
||||||
|
extern crate gio;
|
||||||
|
use gio::ApplicationExt;
|
||||||
|
|
||||||
extern crate gtk;
|
extern crate gtk;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{Window, WindowType};
|
use gtk::{Window, WindowType};
|
||||||
|
use gtk::ApplicationExt as GtkApplicationExt;
|
||||||
|
|
||||||
fn main() {
|
use std::env;
|
||||||
gst::init().unwrap();
|
|
||||||
gtk::init().unwrap();
|
|
||||||
|
|
||||||
|
// Workaround for GTK objects not implementing Send (nor Sync)
|
||||||
|
// but us having to use them in a closure that requires Send
|
||||||
|
use std::thread;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct SendCell<T> {
|
||||||
|
data: T,
|
||||||
|
thread_id: thread::ThreadId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> SendCell<T> {
|
||||||
|
pub fn new(data: T) -> Self {
|
||||||
|
SendCell {
|
||||||
|
data: data,
|
||||||
|
thread_id: thread::current().id(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Deref for SendCell<T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &T {
|
||||||
|
assert_eq!(thread::current().id(), self.thread_id);
|
||||||
|
&self.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T> Send for SendCell<T> {}
|
||||||
|
|
||||||
|
fn create_ui(app: >k::Application) {
|
||||||
let pipeline = Pipeline::new(None);
|
let pipeline = Pipeline::new(None);
|
||||||
let src = ElementFactory::make("videotestsrc", None).unwrap();
|
let src = ElementFactory::make("videotestsrc", None).unwrap();
|
||||||
let (sink, widget) = if let Some(gtkglsink) = ElementFactory::make("gtkglsink", None) {
|
let (sink, widget) = if let Some(gtkglsink) = ElementFactory::make("gtkglsink", None) {
|
||||||
|
@ -40,6 +74,8 @@ fn main() {
|
||||||
window.add(&vbox);
|
window.add(&vbox);
|
||||||
window.show_all();
|
window.show_all();
|
||||||
|
|
||||||
|
app.add_window(&window);
|
||||||
|
|
||||||
let pipeline_clone = pipeline.clone();
|
let pipeline_clone = pipeline.clone();
|
||||||
gtk::timeout_add(500, move || {
|
gtk::timeout_add(500, move || {
|
||||||
let pipeline = &pipeline_clone;
|
let pipeline = &pipeline_clone;
|
||||||
|
@ -66,8 +102,10 @@ fn main() {
|
||||||
glib::Continue(true)
|
glib::Continue(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
window.connect_delete_event(|_, _| {
|
let app_clone = app.clone();
|
||||||
gtk::main_quit();
|
window.connect_delete_event(move |_, _| {
|
||||||
|
let app = &app_clone;
|
||||||
|
app.quit();
|
||||||
Inhibit(false)
|
Inhibit(false)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -76,7 +114,9 @@ fn main() {
|
||||||
let ret = pipeline.set_state(gst::State::Playing);
|
let ret = pipeline.set_state(gst::State::Playing);
|
||||||
assert_ne!(ret, gst::StateChangeReturn::Failure);
|
assert_ne!(ret, gst::StateChangeReturn::Failure);
|
||||||
|
|
||||||
|
let app_clone = SendCell::new(app.clone());
|
||||||
bus.add_watch(move |_, msg| {
|
bus.add_watch(move |_, msg| {
|
||||||
|
let app = &app_clone;
|
||||||
match msg.view() {
|
match msg.view() {
|
||||||
MessageView::Eos(..) => gtk::main_quit(),
|
MessageView::Eos(..) => gtk::main_quit(),
|
||||||
MessageView::Error(err) => {
|
MessageView::Error(err) => {
|
||||||
|
@ -86,7 +126,7 @@ fn main() {
|
||||||
err.get_error(),
|
err.get_error(),
|
||||||
err.get_debug()
|
err.get_debug()
|
||||||
);
|
);
|
||||||
gtk::main_quit();
|
app.quit();
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
|
@ -94,8 +134,22 @@ fn main() {
|
||||||
glib::Continue(true)
|
glib::Continue(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
gtk::main();
|
let pipeline_clone = pipeline.clone();
|
||||||
|
app.connect_shutdown(move |_| {
|
||||||
let ret = pipeline.set_state(gst::State::Null);
|
let pipeline = &pipeline_clone;
|
||||||
assert_ne!(ret, gst::StateChangeReturn::Failure);
|
let ret = pipeline.set_state(gst::State::Null);
|
||||||
|
assert_ne!(ret, gst::StateChangeReturn::Failure);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
gtk::init().unwrap();
|
||||||
|
|
||||||
|
let app = gtk::Application::new(None, gio::APPLICATION_FLAGS_NONE).unwrap();
|
||||||
|
|
||||||
|
app.connect_activate(create_ui);
|
||||||
|
let args = env::args().collect::<Vec<_>>();
|
||||||
|
let args_ref = args.iter().map(|a| a.as_str()).collect::<Vec<_>>();
|
||||||
|
app.run(&args_ref);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue