app: update to gtk 0.8.0 and gst 0.22.2

In the change, the glib::channel has been dropped to use
async_io which achieves the same to receive message
for the logger and display it in the treeview.
Another message is received when a new gtkpaintablesink
has been instanciated.
This commit is contained in:
Stéphane Cerveau 2024-02-28 11:30:59 +01:00
parent 44d64ccdc4
commit 1f200f4f30
5 changed files with 374 additions and 383 deletions

677
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -7,9 +7,9 @@ rust-version = "1.70.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
gtk = { version = "0.7.3", package = "gtk4" }
gst = { package = "gstreamer", version = "0.21.3" }
gst-plugin-gtk4 = { version = "0.11.3", optional=true }
gtk = { version = "0.8.0", package = "gtk4" }
gst = { package = "gstreamer", version = "0.22.2" }
gst-plugin-gtk4 = { version = "0.12.1", optional=true }
anyhow = "1"
log = "0.4.11"
once_cell = "1.7.2"
@ -21,6 +21,8 @@ futures-channel = "0.3"
lazy_static = "1.4"
chrono = "0.4"
structopt = "0.3"
async-channel = "2.0.0"
[dev-dependencies]
futures-executor = "0.3"

View file

@ -446,10 +446,10 @@ impl GPSApp {
pub fn build_ui(&self, application: &Application, pipeline_desc: &String) {
graphbook::setup_graphbook(self);
graphbook::create_graphtab(self, 0, None);
let (ready_tx, ready_rx) = async_channel::unbounded::<(logger::LogType, String)>();
// Setup the logger to get messages into the TreeView
let (ready_tx, ready_rx) = glib::MainContext::channel(glib::Priority::DEFAULT);
let app_weak = self.downgrade();
logger::init_logger(
ready_tx.clone(),
Settings::log_file_path()
@ -460,9 +460,12 @@ impl GPSApp {
GPSUI::logger::setup_logger_list(self, "treeview-app-logger", logger::LogType::App);
GPSUI::logger::setup_logger_list(self, "treeview-msg-logger", logger::LogType::Message);
GPSUI::logger::setup_logger_list(self, "treeview-gst-logger", logger::LogType::Gst);
let _ = ready_rx.attach(None, move |msg: (logger::LogType, String)| {
let app = upgrade_weak!(app_weak, glib::ControlFlow::Break);
GPSUI::logger::add_to_logger_list(&app, msg.0, &msg.1);
let app_weak = self.downgrade();
glib::spawn_future_local(async move {
while let Ok(msg) = ready_rx.recv().await {
let app = upgrade_weak!(app_weak, glib::ControlFlow::Break);
GPSUI::logger::add_to_logger_list(&app, msg.0, &msg.1);
}
glib::ControlFlow::Continue
});

View file

@ -101,7 +101,7 @@ impl Player {
n_video_sink: Cell::new(0),
bus_watch_guard: RefCell::new(None),
}));
gst::debug_add_log_function(gst_log_handler);
gst::log::add_log_function(gst_log_handler);
Ok(pipeline)
}
@ -123,13 +123,13 @@ impl Player {
.parse::<bool>()
.expect("Should a boolean value")
{
ElementInfo::element_update_rank("gtk4paintablesink", gst::Rank::Primary);
ElementInfo::element_update_rank("gtk4paintablesink", gst::Rank::PRIMARY);
} else {
ElementInfo::element_update_rank("gtk4paintablesink", gst::Rank::Marginal);
ElementInfo::element_update_rank("gtk4paintablesink", gst::Rank::MARGINAL);
}
gst::debug_set_threshold_from_string(settings::Settings::gst_log_level().as_str(), true);
gst::log::set_threshold_from_string(settings::Settings::gst_log_level().as_str(), true);
// Create pipeline from the description
let pipeline = gst::parse_launch(description)?;
let pipeline = gst::parse::launch(description)?;
let pipeline = pipeline.downcast::<gst::Pipeline>();
/* start playing */
if pipeline.is_err() {
@ -141,19 +141,21 @@ impl Player {
self.check_for_gtk4sink(pipeline.as_ref().unwrap());
// GPSApp is not Send(trait) ready , so we use a channel to exchange the given data with the main thread and use
// GPSApp.
let (ready_tx, ready_rx) = glib::MainContext::channel(glib::Priority::DEFAULT);
let (ready_tx, ready_rx) = async_channel::unbounded::<gst::Element>();
let player_weak = self.downgrade();
let _ = ready_rx.attach(None, move |element: gst::Element| {
let player = upgrade_weak!(player_weak, glib::ControlFlow::Break);
let paintable = element.property::<gdk::Paintable>("paintable");
let n_sink = player.n_video_sink.get();
player
.app
.borrow()
.as_ref()
.expect("App should be available")
.set_app_preview(&paintable, n_sink);
player.n_video_sink.set(n_sink + 1);
glib::spawn_future_local(async move {
while let Ok(element) = ready_rx.recv().await {
let player = upgrade_weak!(player_weak, glib::ControlFlow::Break);
let paintable = element.property::<gdk::Paintable>("paintable");
let n_sink = player.n_video_sink.get();
player
.app
.borrow()
.as_ref()
.expect("App should be available")
.set_app_preview(&paintable, n_sink);
player.n_video_sink.set(n_sink + 1);
}
glib::ControlFlow::Continue
});
let bin = pipeline.unwrap().dynamic_cast::<gst::Bin>();
@ -162,7 +164,7 @@ impl Player {
if let Some(factory) = element.factory() {
GPS_INFO!("Received the signal deep element added {}", factory.name());
if factory.name() == "gtk4paintablesink" {
let _ = ready_tx.send(element.clone());
let _ = ready_tx.try_send(element.clone());
}
}
});

View file

@ -6,7 +6,6 @@
//
// SPDX-License-Identifier: GPL-3.0-only
use gtk::glib::Sender;
use log::{debug, error, info, trace, warn};
use simplelog::*;
use std::fmt;
@ -116,7 +115,7 @@ macro_rules! GPS_TRACE (
);
struct WriteAdapter {
sender: Sender<(LogType, String)>,
sender: async_channel::Sender<(LogType, String)>,
buffer: String,
}
@ -127,10 +126,8 @@ impl io::Write for WriteAdapter {
.push_str(&String::from_utf8(buf.to_vec()).unwrap());
if self.buffer.ends_with('\n') {
self.buffer.pop();
self.sender
.send((LogType::App, self.buffer.clone()))
.unwrap();
self.buffer = String::from("");
let _ = self.sender.try_send((LogType::App, self.buffer.clone()));
self.buffer.clear();
}
Ok(buf.len())
@ -152,7 +149,7 @@ fn translate_to_simple_logger(log_level: LogLevel) -> LevelFilter {
}
}
pub fn init_logger(sender: Sender<(LogType, String)>, log_file: &str) {
pub fn init_logger(sender: async_channel::Sender<(LogType, String)>, log_file: &str) {
simplelog::CombinedLogger::init(vec![
WriteLogger::new(
translate_to_simple_logger(LogLevel::Trace),
@ -204,21 +201,23 @@ pub fn print_log(log_level: LogLevel, msg: String) {
#[derive(Debug, Clone)]
pub struct MessageLogger {
sender: Sender<(LogType, String)>,
sender: async_channel::Sender<(LogType, String)>,
}
impl MessageLogger {
pub fn new(sender: Sender<(LogType, String)>) -> Self {
pub fn new(sender: async_channel::Sender<(LogType, String)>) -> Self {
Self { sender }
}
pub fn print_log(&self, log_type: LogType, msg: String) {
let to_send = format!("{}\t{}", Local::now().format("%H:%M:%S"), msg);
self.sender.send((log_type, to_send)).unwrap();
self.sender
.try_send((log_type, to_send))
.expect("Unable to send the log");
}
}
pub fn init_msg_logger(sender: Sender<(LogType, String)>) {
pub fn init_msg_logger(sender: async_channel::Sender<(LogType, String)>) {
let mut msg_logger = MSG_LOGGER.lock().unwrap();
if msg_logger.is_none() {
// Initialize the variable