mirror of
https://gitlab.freedesktop.org/dabrain34/GstPipelineStudio.git
synced 2024-11-22 09:00:59 +00:00
app: code cleanup
Use simplified anyhow result Rewrite the expect/error messages. Refactor the start pipeline API Rename the treeview ids
This commit is contained in:
parent
2a7137e6dc
commit
198847cb54
5 changed files with 132 additions and 135 deletions
11
TODO.md
11
TODO.md
|
@ -25,6 +25,15 @@ TODO:
|
|||
- [x] Connect the logs to the window
|
||||
- [] Create a window for the video output
|
||||
- [] Add multiple graphviews with tabs.
|
||||
- [] Property window in the main window
|
||||
- [] Connect the GPS status to GST status
|
||||
- [] Implement graph dot render/load
|
||||
- [] Implement a command line parser to graph
|
||||
- [] Unable to create a pad in an element without the template
|
||||
- [] Remove a pad from the graph
|
||||
- [] Implement graphview unit test
|
||||
- [] Implement pipeline unit test
|
||||
- [] Save node position in XML
|
||||
|
||||
## bugs
|
||||
|
||||
|
@ -35,5 +44,5 @@ TODO:
|
|||
## Code cleanup
|
||||
|
||||
[] remove useless code from graphview
|
||||
[] Move render to a specific module
|
||||
[X] Move render to a specific module
|
||||
[x] Move GST render to a specific module
|
||||
|
|
138
src/app.rs
138
src/app.rs
|
@ -16,6 +16,7 @@
|
|||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use glib::SignalHandlerId;
|
||||
use glib::Value;
|
||||
use gtk::gdk::Rectangle;
|
||||
|
@ -29,8 +30,8 @@ use gtk::{gio, gio::SimpleAction, glib, graphene};
|
|||
use once_cell::unsync::OnceCell;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::ops;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::{error, ops};
|
||||
|
||||
use crate::about;
|
||||
use crate::logger;
|
||||
|
@ -78,26 +79,29 @@ impl GPSAppWeak {
|
|||
}
|
||||
|
||||
impl GPSApp {
|
||||
fn new(application: >k::Application) -> anyhow::Result<GPSApp, Box<dyn error::Error>> {
|
||||
fn new(application: >k::Application) -> anyhow::Result<GPSApp> {
|
||||
let glade_src = include_str!("gps.ui");
|
||||
let builder = Builder::from_string(glade_src);
|
||||
let window: ApplicationWindow = builder.object("mainwindow").expect("Couldn't get window");
|
||||
let window: ApplicationWindow = builder
|
||||
.object("mainwindow")
|
||||
.expect("Couldn't get the main window");
|
||||
window.set_application(Some(application));
|
||||
window.set_title(Some("GstPipelineStudio"));
|
||||
|
||||
let settings = Settings::load_settings();
|
||||
window.set_size_request(settings.app_width, settings.app_height);
|
||||
let paned: Paned = builder
|
||||
.object("graph_logs-paned")
|
||||
.expect("Couldn't get window");
|
||||
.expect("Couldn't get graph_logs-paned");
|
||||
paned.set_position(settings.app_graph_logs_paned_pos);
|
||||
let paned: Paned = builder
|
||||
.object("graph_favorites-paned")
|
||||
.expect("Couldn't get window");
|
||||
.expect("Couldn't get graph_favorites-paned");
|
||||
paned.set_position(settings.app_graph_favorites_paned_pos);
|
||||
if settings.app_maximized {
|
||||
window.maximize();
|
||||
}
|
||||
let pipeline = Pipeline::new().expect("Unable to initialize the pipeline");
|
||||
let pipeline = Pipeline::new().expect("Unable to initialize GStreamer subsystem");
|
||||
let app = GPSApp(Rc::new(GPSAppInner {
|
||||
window,
|
||||
graphview: RefCell::new(GraphView::new()),
|
||||
|
@ -113,11 +117,8 @@ impl GPSApp {
|
|||
// Create application and error out if that fails for whatever reason
|
||||
let app = match GPSApp::new(application) {
|
||||
Ok(app) => app,
|
||||
Err(_err) => {
|
||||
/* utils::show_error_dialog(
|
||||
true,
|
||||
format!("Error creating application: {}", err).as_str(),
|
||||
); */
|
||||
Err(err) => {
|
||||
println!("Error creating application: {}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -125,7 +126,6 @@ impl GPSApp {
|
|||
// When the application is activated show the UI. This happens when the first process is
|
||||
// started, and in the first process whenever a second process is started
|
||||
let app_weak = app.downgrade();
|
||||
|
||||
application.connect_activate(glib::clone!(@weak application => move |_| {
|
||||
let app = upgrade_weak!(app_weak);
|
||||
app.build_ui(&application);
|
||||
|
@ -140,7 +140,7 @@ impl GPSApp {
|
|||
let window: ApplicationWindow = app
|
||||
.builder
|
||||
.object("mainwindow")
|
||||
.expect("Couldn't get window");
|
||||
.expect("Couldn't get the main window");
|
||||
let mut settings = Settings::load_settings();
|
||||
settings.app_maximized = window.is_maximized();
|
||||
settings.app_width = window.width();
|
||||
|
@ -148,19 +148,19 @@ impl GPSApp {
|
|||
let paned: Paned = app
|
||||
.builder
|
||||
.object("graph_logs-paned")
|
||||
.expect("Couldn't get window");
|
||||
.expect("Couldn't get graph_logs-paned");
|
||||
settings.app_graph_logs_paned_pos = paned.position();
|
||||
let paned: Paned = app
|
||||
.builder
|
||||
.object("graph_favorites-paned")
|
||||
.expect("Couldn't get window");
|
||||
.expect("Couldn't get graph_favorites-paned");
|
||||
settings.app_graph_favorites_paned_pos = paned.position();
|
||||
Settings::save_settings(&settings);
|
||||
|
||||
let pop_menu: PopoverMenu = app
|
||||
.builder
|
||||
.object("app_pop_menu")
|
||||
.expect("Couldn't get pop over menu for app");
|
||||
.expect("Couldn't get app_pop_menu");
|
||||
pop_menu.unparent();
|
||||
|
||||
app.drop();
|
||||
|
@ -203,12 +203,12 @@ impl GPSApp {
|
|||
let mainwindow: ApplicationWindow = self
|
||||
.builder
|
||||
.object("mainwindow")
|
||||
.expect("Couldn't get mainwindow");
|
||||
.expect("Couldn't get the main window");
|
||||
|
||||
let pop_menu: PopoverMenu = self
|
||||
.builder
|
||||
.object("app_pop_menu")
|
||||
.expect("Couldn't get popover menu");
|
||||
.expect("Couldn't get app_pop_menu");
|
||||
|
||||
if let Some((x, y)) = widget.translate_coordinates(&mainwindow, x, y) {
|
||||
let point = graphene::Point::new(x as f32, y as f32);
|
||||
|
@ -232,12 +232,12 @@ impl GPSApp {
|
|||
let application = gio::Application::default()
|
||||
.expect("No default application")
|
||||
.downcast::<gtk::Application>()
|
||||
.expect("Default application has wrong type");
|
||||
.expect("Unable to downcast default application");
|
||||
let action = application
|
||||
.lookup_action(action_name)
|
||||
.expect("Unable to find action")
|
||||
.unwrap_or_else(|| panic!("Unable to find action {}", action_name))
|
||||
.dynamic_cast::<SimpleAction>()
|
||||
.expect("Unable to cast to SimpleAction");
|
||||
.expect("Unable to dynamic cast to SimpleAction");
|
||||
|
||||
if let Some(signal_handler_id) = self.menu_signal_handlers.borrow_mut().remove(action_name)
|
||||
{
|
||||
|
@ -270,7 +270,7 @@ impl GPSApp {
|
|||
let window: ApplicationWindow = app
|
||||
.builder
|
||||
.object("mainwindow")
|
||||
.expect("Couldn't get window");
|
||||
.expect("Couldn't get main window");
|
||||
let file_chooser: FileChooserDialog = FileChooserDialog::new(
|
||||
Some(message),
|
||||
Some(&window),
|
||||
|
@ -289,7 +289,7 @@ impl GPSApp {
|
|||
file.path()
|
||||
.expect("Couldn't get file path")
|
||||
.to_str()
|
||||
.expect("unable to convert to string"),
|
||||
.expect("Unable to convert to string"),
|
||||
);
|
||||
f(app, filename);
|
||||
}
|
||||
|
@ -336,8 +336,8 @@ impl GPSApp {
|
|||
fn setup_logger_list(&self) {
|
||||
let logger_list: TreeView = self
|
||||
.builder
|
||||
.object("logger_list")
|
||||
.expect("Couldn't get window");
|
||||
.object("treeview-logger")
|
||||
.expect("Couldn't get treeview-logger");
|
||||
let column = TreeViewColumn::new();
|
||||
let cell = CellRendererText::new();
|
||||
column.pack_start(&cell, true);
|
||||
|
@ -358,8 +358,8 @@ impl GPSApp {
|
|||
fn add_to_logger_list(&self, log_entry: String) {
|
||||
let logger_list: TreeView = self
|
||||
.builder
|
||||
.object("logger_list")
|
||||
.expect("Couldn't get window");
|
||||
.object("treeview-logger")
|
||||
.expect("Couldn't get treeview-logger");
|
||||
if let Some(model) = logger_list.model() {
|
||||
let list_store = model
|
||||
.dynamic_cast::<ListStore>()
|
||||
|
@ -382,8 +382,8 @@ impl GPSApp {
|
|||
fn setup_favorite_list(&self, application: &Application) {
|
||||
let favorite_list: TreeView = self
|
||||
.builder
|
||||
.object("favorites_list")
|
||||
.expect("Couldn't get window");
|
||||
.object("treeview-favorites")
|
||||
.expect("Couldn't get treeview-favorites");
|
||||
let column = TreeViewColumn::new();
|
||||
let cell = CellRendererText::new();
|
||||
|
||||
|
@ -402,7 +402,7 @@ impl GPSApp {
|
|||
.get(&iter, 0)
|
||||
.get::<String>()
|
||||
.expect("Treeview selection, column 1");
|
||||
GPS_DEBUG!("{}", element_name);
|
||||
GPS_DEBUG!("{} selected", element_name);
|
||||
app.add_new_element(&element_name);
|
||||
}
|
||||
});
|
||||
|
@ -418,14 +418,14 @@ impl GPSApp {
|
|||
let element_name = model
|
||||
.get(&iter, 0)
|
||||
.get::<String>()
|
||||
.expect("Treeview selection, column 1");
|
||||
GPS_DEBUG!("{}", element_name);
|
||||
.expect("Treeview selection, column 0");
|
||||
GPS_DEBUG!("Element {} selected", element_name);
|
||||
|
||||
let pop_menu = app.app_pop_menu_at_position(&favorite_list, x, y);
|
||||
let menu: gio::MenuModel = app
|
||||
.builder
|
||||
.object("fav_menu")
|
||||
.expect("Couldn't get menu model for graph");
|
||||
.expect("Couldn't get fav_menu model");
|
||||
pop_menu.set_menu_model(Some(&menu));
|
||||
|
||||
let app_weak = app.downgrade();
|
||||
|
@ -451,8 +451,8 @@ impl GPSApp {
|
|||
if !favorites.contains(&element_name) {
|
||||
let favorite_list: TreeView = self
|
||||
.builder
|
||||
.object("favorites_list")
|
||||
.expect("Couldn't get window");
|
||||
.object("treeview-favorites")
|
||||
.expect("Couldn't get treeview-favorites");
|
||||
if let Some(model) = favorite_list.model() {
|
||||
let list_store = model
|
||||
.dynamic_cast::<ListStore>()
|
||||
|
@ -472,7 +472,7 @@ impl GPSApp {
|
|||
let drawing_area_window: Viewport = self
|
||||
.builder
|
||||
.object("drawing_area")
|
||||
.expect("Couldn't get window");
|
||||
.expect("Couldn't get drawing_area");
|
||||
|
||||
drawing_area_window.set_child(Some(&*self.graphview.borrow()));
|
||||
|
||||
|
@ -482,7 +482,7 @@ impl GPSApp {
|
|||
let status_bar: Statusbar = self
|
||||
.builder
|
||||
.object("status_bar")
|
||||
.expect("Couldn't get window");
|
||||
.expect("Couldn't get status_bar");
|
||||
status_bar.push(status_bar.context_id("Description"), "GPS is ready");
|
||||
|
||||
self.setup_app_actions(application);
|
||||
|
@ -490,7 +490,7 @@ impl GPSApp {
|
|||
let pop_menu: PopoverMenu = self
|
||||
.builder
|
||||
.object("app_pop_menu")
|
||||
.expect("Couldn't get pop over menu for app");
|
||||
.expect("Couldn't get app_pop_menu");
|
||||
pop_menu.set_parent(window);
|
||||
|
||||
let app_weak = self.downgrade();
|
||||
|
@ -543,48 +543,26 @@ impl GPSApp {
|
|||
let app = upgrade_weak!(app_weak);
|
||||
GPSApp::display_plugin_list(&app);
|
||||
});
|
||||
let add_button: Button = self
|
||||
.builder
|
||||
.object("button-play")
|
||||
.expect("Couldn't get app_button");
|
||||
let app_weak = self.downgrade();
|
||||
add_button.connect_clicked(glib::clone!(@weak window => move |_| {
|
||||
// entry.set_text("Clicked!");
|
||||
let app = upgrade_weak!(app_weak);
|
||||
let graph_view = app.graphview.borrow();
|
||||
let pipeline = app.pipeline.borrow();
|
||||
if pipeline.state() == PipelineState::Stopped {
|
||||
if let Err(err) = pipeline.create_pipeline(&pipeline.render_gst_launch(&graph_view)) {
|
||||
GPS_ERROR!("Unable to start a pipeline: {}", err);
|
||||
|
||||
}
|
||||
pipeline.set_state(PipelineState::Playing).expect("Unable to change state");
|
||||
} else if pipeline.state() == PipelineState::Paused {
|
||||
pipeline.set_state(PipelineState::Playing).expect("Unable to change state");
|
||||
} else {
|
||||
pipeline.set_state(PipelineState::Paused).expect("Unable to change state");
|
||||
}
|
||||
}));
|
||||
let add_button: Button = self
|
||||
.builder
|
||||
.object("button-pause")
|
||||
.expect("Couldn't get app_button");
|
||||
let app_weak = self.downgrade();
|
||||
add_button.connect_clicked(glib::clone!(@weak window => move |_| {
|
||||
self.connect_button_action("button-play", move |_| {
|
||||
let app = upgrade_weak!(app_weak);
|
||||
let graph_view = app.graphview.borrow();
|
||||
let pipeline = app.pipeline.borrow();
|
||||
if pipeline.state() == PipelineState::Stopped {
|
||||
if let Err(err) = pipeline.create_pipeline(&pipeline.render_gst_launch(&graph_view)) {
|
||||
GPS_ERROR!("Unable to start a pipeline: {}", err);
|
||||
}
|
||||
pipeline.set_state(PipelineState::Paused).expect("Unable to change state");
|
||||
} else if pipeline.state() == PipelineState::Paused {
|
||||
pipeline.set_state(PipelineState::Playing).expect("Unable to change state");
|
||||
} else {
|
||||
pipeline.set_state(PipelineState::Paused).expect("Unable to change state");
|
||||
}
|
||||
}));
|
||||
let _ = app
|
||||
.pipeline
|
||||
.borrow()
|
||||
.start_pipeline(&graph_view, PipelineState::Playing);
|
||||
});
|
||||
|
||||
let app_weak = self.downgrade();
|
||||
self.connect_button_action("button-pause", move |_| {
|
||||
let app = upgrade_weak!(app_weak);
|
||||
let graph_view = app.graphview.borrow();
|
||||
let _ = app
|
||||
.pipeline
|
||||
.borrow()
|
||||
.start_pipeline(&graph_view, PipelineState::Paused);
|
||||
});
|
||||
|
||||
let app_weak = self.downgrade();
|
||||
self.connect_button_action("button-stop", move |_| {
|
||||
|
@ -592,6 +570,7 @@ impl GPSApp {
|
|||
let pipeline = app.pipeline.borrow();
|
||||
let _ = pipeline.set_state(PipelineState::Stopped);
|
||||
});
|
||||
|
||||
let app_weak = self.downgrade();
|
||||
self.connect_button_action("button-clear", move |_| {
|
||||
let app = upgrade_weak!(app_weak);
|
||||
|
@ -614,7 +593,7 @@ impl GPSApp {
|
|||
let menu: gio::MenuModel = app
|
||||
.builder
|
||||
.object("graph_menu")
|
||||
.expect("Couldn't get menu model for graph");
|
||||
.expect("Couldn't graph_menu");
|
||||
pop_menu.set_menu_model(Some(&menu));
|
||||
|
||||
let app_weak = app.downgrade();
|
||||
|
@ -624,7 +603,6 @@ impl GPSApp {
|
|||
GPSApp::display_plugin_list(&app);
|
||||
}
|
||||
);
|
||||
|
||||
pop_menu.show();
|
||||
None
|
||||
}),
|
||||
|
@ -795,13 +773,13 @@ impl GPSApp {
|
|||
graph_view.remove_all_nodes();
|
||||
}
|
||||
|
||||
fn save_graph(&self, filename: &str) -> anyhow::Result<(), Box<dyn error::Error>> {
|
||||
fn save_graph(&self, filename: &str) -> anyhow::Result<()> {
|
||||
let graph_view = self.graphview.borrow_mut();
|
||||
graph_view.render_xml(filename)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn load_graph(&self, filename: &str) -> anyhow::Result<(), Box<dyn error::Error>> {
|
||||
fn load_graph(&self, filename: &str) -> anyhow::Result<()> {
|
||||
self.clear_graph();
|
||||
let graph_view = self.graphview.borrow_mut();
|
||||
graph_view.load_xml(filename)?;
|
||||
|
|
|
@ -139,7 +139,7 @@
|
|||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="apply-plugin-properties">
|
||||
<object class="GtkButton" id="button-apply-plugin-properties">
|
||||
<property name="halign">end</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
|
@ -254,7 +254,7 @@
|
|||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="child">
|
||||
<object class="GtkTreeView" id="favorites_list">
|
||||
<object class="GtkTreeView" id="treeview-favorites">
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
|
@ -264,7 +264,7 @@
|
|||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="child">
|
||||
<object class="GtkTreeView" id="logger_list"/>
|
||||
<object class="GtkTreeView" id="treeview-logger"/>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
|
|
@ -25,7 +25,6 @@ use gst::prelude::*;
|
|||
use gstreamer as gst;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::HashMap;
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::ops;
|
||||
use std::rc::{Rc, Weak};
|
||||
|
@ -88,7 +87,7 @@ pub struct PipelineInner {
|
|||
}
|
||||
|
||||
impl Pipeline {
|
||||
pub fn new() -> Result<Self, Box<dyn error::Error>> {
|
||||
pub fn new() -> anyhow::Result<Self> {
|
||||
let pipeline = Pipeline(Rc::new(PipelineInner {
|
||||
pipeline: RefCell::new(None),
|
||||
current_state: Cell::new(PipelineState::Stopped),
|
||||
|
@ -97,36 +96,58 @@ impl Pipeline {
|
|||
Ok(pipeline)
|
||||
}
|
||||
|
||||
pub fn create_pipeline(&self, description: &str) -> Result<(), Box<dyn error::Error>> {
|
||||
pub fn create_pipeline(&self, description: &str) -> anyhow::Result<()> {
|
||||
GPS_INFO!("Creating pipeline {}", description);
|
||||
|
||||
/* create playbin */
|
||||
|
||||
// Create pipeline from the description
|
||||
let pipeline = gst::parse_launch(&description.to_string())?;
|
||||
if let Ok(pipeline) = pipeline.downcast::<gst::Pipeline>() {
|
||||
//pipeline.set_property_message_forward(true);
|
||||
|
||||
let bus = pipeline.bus().expect("Pipeline had no bus");
|
||||
let pipeline_weak = self.downgrade();
|
||||
bus.add_watch_local(move |_bus, msg| {
|
||||
let pipeline = upgrade_weak!(pipeline_weak, glib::Continue(false));
|
||||
|
||||
pipeline.on_pipeline_message(msg);
|
||||
|
||||
glib::Continue(true)
|
||||
})?;
|
||||
|
||||
*self.pipeline.borrow_mut() = Some(pipeline);
|
||||
/* start playing */
|
||||
} else {
|
||||
GPS_ERROR!("Couldn't downcast pipeline")
|
||||
GPS_ERROR!("Can not create a proper pipeline from gstreamer parse_launch");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_state(&self, state: PipelineState) -> Result<(), Box<dyn error::Error>> {
|
||||
pub fn start_pipeline(
|
||||
&self,
|
||||
graphview: &GraphView,
|
||||
new_state: PipelineState,
|
||||
) -> anyhow::Result<PipelineState> {
|
||||
if self.state() == PipelineState::Stopped {
|
||||
self.create_pipeline(&self.render_gst_launch(graphview))
|
||||
.map_err(|err| {
|
||||
GPS_ERROR!("Unable to start a pipeline: {}", err);
|
||||
})
|
||||
.unwrap();
|
||||
self.set_state(new_state)
|
||||
.map_err(|_| GPS_ERROR!("Unable to change state"))
|
||||
.unwrap();
|
||||
} else if self.state() == PipelineState::Paused {
|
||||
self.set_state(PipelineState::Playing)
|
||||
.map_err(|_| GPS_ERROR!("Unable to change state"))
|
||||
.unwrap();
|
||||
} else {
|
||||
self.set_state(PipelineState::Paused)
|
||||
.map_err(|_| GPS_ERROR!("Unable to change state"))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
Ok(self.state())
|
||||
}
|
||||
|
||||
pub fn set_state(&self, new_state: PipelineState) -> anyhow::Result<PipelineState> {
|
||||
if let Some(pipeline) = self.pipeline.borrow().to_owned() {
|
||||
match state {
|
||||
match new_state {
|
||||
PipelineState::Playing => pipeline.set_state(gst::State::Playing)?,
|
||||
PipelineState::Paused => pipeline.set_state(gst::State::Paused)?,
|
||||
PipelineState::Stopped => {
|
||||
|
@ -134,9 +155,9 @@ impl Pipeline {
|
|||
gst::StateChangeSuccess::Success
|
||||
}
|
||||
};
|
||||
self.current_state.set(state);
|
||||
self.current_state.set(new_state);
|
||||
}
|
||||
Ok(())
|
||||
Ok(new_state)
|
||||
}
|
||||
|
||||
pub fn state(&self) -> PipelineState {
|
||||
|
@ -181,7 +202,7 @@ impl Pipeline {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn elements_list() -> Result<Vec<ElementInfo>, Box<dyn error::Error>> {
|
||||
pub fn elements_list() -> anyhow::Result<Vec<ElementInfo>> {
|
||||
let registry = gst::Registry::get();
|
||||
let mut elements: Vec<ElementInfo> = Vec::new();
|
||||
let plugins = gst::Registry::plugin_list(®istry);
|
||||
|
@ -204,24 +225,15 @@ impl Pipeline {
|
|||
Ok(elements)
|
||||
}
|
||||
|
||||
pub fn element_feature(
|
||||
element_name: &str,
|
||||
) -> anyhow::Result<gst::PluginFeature, Box<dyn error::Error>> {
|
||||
fn element_feature(element_name: &str) -> Option<gst::PluginFeature> {
|
||||
let registry = gst::Registry::get();
|
||||
let feature = gst::Registry::find_feature(
|
||||
®istry,
|
||||
element_name,
|
||||
gst::ElementFactory::static_type(),
|
||||
)
|
||||
.expect("Unable to find the element name");
|
||||
Ok(feature)
|
||||
gst::Registry::find_feature(®istry, element_name, gst::ElementFactory::static_type())
|
||||
}
|
||||
|
||||
pub fn element_description(
|
||||
element_name: &str,
|
||||
) -> anyhow::Result<String, Box<dyn error::Error>> {
|
||||
pub fn element_description(element_name: &str) -> anyhow::Result<String> {
|
||||
let mut desc = String::from("");
|
||||
let feature = Pipeline::element_feature(element_name)?;
|
||||
let feature = Pipeline::element_feature(element_name)
|
||||
.ok_or_else(|| glib::bool_error!("Failed get element feature"))?;
|
||||
|
||||
if let Ok(factory) = feature.downcast::<gst::ElementFactory>() {
|
||||
desc.push_str("<b>Factory details:</b>\n");
|
||||
|
@ -330,15 +342,13 @@ impl Pipeline {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn element_properties(
|
||||
element_name: &str,
|
||||
) -> anyhow::Result<HashMap<String, String>, Box<dyn error::Error>> {
|
||||
pub fn element_properties(element_name: &str) -> anyhow::Result<HashMap<String, String>> {
|
||||
let mut properties_list = HashMap::new();
|
||||
let feature = Pipeline::element_feature(element_name).expect("Unable to get feature");
|
||||
|
||||
let factory = feature
|
||||
.downcast::<gst::ElementFactory>()
|
||||
.expect("Factory not found");
|
||||
.expect("Unable to get the factory from the feature");
|
||||
let element = factory.create(None)?;
|
||||
let params = element.class().list_properties();
|
||||
|
||||
|
@ -364,8 +374,10 @@ impl Pipeline {
|
|||
|
||||
let factory = feature
|
||||
.downcast::<gst::ElementFactory>()
|
||||
.expect("Factory not found");
|
||||
let element = factory.create(None).expect("Unable to get factory");
|
||||
.expect("Unable to get the factory from the feature");
|
||||
let element = factory
|
||||
.create(None)
|
||||
.expect("Unable to create an element from the feature");
|
||||
match element.dynamic_cast::<gst::URIHandler>() {
|
||||
Ok(uri_handler) => uri_handler.uri_type() == gst::URIType::Src,
|
||||
Err(_e) => false,
|
||||
|
@ -373,7 +385,7 @@ impl Pipeline {
|
|||
}
|
||||
|
||||
// Render graph methods
|
||||
pub fn process_node(
|
||||
fn process_gst_node(
|
||||
&self,
|
||||
graphview: &GraphView,
|
||||
node: &Node,
|
||||
|
@ -401,7 +413,7 @@ impl Pipeline {
|
|||
description.push_str(&format!("{}. ", node.unique_name()));
|
||||
} else {
|
||||
description =
|
||||
self.process_node(graphview, &node, elements, description.clone());
|
||||
self.process_gst_node(graphview, &node, elements, description.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -415,7 +427,7 @@ impl Pipeline {
|
|||
let mut description = String::from("");
|
||||
for source_node in source_nodes {
|
||||
description =
|
||||
self.process_node(graphview, &source_node, &mut elements, description.clone());
|
||||
self.process_gst_node(graphview, &source_node, &mut elements, description.clone());
|
||||
}
|
||||
description
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ pub fn display_plugin_list(app: &GPSApp, elements: &[ElementInfo]) {
|
|||
let dialog: Dialog = app
|
||||
.builder
|
||||
.object("dialog-plugin-list")
|
||||
.expect("Couldn't get window");
|
||||
.expect("Couldn't get the dialog-plugin-list window");
|
||||
|
||||
if app.plugin_list_initialized.get().is_none() {
|
||||
dialog.set_title(Some("Plugin list"));
|
||||
|
@ -70,13 +70,13 @@ pub fn display_plugin_list(app: &GPSApp, elements: &[ElementInfo]) {
|
|||
let text_view: TextView = app
|
||||
.builder
|
||||
.object("textview-plugin-list")
|
||||
.expect("Couldn't get window");
|
||||
.expect("Couldn't get textview-plugin-list window");
|
||||
let text_buffer: TextBuffer = text_view.buffer();
|
||||
|
||||
let tree: TreeView = app
|
||||
.builder
|
||||
.object("treeview-plugin-list")
|
||||
.expect("Couldn't get window");
|
||||
.expect("Couldn't get treeview-plugin-list window");
|
||||
if tree.n_columns() < 2 {
|
||||
append_column(&tree, 0);
|
||||
append_column(&tree, 1);
|
||||
|
@ -94,8 +94,8 @@ pub fn display_plugin_list(app: &GPSApp, elements: &[ElementInfo]) {
|
|||
let element_name = model
|
||||
.get(&iter, 1)
|
||||
.get::<String>()
|
||||
.expect("Treeview selection, column 1");
|
||||
let description = Pipeline::element_description(&element_name).expect("Unable to get element list from GStreamer");
|
||||
.expect("Unable to get the treeview selection, column 1");
|
||||
let description = Pipeline::element_description(&element_name).expect("Unable to get element description from GStreamer");
|
||||
text_buffer.set_text("");
|
||||
text_buffer.insert_markup(&mut text_buffer.end_iter(), &description);
|
||||
}
|
||||
|
@ -110,14 +110,12 @@ pub fn display_plugin_list(app: &GPSApp, elements: &[ElementInfo]) {
|
|||
let element_name = model
|
||||
.get(&iter, 1)
|
||||
.get::<String>()
|
||||
.expect("Treeview selection, column 1");
|
||||
.expect("Unable to get the treeview selection, column 1");
|
||||
app.add_new_element(&element_name);
|
||||
}
|
||||
}),
|
||||
);
|
||||
app.plugin_list_initialized
|
||||
.set(true)
|
||||
.expect("Should never happen");
|
||||
app.plugin_list_initialized.set(true).unwrap();
|
||||
}
|
||||
|
||||
dialog.show();
|
||||
|
@ -127,7 +125,7 @@ pub fn display_plugin_properties(app: &GPSApp, element_name: &str, node_id: u32)
|
|||
let dialog: Dialog = app
|
||||
.builder
|
||||
.object("dialog-plugin-properties")
|
||||
.expect("Couldn't get window");
|
||||
.expect("Couldn't get dialog-plugin-properties");
|
||||
|
||||
dialog.set_title(Some(&format!("{} properties", element_name)));
|
||||
dialog.set_default_size(640, 480);
|
||||
|
@ -136,7 +134,7 @@ pub fn display_plugin_properties(app: &GPSApp, element_name: &str, node_id: u32)
|
|||
let properties_box: Box = app
|
||||
.builder
|
||||
.object("box-plugin-properties")
|
||||
.expect("Couldn't get window");
|
||||
.expect("Couldn't get box-plugin-properties");
|
||||
let update_properties: Rc<RefCell<HashMap<String, String>>> =
|
||||
Rc::new(RefCell::new(HashMap::new()));
|
||||
let properties = Pipeline::element_properties(element_name).unwrap();
|
||||
|
@ -163,8 +161,8 @@ pub fn display_plugin_properties(app: &GPSApp, element_name: &str, node_id: u32)
|
|||
}
|
||||
let properties_apply_btn: Button = app
|
||||
.builder
|
||||
.object("apply-plugin-properties")
|
||||
.expect("Couldn't get window");
|
||||
.object("button-apply-plugin-properties")
|
||||
.expect("Couldn't get button-apply-plugin-properties");
|
||||
|
||||
let app_weak = app.downgrade();
|
||||
properties_apply_btn.connect_clicked(
|
||||
|
|
Loading…
Reference in a new issue