From ea2c2adcb782a4cdecd70d95bb83c6f0d56050f7 Mon Sep 17 00:00:00 2001 From: Clouds Flowing Date: Thu, 14 Nov 2024 17:08:06 +0800 Subject: [PATCH 1/2] update deps --- Cargo.toml | 12 ++-- src/device_provider/imp.rs | 16 ++--- src/device_provider/mod.rs | 2 +- src/ndi.rs | 1 + src/ndisink/imp.rs | 28 ++++----- src/ndisink/mod.rs | 2 +- src/ndisinkcombiner/imp.rs | 68 ++++++++++----------- src/ndisinkcombiner/mod.rs | 2 +- src/ndisrc/imp.rs | 48 +++++++-------- src/ndisrc/mod.rs | 2 +- src/ndisrcdemux/imp.rs | 16 ++--- src/ndisrcdemux/mod.rs | 2 +- src/receiver.rs | 118 ++++++++++++++++++------------------- 13 files changed, 159 insertions(+), 158 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9544708..ff224fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,11 +8,11 @@ description = "NewTek NDI Plugin" edition = "2018" [dependencies] -glib = "0.15" -gst = { package = "gstreamer", version = "0.18", features = ["v1_12"] } -gst-base = { package = "gstreamer-base", version = "0.18" } -gst-audio = { package = "gstreamer-audio", version = "0.18" } -gst-video = { package = "gstreamer-video", version = "0.18", features = ["v1_12"] } +glib = "0.20" +gst = { package = "gstreamer", version = "0.23" } +gst-base = { package = "gstreamer-base", version = "0.23" } +gst-audio = { package = "gstreamer-audio", version = "0.23" } +gst-video = { package = "gstreamer-video", version = "0.23" } byte-slice-cast = "1" once_cell = "1.0" byteorder = "1.0" @@ -23,7 +23,7 @@ gst-plugin-version-helper = "0.7" [features] default = ["interlaced-fields", "reference-timestamps", "sink"] interlaced-fields = ["gst/v1_16", "gst-video/v1_16"] -reference-timestamps = ["gst/v1_14"] +reference-timestamps = [] sink = ["gst/v1_18", "gst-base/v1_18"] advanced-sdk = [] diff --git a/src/device_provider/imp.rs b/src/device_provider/imp.rs index 8484511..62e4dce 100644 --- a/src/device_provider/imp.rs +++ b/src/device_provider/imp.rs @@ -1,6 +1,6 @@ use gst::prelude::*; use gst::subclass::prelude::*; -use gst::{gst_error, gst_log, gst_trace}; +use gst::{error, log, trace}; use once_cell::sync::OnceCell; @@ -72,7 +72,7 @@ impl DeviceProviderImpl for DeviceProvider { fn start(&self, device_provider: &Self::Type) -> Result<(), gst::LoggableError> { let mut thread_guard = self.thread.lock().unwrap(); if thread_guard.is_some() { - gst_log!(CAT, obj: device_provider, "Device provider already started"); + log!(CAT, obj = device_provider, "Device provider already started"); return Ok(()); } @@ -90,13 +90,13 @@ impl DeviceProviderImpl for DeviceProvider { { let mut find_guard = imp.find.lock().unwrap(); if find_guard.is_some() { - gst_log!(CAT, obj: &device_provider, "Already started"); + log!(CAT, obj = &device_provider, "Already started"); return; } let find = match ndi::FindInstance::builder().build() { None => { - gst_error!(CAT, obj: &device_provider, "Failed to create Find instance"); + error!(CAT, obj = &device_provider, "Failed to create Find instance"); return; } Some(find) => find, @@ -140,7 +140,7 @@ impl DeviceProvider { }; if !find.wait_for_sources(if first { 1000 } else { 5000 }) { - gst_trace!(CAT, obj: device_provider, "No new sources found"); + trace!(CAT, obj = device_provider, "No new sources found"); return; } @@ -157,9 +157,9 @@ impl DeviceProvider { let old_source = old_device_imp.source.get().unwrap(); if !sources.contains(&*old_source) { - gst_log!( + log!( CAT, - obj: device_provider, + obj = device_provider, "Source {:?} disappeared", old_source ); @@ -184,7 +184,7 @@ impl DeviceProvider { // Now go through all new devices and announce them for source in sources { - gst_log!(CAT, obj: device_provider, "Source {:?} appeared", source); + log!(CAT, obj = device_provider, "Source {:?} appeared", source); let device = super::Device::new(&source); device_provider.device_add(&device); current_devices_guard.push(device); diff --git a/src/device_provider/mod.rs b/src/device_provider/mod.rs index cda26ec..872ec6c 100644 --- a/src/device_provider/mod.rs +++ b/src/device_provider/mod.rs @@ -20,7 +20,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { gst::DeviceProvider::register( Some(plugin), "ndideviceprovider", - gst::Rank::Primary, + gst::Rank::PRIMARY, DeviceProvider::static_type(), ) } diff --git a/src/ndi.rs b/src/ndi.rs index 24507b8..305f021 100644 --- a/src/ndi.rs +++ b/src/ndi.rs @@ -5,6 +5,7 @@ use std::mem; use std::ptr; use byte_slice_cast::*; +use gst_video::VideoFrameExt as _; pub fn initialize() -> bool { unsafe { NDIlib_initialize() } diff --git a/src/ndisink/imp.rs b/src/ndisink/imp.rs index 86c3103..c43fb8b 100644 --- a/src/ndisink/imp.rs +++ b/src/ndisink/imp.rs @@ -1,7 +1,7 @@ use glib::subclass::prelude::*; use gst::prelude::*; use gst::subclass::prelude::*; -use gst::{gst_debug, gst_error, gst_info, gst_trace}; +use gst::{debug, error, info, trace}; use gst_base::prelude::*; use gst_base::subclass::prelude::*; @@ -195,7 +195,7 @@ impl BaseSinkImpl for NdiSink { audio_info: None, }; *state_storage = Some(state); - gst_info!(CAT, obj: element, "Started"); + info!(CAT, obj = element, "Started"); Ok(()) } @@ -204,7 +204,7 @@ impl BaseSinkImpl for NdiSink { let mut state_storage = self.state.lock().unwrap(); *state_storage = None; - gst_info!(CAT, obj: element, "Stopped"); + info!(CAT, obj = element, "Stopped"); Ok(()) } @@ -218,7 +218,7 @@ impl BaseSinkImpl for NdiSink { } fn set_caps(&self, element: &Self::Type, caps: &gst::Caps) -> Result<(), gst::LoggableError> { - gst_debug!(CAT, obj: element, "Setting caps {}", caps); + debug!(CAT, obj = element, "Setting caps {}", caps); let mut state_storage = self.state.lock().unwrap(); let state = match &mut *state_storage { @@ -260,13 +260,13 @@ impl BaseSinkImpl for NdiSink { for (buffer, info, timecode) in audio_meta.buffers() { let frame = crate::ndi::AudioFrame::try_from_buffer(info, buffer, *timecode) .map_err(|_| { - gst_error!(CAT, obj: element, "Unsupported audio frame"); + error!(CAT, obj = element, "Unsupported audio frame"); gst::FlowError::NotNegotiated })?; - gst_trace!( + trace!( CAT, - obj: element, + obj = element, "Sending audio buffer {:?} with timecode {} and format {:?}", buffer, if *timecode < 0 { @@ -297,19 +297,19 @@ impl BaseSinkImpl for NdiSink { let frame = gst_video::VideoFrameRef::from_buffer_ref_readable(buffer, info) .map_err(|_| { - gst_error!(CAT, obj: element, "Failed to map buffer"); + error!(CAT, obj = element, "Failed to map buffer"); gst::FlowError::Error })?; let frame = crate::ndi::VideoFrame::try_from_video_frame(&frame, timecode) .map_err(|_| { - gst_error!(CAT, obj: element, "Unsupported video frame"); + error!(CAT, obj = element, "Unsupported video frame"); gst::FlowError::NotNegotiated })?; - gst_trace!( + trace!( CAT, - obj: element, + obj = element, "Sending video buffer {:?} with timecode {} and format {:?}", buffer, if timecode < 0 { @@ -337,13 +337,13 @@ impl BaseSinkImpl for NdiSink { let frame = crate::ndi::AudioFrame::try_from_buffer(info, buffer, timecode).map_err(|_| { - gst_error!(CAT, obj: element, "Unsupported audio frame"); + error!(CAT, obj = element, "Unsupported audio frame"); gst::FlowError::NotNegotiated })?; - gst_trace!( + trace!( CAT, - obj: element, + obj = element, "Sending audio buffer {:?} with timecode {} and format {:?}", buffer, if timecode < 0 { diff --git a/src/ndisink/mod.rs b/src/ndisink/mod.rs index 8d6d955..737a795 100644 --- a/src/ndisink/mod.rs +++ b/src/ndisink/mod.rs @@ -13,7 +13,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { gst::Element::register( Some(plugin), "ndisink", - gst::Rank::None, + gst::Rank::NONE, NdiSink::static_type(), ) } diff --git a/src/ndisinkcombiner/imp.rs b/src/ndisinkcombiner/imp.rs index 20fd881..1a033b2 100644 --- a/src/ndisinkcombiner/imp.rs +++ b/src/ndisinkcombiner/imp.rs @@ -2,7 +2,7 @@ use glib::prelude::*; use glib::subclass::prelude::*; use gst::prelude::*; use gst::subclass::prelude::*; -use gst::{gst_debug, gst_error, gst_trace, gst_warning}; +use gst::{debug, error, trace, warning}; use gst_base::prelude::*; use gst_base::subclass::prelude::*; @@ -151,7 +151,7 @@ impl ElementImpl for NdiSinkCombiner { let mut audio_pad_storage = self.audio_pad.lock().unwrap(); if audio_pad_storage.as_ref().map(|p| p.upcast_ref()) == Some(pad) { - gst_debug!(CAT, obj: element, "Release audio pad"); + debug!(CAT, obj = element, "Release audio pad"); self.parent_release_pad(element, pad); *audio_pad_storage = None; } @@ -169,13 +169,13 @@ impl AggregatorImpl for NdiSinkCombiner { let mut audio_pad_storage = self.audio_pad.lock().unwrap(); if audio_pad_storage.is_some() { - gst_error!(CAT, obj: agg, "Audio pad already requested"); + error!(CAT, obj = agg, "Audio pad already requested"); return None; } let sink_templ = agg.pad_template("audio").unwrap(); if templ != &sink_templ { - gst_error!(CAT, obj: agg, "Wrong pad template"); + error!(CAT, obj = agg, "Wrong pad template"); return None; } @@ -183,7 +183,7 @@ impl AggregatorImpl for NdiSinkCombiner { gst::PadBuilder::::from_template(templ, Some("audio")).build(); *audio_pad_storage = Some(pad.clone()); - gst_debug!(CAT, obj: agg, "Requested audio pad"); + debug!(CAT, obj = agg, "Requested audio pad"); Some(pad) } @@ -197,7 +197,7 @@ impl AggregatorImpl for NdiSinkCombiner { current_audio_buffers: Vec::new(), }); - gst_debug!(CAT, obj: agg, "Started"); + debug!(CAT, obj = agg, "Started"); Ok(()) } @@ -206,7 +206,7 @@ impl AggregatorImpl for NdiSinkCombiner { // Drop our state now let _ = self.state.lock().unwrap().take(); - gst_debug!(CAT, obj: agg, "Stopped"); + debug!(CAT, obj = agg, "Stopped"); Ok(()) } @@ -225,22 +225,22 @@ impl AggregatorImpl for NdiSinkCombiner { let segment = match agg_pad.segment().downcast::() { Ok(segment) => segment, Err(_) => { - gst_error!(CAT, obj: agg, "Only TIME segments supported"); + error!(CAT, obj = agg, "Only TIME segments supported"); return Some(buffer); } }; let pts = buffer.pts(); if pts.is_none() { - gst_error!(CAT, obj: agg, "Only buffers with PTS supported"); + error!(CAT, obj = agg, "Only buffers with PTS supported"); return Some(buffer); } let duration = buffer.duration(); - gst_trace!( + trace!( CAT, - obj: agg_pad, + obj = agg_pad, "Clipping buffer {:?} with PTS {} and duration {}", buffer, pts.display(), @@ -273,9 +273,9 @@ impl AggregatorImpl for NdiSinkCombiner { unreachable!() }; - gst_debug!( + debug!( CAT, - obj: agg_pad, + obj = agg_pad, "Clipping buffer {:?} with PTS {} and duration {}", buffer, pts.display(), @@ -329,9 +329,9 @@ impl AggregatorImpl for NdiSinkCombiner { let video_segment = match video_segment.downcast::() { Ok(video_segment) => video_segment, Err(video_segment) => { - gst_error!( + error!( CAT, - obj: agg, + obj = agg, "Video segment of wrong format {:?}", video_segment.format() ); @@ -342,7 +342,7 @@ impl AggregatorImpl for NdiSinkCombiner { Some((video_buffer, video_segment)) } None if !self.video_pad.is_eos() => { - gst_trace!(CAT, obj: agg, "Waiting for video buffer"); + trace!(CAT, obj = agg, "Waiting for video buffer"); return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA); } None => None, @@ -354,7 +354,7 @@ impl AggregatorImpl for NdiSinkCombiner { Some(audio_buffer) if audio_buffer.size() == 0 => { // Skip empty/gap audio buffer audio_pad.drop_buffer(); - gst_trace!(CAT, obj: agg, "Empty audio buffer, waiting for next"); + trace!(CAT, obj = agg, "Empty audio buffer, waiting for next"); return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA); } Some(audio_buffer) => { @@ -362,9 +362,9 @@ impl AggregatorImpl for NdiSinkCombiner { let audio_segment = match audio_segment.downcast::() { Ok(audio_segment) => audio_segment, Err(audio_segment) => { - gst_error!( + error!( CAT, - obj: agg, + obj = agg, "Audio segment of wrong format {:?}", audio_segment.format() ); @@ -375,7 +375,7 @@ impl AggregatorImpl for NdiSinkCombiner { Some((audio_buffer, audio_segment, audio_pad)) } None if !audio_pad.is_eos() => { - gst_trace!(CAT, obj: agg, "Waiting for audio buffer"); + trace!(CAT, obj = agg, "Waiting for audio buffer"); return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA); } None => None, @@ -396,7 +396,7 @@ impl AggregatorImpl for NdiSinkCombiner { match state.current_video_buffer { None => { - gst_trace!(CAT, obj: agg, "First video buffer, waiting for second"); + trace!(CAT, obj = agg, "First video buffer, waiting for second"); state.current_video_buffer = Some((video_buffer, video_running_time)); drop(state_storage); self.video_pad.drop_buffer(); @@ -411,9 +411,9 @@ impl AggregatorImpl for NdiSinkCombiner { } else { match (&state.current_video_buffer, &audio_buffer_segment_and_pad) { (None, None) => { - gst_trace!( + trace!( CAT, - obj: agg, + obj = agg, "All pads are EOS and no buffers are queued, finishing" ); return Err(gst::FlowError::Eos); @@ -428,9 +428,9 @@ impl AggregatorImpl for NdiSinkCombiner { let video_segment = match video_segment.downcast::() { Ok(video_segment) => video_segment, Err(video_segment) => { - gst_error!( + error!( CAT, - obj: agg, + obj = agg, "Video segment of wrong format {:?}", video_segment.format() ); @@ -440,7 +440,7 @@ impl AggregatorImpl for NdiSinkCombiner { let video_pts = video_segment.position_from_running_time(audio_running_time); if video_pts.is_none() { - gst_warning!(CAT, obj: agg, "Can't output more audio after video EOS"); + warning!(CAT, obj = agg, "Can't output more audio after video EOS"); return Err(gst::FlowError::Eos); } @@ -460,7 +460,7 @@ impl AggregatorImpl for NdiSinkCombiner { let audio_info = match state.audio_info { Some(ref audio_info) => audio_info, None => { - gst_error!(CAT, obj: agg, "Have no audio caps"); + error!(CAT, obj = agg, "Have no audio caps"); return Err(gst::FlowError::NotNegotiated); } }; @@ -487,9 +487,9 @@ impl AggregatorImpl for NdiSinkCombiner { }) .unwrap_or(crate::ndisys::NDIlib_send_timecode_synthesize); - gst_trace!( + trace!( CAT, - obj: agg, + obj = agg, "Including audio buffer {:?} with timecode {}: {} <= {}", audio_buffer, timecode, @@ -528,9 +528,9 @@ impl AggregatorImpl for NdiSinkCombiner { drop(state_storage); } - gst_trace!( + trace!( CAT, - obj: agg, + obj = agg, "Finishing video buffer {:?}", current_video_buffer ); @@ -559,7 +559,7 @@ impl AggregatorImpl for NdiSinkCombiner { let info = match gst_video::VideoInfo::from_caps(&caps) { Ok(info) => info, Err(_) => { - gst_error!(CAT, obj: pad, "Failed to parse caps {:?}", caps); + error!(CAT, obj = pad, "Failed to parse caps {:?}", caps); return false; } }; @@ -587,7 +587,7 @@ impl AggregatorImpl for NdiSinkCombiner { let info = match gst_audio::AudioInfo::from_caps(&caps) { Ok(info) => info, Err(_) => { - gst_error!(CAT, obj: pad, "Failed to parse caps {:?}", caps); + error!(CAT, obj = pad, "Failed to parse caps {:?}", caps); return false; } }; @@ -598,7 +598,7 @@ impl AggregatorImpl for NdiSinkCombiner { // The video segment is passed through as-is and the video timestamps are preserved EventView::Segment(segment) if pad == &self.video_pad => { let segment = segment.segment(); - gst_debug!(CAT, obj: agg, "Updating segment {:?}", segment); + debug!(CAT, obj = agg, "Updating segment {:?}", segment); agg.update_segment(segment); } _ => (), diff --git a/src/ndisinkcombiner/mod.rs b/src/ndisinkcombiner/mod.rs index b86c4ca..66b8f04 100644 --- a/src/ndisinkcombiner/mod.rs +++ b/src/ndisinkcombiner/mod.rs @@ -13,7 +13,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { gst::Element::register( Some(plugin), "ndisinkcombiner", - gst::Rank::None, + gst::Rank::NONE, NdiSinkCombiner::static_type(), ) } diff --git a/src/ndisrc/imp.rs b/src/ndisrc/imp.rs index 8bed052..bdf37ac 100644 --- a/src/ndisrc/imp.rs +++ b/src/ndisrc/imp.rs @@ -1,6 +1,6 @@ use gst::prelude::*; use gst::subclass::prelude::*; -use gst::{gst_debug, gst_error}; +use gst::{debug, error}; use gst_base::prelude::*; use gst_base::subclass::base_src::CreateSuccess; use gst_base::subclass::prelude::*; @@ -204,9 +204,9 @@ impl ObjectImpl for NdiSrc { "ndi-name" => { let mut settings = self.settings.lock().unwrap(); let ndi_name = value.get().unwrap(); - gst_debug!( + debug!( CAT, - obj: obj, + obj = obj, "Changing ndi-name from {:?} to {:?}", settings.ndi_name, ndi_name, @@ -216,9 +216,9 @@ impl ObjectImpl for NdiSrc { "url-address" => { let mut settings = self.settings.lock().unwrap(); let url_address = value.get().unwrap(); - gst_debug!( + debug!( CAT, - obj: obj, + obj = obj, "Changing url-address from {:?} to {:?}", settings.url_address, url_address, @@ -228,9 +228,9 @@ impl ObjectImpl for NdiSrc { "receiver-ndi-name" => { let mut settings = self.settings.lock().unwrap(); let receiver_ndi_name = value.get::>().unwrap(); - gst_debug!( + debug!( CAT, - obj: obj, + obj = obj, "Changing receiver-ndi-name from {:?} to {:?}", settings.receiver_ndi_name, receiver_ndi_name, @@ -241,9 +241,9 @@ impl ObjectImpl for NdiSrc { "connect-timeout" => { let mut settings = self.settings.lock().unwrap(); let connect_timeout = value.get().unwrap(); - gst_debug!( + debug!( CAT, - obj: obj, + obj = obj, "Changing connect-timeout from {} to {}", settings.connect_timeout, connect_timeout, @@ -253,9 +253,9 @@ impl ObjectImpl for NdiSrc { "timeout" => { let mut settings = self.settings.lock().unwrap(); let timeout = value.get().unwrap(); - gst_debug!( + debug!( CAT, - obj: obj, + obj = obj, "Changing timeout from {} to {}", settings.timeout, timeout, @@ -265,9 +265,9 @@ impl ObjectImpl for NdiSrc { "max-queue-length" => { let mut settings = self.settings.lock().unwrap(); let max_queue_length = value.get().unwrap(); - gst_debug!( + debug!( CAT, - obj: obj, + obj = obj, "Changing max-queue-length from {} to {}", settings.max_queue_length, max_queue_length, @@ -277,9 +277,9 @@ impl ObjectImpl for NdiSrc { "bandwidth" => { let mut settings = self.settings.lock().unwrap(); let bandwidth = value.get().unwrap(); - gst_debug!( + debug!( CAT, - obj: obj, + obj = obj, "Changing bandwidth from {} to {}", settings.bandwidth, bandwidth, @@ -289,9 +289,9 @@ impl ObjectImpl for NdiSrc { "color-format" => { let mut settings = self.settings.lock().unwrap(); let color_format = value.get().unwrap(); - gst_debug!( + debug!( CAT, - obj: obj, + obj = obj, "Changing color format from {:?} to {:?}", settings.color_format, color_format, @@ -301,9 +301,9 @@ impl ObjectImpl for NdiSrc { "timestamp-mode" => { let mut settings = self.settings.lock().unwrap(); let timestamp_mode = value.get().unwrap(); - gst_debug!( + debug!( CAT, - obj: obj, + obj = obj, "Changing timestamp mode from {:?} to {:?}", settings.timestamp_mode, timestamp_mode @@ -428,7 +428,7 @@ impl BaseSrcImpl for NdiSrc { } fn unlock(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> { - gst_debug!(CAT, obj: element, "Unlocking",); + debug!(CAT, obj = element, "Unlocking",); if let Some(ref controller) = *self.receiver_controller.lock().unwrap() { controller.set_flushing(true); } @@ -436,7 +436,7 @@ impl BaseSrcImpl for NdiSrc { } fn unlock_stop(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> { - gst_debug!(CAT, obj: element, "Stop unlocking",); + debug!(CAT, obj = element, "Stop unlocking",); if let Some(ref controller) = *self.receiver_controller.lock().unwrap() { controller.set_flushing(false); } @@ -516,9 +516,9 @@ impl BaseSrcImpl for NdiSrc { let max = settings.max_queue_length as u64 * latency; - gst_debug!( + debug!( CAT, - obj: element, + obj = element, "Returning latency min {} max {}", min, max @@ -545,7 +545,7 @@ impl BaseSrcImpl for NdiSrc { match state.receiver.take() { Some(recv) => recv, None => { - gst_error!(CAT, obj: element, "Have no receiver"); + error!(CAT, obj = element, "Have no receiver"); return Err(gst::FlowError::Error); } } diff --git a/src/ndisrc/mod.rs b/src/ndisrc/mod.rs index e603d69..69add73 100644 --- a/src/ndisrc/mod.rs +++ b/src/ndisrc/mod.rs @@ -13,7 +13,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { gst::Element::register( Some(plugin), "ndisrc", - gst::Rank::None, + gst::Rank::NONE, NdiSrc::static_type(), ) } diff --git a/src/ndisrcdemux/imp.rs b/src/ndisrcdemux/imp.rs index a9589a7..11a33ea 100644 --- a/src/ndisrcdemux/imp.rs +++ b/src/ndisrcdemux/imp.rs @@ -1,6 +1,6 @@ use gst::prelude::*; use gst::subclass::prelude::*; -use gst::{gst_debug, gst_error, gst_log}; +use gst::{debug, error, log}; use std::sync::Mutex; @@ -156,10 +156,10 @@ impl NdiSrcDemux { element: &super::NdiSrcDemux, mut buffer: gst::Buffer, ) -> Result { - gst_log!(CAT, obj: pad, "Handling buffer {:?}", buffer); + log!(CAT, obj = pad, "Handling buffer {:?}", buffer); let meta = buffer.make_mut().meta_mut::().ok_or_else(|| { - gst_error!(CAT, obj: element, "Buffer without NDI source meta"); + error!(CAT, obj = element, "Buffer without NDI source meta"); gst::FlowError::Error })?; @@ -174,7 +174,7 @@ impl NdiSrcDemux { if let Some(ref pad) = state.audio_pad { srcpad = pad.clone(); } else { - gst_debug!(CAT, obj: element, "Adding audio pad with caps {}", caps); + debug!(CAT, obj = element, "Adding audio pad with caps {}", caps); let klass = element.element_class(); let templ = klass.pad_template("audio").unwrap(); @@ -215,7 +215,7 @@ impl NdiSrcDemux { } if state.audio_caps.as_ref() != Some(&caps) { - gst_debug!(CAT, obj: element, "Audio caps changed to {}", caps); + debug!(CAT, obj = element, "Audio caps changed to {}", caps); events.push(gst::event::Caps::new(&caps)); state.audio_caps = Some(caps); } @@ -224,7 +224,7 @@ impl NdiSrcDemux { if let Some(ref pad) = state.video_pad { srcpad = pad.clone(); } else { - gst_debug!(CAT, obj: element, "Adding video pad with caps {}", caps); + debug!(CAT, obj = element, "Adding video pad with caps {}", caps); let klass = element.element_class(); let templ = klass.pad_template("video").unwrap(); @@ -265,7 +265,7 @@ impl NdiSrcDemux { } if state.video_caps.as_ref() != Some(&caps) { - gst_debug!(CAT, obj: element, "Video caps changed to {}", caps); + debug!(CAT, obj = element, "Video caps changed to {}", caps); events.push(gst::event::Caps::new(&caps)); state.video_caps = Some(caps); } @@ -295,7 +295,7 @@ impl NdiSrcDemux { ) -> bool { use gst::EventView; - gst_log!(CAT, obj: pad, "Handling event {:?}", event); + log!(CAT, obj = pad, "Handling event {:?}", event); if let EventView::Eos(_) = event.view() { if element.num_src_pads() == 0 { // error out on EOS if no src pad are available diff --git a/src/ndisrcdemux/mod.rs b/src/ndisrcdemux/mod.rs index 12c78f7..422fe28 100644 --- a/src/ndisrcdemux/mod.rs +++ b/src/ndisrcdemux/mod.rs @@ -13,7 +13,7 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { gst::Element::register( Some(plugin), "ndisrcdemux", - gst::Rank::Primary, + gst::Rank::PRIMARY, NdiSrcDemux::static_type(), ) } diff --git a/src/receiver.rs b/src/receiver.rs index 15514f9..2a18d54 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -1,6 +1,6 @@ use glib::prelude::*; use gst::prelude::*; -use gst::{gst_debug, gst_error, gst_log, gst_trace, gst_warning}; +use gst::{debug, error, log, trace, warning}; use gst_video::prelude::*; use byte_slice_cast::*; @@ -271,9 +271,9 @@ impl Observations { let remote_time = time.0.nseconds(); let local_time = time.1.nseconds(); - gst_trace!( + trace!( CAT, - obj: element, + obj = element, "Local time {}, remote time {}", gst::ClockTime::from_nseconds(local_time), gst::ClockTime::from_nseconds(remote_time), @@ -285,9 +285,9 @@ impl Observations { match (inner.base_remote_time, inner.base_local_time) { (Some(remote), Some(local)) => (remote, local), _ => { - gst_debug!( + debug!( CAT, - obj: element, + obj = element, "Initializing base time: local {}, remote {}", gst::ClockTime::from_nseconds(local_time), gst::ClockTime::from_nseconds(remote_time), @@ -303,9 +303,9 @@ impl Observations { let local_diff = local_time.saturating_sub(base_local_time); let delta = (local_diff as i64) - (remote_diff as i64); - gst_trace!( + trace!( CAT, - obj: element, + obj = element, "Local diff {}, remote diff {}, delta {}", gst::ClockTime::from_nseconds(local_diff), gst::ClockTime::from_nseconds(remote_diff), @@ -315,9 +315,9 @@ impl Observations { if remote_diff > 0 && local_diff > 0 { let slope = (local_diff as f64) / (remote_diff as f64); if !(0.8..1.2).contains(&slope) { - gst_warning!( + warning!( CAT, - obj: element, + obj = element, "Too small/big slope {}, resetting", slope ); @@ -325,9 +325,9 @@ impl Observations { let discont = !inner.deltas.is_empty(); *inner = ObservationsInner::default(); - gst_debug!( + debug!( CAT, - obj: element, + obj = element, "Initializing base time: local {}, remote {}", gst::ClockTime::from_nseconds(local_time), gst::ClockTime::from_nseconds(remote_time), @@ -342,9 +342,9 @@ impl Observations { if (delta > inner.skew && delta - inner.skew > 1_000_000_000) || (delta < inner.skew && inner.skew - delta > 1_000_000_000) { - gst_warning!( + warning!( CAT, - obj: element, + obj = element, "Delta {} too far from skew {}, resetting", delta, inner.skew @@ -353,9 +353,9 @@ impl Observations { let discont = !inner.deltas.is_empty(); *inner = ObservationsInner::default(); - gst_debug!( + debug!( CAT, - obj: element, + obj = element, "Initializing base time: local {}, remote {}", gst::ClockTime::from_nseconds(local_time), gst::ClockTime::from_nseconds(remote_time), @@ -405,16 +405,16 @@ impl Observations { out_time + (inner.skew as u64) }; - gst_trace!( + trace!( CAT, - obj: element, + obj = element, "Skew {}, min delta {}", inner.skew, inner.min_delta ); - gst_trace!( + trace!( CAT, - obj: element, + obj = element, "Outputting {}", gst::ClockTime::from_nseconds(out_time) ); @@ -457,7 +457,7 @@ impl Drop for ReceiverInner { let element = self.element.upgrade(); if let Some(ref element) = element { - gst_debug!(CAT, obj: element, "Closed NDI connection"); + debug!(CAT, obj = element, "Closed NDI connection"); } } } @@ -576,13 +576,13 @@ impl Receiver { timeout: u32, max_queue_length: usize, ) -> Option { - gst_debug!(CAT, obj: element, "Starting NDI connection..."); + debug!(CAT, obj = element, "Starting NDI connection..."); assert!(ndi_name.is_some() || url_address.is_some()); - gst_debug!( + debug!( CAT, - obj: element, + obj = element, "Connecting to NDI source with NDI name '{:?}' and URL/Address {:?}", ndi_name, url_address, @@ -646,13 +646,13 @@ impl Receiver { let flushing = { let queue = (receiver.0.queue.0).0.lock().unwrap(); if queue.shutdown { - gst_debug!(CAT, obj: &element, "Shutting down"); + debug!(CAT, obj = &element, "Shutting down"); break; } // If an error happened in the meantime, just go out of here if queue.error.is_some() { - gst_error!(CAT, obj: &element, "Error while waiting for connection"); + error!(CAT, obj = &element, "Error while waiting for connection"); return; } @@ -667,7 +667,7 @@ impl Receiver { let res = match recv.capture(50) { _ if flushing => { - gst_debug!(CAT, obj: &element, "Flushing"); + debug!(CAT, obj = &element, "Flushing"); Err(gst::FlowError::Flushing) } Err(_) => { @@ -679,11 +679,11 @@ impl Receiver { Err(gst::FlowError::Error) } Ok(None) if timeout > 0 && timer.elapsed().as_millis() >= timeout as u128 => { - gst_debug!(CAT, obj: &element, "Timed out -- assuming EOS",); + debug!(CAT, obj = &element, "Timed out -- assuming EOS",); Err(gst::FlowError::Eos) } Ok(None) => { - gst_debug!(CAT, obj: &element, "No frame received yet, retry"); + debug!(CAT, obj = &element, "No frame received yet, retry"); continue; } Ok(Some(Frame::Video(frame))) => { @@ -716,9 +716,9 @@ impl Receiver { } Ok(Some(Frame::Metadata(frame))) => { if let Some(metadata) = frame.metadata() { - gst_debug!( + debug!( CAT, - obj: &element, + obj = &element, "Received metadata at timecode {}: {}", gst::ClockTime::from_nseconds(frame.timecode() as u64 * 100), metadata, @@ -733,9 +733,9 @@ impl Receiver { Ok(item) => { let mut queue = (receiver.0.queue.0).0.lock().unwrap(); while queue.buffer_queue.len() > receiver.0.max_queue_length { - gst_warning!( + warning!( CAT, - obj: &element, + obj = &element, "Dropping old buffer -- queue has {} items", queue.buffer_queue.len() ); @@ -746,7 +746,7 @@ impl Receiver { timer = time::Instant::now(); } Err(gst::FlowError::Eos) => { - gst_debug!(CAT, obj: &element, "Signalling EOS"); + debug!(CAT, obj = &element, "Signalling EOS"); let mut queue = (receiver.0.queue.0).0.lock().unwrap(); queue.timeout = true; (receiver.0.queue.0).1.notify_one(); @@ -760,7 +760,7 @@ impl Receiver { timer = time::Instant::now(); } Err(err) => { - gst_error!(CAT, obj: &element, "Signalling error"); + error!(CAT, obj = &element, "Signalling error"); let mut queue = (receiver.0.queue.0).0.lock().unwrap(); if queue.error.is_none() { queue.error = Some(err); @@ -789,9 +789,9 @@ impl Receiver { }; let timecode = gst::ClockTime::from_nseconds(timecode as u64 * 100); - gst_log!( + log!( CAT, - obj: element, + obj = element, "Received frame with timecode {}, timestamp {}, duration {}, receive time {}, local time now {}", timecode, timestamp.display(), @@ -831,9 +831,9 @@ impl Receiver { TimestampMode::ReceiveTime => (receive_time, duration, false), }; - gst_log!( + log!( CAT, - obj: element, + obj = element, "Calculated PTS {}, duration {}", pts.display(), duration.display(), @@ -847,12 +847,12 @@ impl Receiver { element: &gst_base::BaseSrc, video_frame: VideoFrame, ) -> Result { - gst_debug!(CAT, obj: element, "Received video frame {:?}", video_frame); + debug!(CAT, obj = element, "Received video frame {:?}", video_frame); let (pts, duration, discont) = self .calculate_video_timestamp(element, &video_frame) .ok_or_else(|| { - gst_debug!(CAT, obj: element, "Flushing, dropping buffer"); + debug!(CAT, obj = element, "Flushing, dropping buffer"); gst::FlowError::Flushing })?; @@ -866,7 +866,7 @@ impl Receiver { .set_flags(gst::BufferFlags::RESYNC); } - gst_log!(CAT, obj: element, "Produced video buffer {:?}", buffer); + log!(CAT, obj = element, "Produced video buffer {:?}", buffer); Ok(Buffer::Video(buffer, info)) } @@ -1067,9 +1067,9 @@ impl Receiver { .contains(&fourcc) { let compressed_packet = video_frame.compressed_packet().ok_or_else(|| { - gst_error!( + error!( CAT, - obj: element, + obj = element, "Video packet doesn't have compressed packet start" ); gst::element_error!(element, gst::StreamError::Format, ["Invalid video packet"]); @@ -1078,7 +1078,7 @@ impl Receiver { })?; if compressed_packet.fourcc != NDIlib_compressed_FourCC_type_H264 { - gst_error!(CAT, obj: element, "Non-H264 video packet"); + error!(CAT, obj = element, "Non-H264 video packet"); gst::element_error!(element, gst::StreamError::Format, ["Invalid video packet"]); return Err(gst::FlowError::Error); @@ -1105,9 +1105,9 @@ impl Receiver { .contains(&fourcc) { let compressed_packet = video_frame.compressed_packet().ok_or_else(|| { - gst_error!( + error!( CAT, - obj: element, + obj = element, "Video packet doesn't have compressed packet start" ); gst::element_error!(element, gst::StreamError::Format, ["Invalid video packet"]); @@ -1116,7 +1116,7 @@ impl Receiver { })?; if compressed_packet.fourcc != NDIlib_compressed_FourCC_type_HEVC { - gst_error!(CAT, obj: element, "Non-H265 video packet"); + error!(CAT, obj = element, "Non-H265 video packet"); gst::element_error!(element, gst::StreamError::Format, ["Invalid video packet"]); return Err(gst::FlowError::Error); @@ -1347,7 +1347,7 @@ impl Receiver { #[cfg(feature = "advanced-sdk")] VideoInfo::SpeedHQInfo { .. } => { let data = video_frame.data().ok_or_else(|| { - gst_error!(CAT, obj: element, "Video packet has no data"); + error!(CAT, obj = element, "Video packet has no data"); gst::element_error!( element, gst::StreamError::Format, @@ -1362,9 +1362,9 @@ impl Receiver { #[cfg(feature = "advanced-sdk")] VideoInfo::H264Info { .. } | VideoInfo::H265Info { .. } => { let compressed_packet = video_frame.compressed_packet().ok_or_else(|| { - gst_error!( + error!( CAT, - obj: element, + obj = element, "Video packet doesn't have compressed packet start" ); gst::element_error!( @@ -1397,12 +1397,12 @@ impl Receiver { element: &gst_base::BaseSrc, audio_frame: AudioFrame, ) -> Result { - gst_debug!(CAT, obj: element, "Received audio frame {:?}", audio_frame); + debug!(CAT, obj = element, "Received audio frame {:?}", audio_frame); let (pts, duration, discont) = self .calculate_audio_timestamp(element, &audio_frame) .ok_or_else(|| { - gst_debug!(CAT, obj: element, "Flushing, dropping buffer"); + debug!(CAT, obj = element, "Flushing, dropping buffer"); gst::FlowError::Flushing })?; @@ -1416,7 +1416,7 @@ impl Receiver { .set_flags(gst::BufferFlags::RESYNC); } - gst_log!(CAT, obj: element, "Produced audio buffer {:?}", buffer); + log!(CAT, obj = element, "Produced audio buffer {:?}", buffer); Ok(Buffer::Audio(buffer, info)) } @@ -1471,9 +1471,9 @@ impl Receiver { use std::convert::TryInto; let compressed_packet = audio_frame.compressed_packet().ok_or_else(|| { - gst_error!( + error!( CAT, - obj: element, + obj = element, "Audio packet doesn't have compressed packet start" ); gst::element_error!(element, gst::StreamError::Format, ["Invalid audio packet"]); @@ -1482,7 +1482,7 @@ impl Receiver { })?; if compressed_packet.fourcc != NDIlib_compressed_FourCC_type_AAC { - gst_error!(CAT, obj: element, "Non-AAC audio packet"); + error!(CAT, obj = element, "Non-AAC audio packet"); gst::element_error!(element, gst::StreamError::Format, ["Invalid audio packet"]); return Err(gst::FlowError::Error); @@ -1580,7 +1580,7 @@ impl Receiver { #[cfg(feature = "advanced-sdk")] AudioInfo::OpusInfo { .. } => { let data = audio_frame.data().ok_or_else(|| { - gst_error!(CAT, obj: element, "Audio packet has no data"); + error!(CAT, obj = element, "Audio packet has no data"); gst::element_error!( element, gst::StreamError::Format, @@ -1595,9 +1595,9 @@ impl Receiver { #[cfg(feature = "advanced-sdk")] AudioInfo::AacInfo { .. } => { let compressed_packet = audio_frame.compressed_packet().ok_or_else(|| { - gst_error!( + error!( CAT, - obj: element, + obj = element, "Audio packet doesn't have compressed packet start" ); gst::element_error!( From 5f9add355a268009cdf2b46fe4d6f7e33854d44e Mon Sep 17 00:00:00 2001 From: Clouds Flowing Date: Thu, 14 Nov 2024 18:09:28 +0800 Subject: [PATCH 2/2] fix build --- src/device_provider/imp.rs | 47 +++++----- src/lib.rs | 4 +- src/ndisink/imp.rs | 34 +++---- src/ndisinkcombiner/imp.rs | 45 ++++----- src/ndisrc/imp.rs | 182 +++++++++++++++++-------------------- src/ndisrcdemux/imp.rs | 25 ++--- 6 files changed, 161 insertions(+), 176 deletions(-) diff --git a/src/device_provider/imp.rs b/src/device_provider/imp.rs index 62e4dce..3dd243d 100644 --- a/src/device_provider/imp.rs +++ b/src/device_provider/imp.rs @@ -60,7 +60,7 @@ impl DeviceProviderImpl for DeviceProvider { Some(&*METADATA) } - fn probe(&self, _device_provider: &Self::Type) -> Vec { + fn probe(&self) -> Vec { self.current_devices .lock() .unwrap() @@ -69,7 +69,8 @@ impl DeviceProviderImpl for DeviceProvider { .collect() } - fn start(&self, device_provider: &Self::Type) -> Result<(), gst::LoggableError> { + fn start(&self) -> Result<(), gst::LoggableError> { + let device_provider = self.obj(); let mut thread_guard = self.thread.lock().unwrap(); if thread_guard.is_some() { log!(CAT, obj = device_provider, "Device provider already started"); @@ -86,7 +87,7 @@ impl DeviceProviderImpl for DeviceProvider { Some(device_provider) => device_provider, }; - let imp = DeviceProvider::from_instance(&device_provider); + let imp = DeviceProvider::from_obj(&device_provider); { let mut find_guard = imp.find.lock().unwrap(); if find_guard.is_some() { @@ -110,7 +111,7 @@ impl DeviceProviderImpl for DeviceProvider { Some(device_provider) => device_provider, }; - let imp = DeviceProvider::from_instance(&device_provider); + let imp = DeviceProvider::from_obj(&device_provider); if !imp.is_running.load(atomic::Ordering::SeqCst) { break; } @@ -123,7 +124,7 @@ impl DeviceProviderImpl for DeviceProvider { Ok(()) } - fn stop(&self, _device_provider: &Self::Type) { + fn stop(&self) { if let Some(_thread) = self.thread.lock().unwrap().take() { self.is_running.store(false, atomic::Ordering::SeqCst); // Don't actually join because that might take a while @@ -153,7 +154,7 @@ impl DeviceProvider { // First check for each device we previously knew if it's still available for old_device in &*current_devices_guard { - let old_device_imp = Device::from_instance(old_device); + let old_device_imp = Device::from_obj(old_device); let old_source = old_device_imp.source.get().unwrap(); if !sources.contains(&*old_source) { @@ -217,21 +218,16 @@ impl GstObjectImpl for Device {} impl DeviceImpl for Device { fn create_element( &self, - _device: &Self::Type, name: Option<&str>, ) -> Result { let source_info = self.source.get().unwrap(); - let element = glib::Object::with_type( - crate::ndisrc::NdiSrc::static_type(), - &[ - ("name", &name), - ("ndi-name", &source_info.ndi_name()), - ("url-address", &source_info.url_address()), - ], - ) - .unwrap() - .dynamic_cast::() - .unwrap(); + let element = glib::Object::builder_with_type(crate::ndisrc::NdiSrc::static_type()) + .property("name", &name) + .property("ndi-name", &source_info.ndi_name()) + .property("url-address", &source_info.url_address()) + .build() + .dynamic_cast::() + .unwrap(); Ok(element) } @@ -253,14 +249,13 @@ impl super::Device { .field("url-address", &source.url_address()) .build(); - let device = glib::Object::new::(&[ - ("caps", &caps), - ("display-name", &display_name), - ("device-class", &device_class), - ("properties", &extra_properties), - ]) - .unwrap(); - let device_impl = Device::from_instance(&device); + let device = glib::Object::builder::() + .property("caps", &caps) + .property("display-name", &display_name) + .property("device-class", &device_class) + .property("properties", &extra_properties) + .build(); + let device_impl = Device::from_obj(&device); device_impl.source.set(source.to_owned()).unwrap(); diff --git a/src/lib.rs b/src/lib.rs index dfdabf2..08407ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -141,10 +141,10 @@ static DEFAULT_RECEIVER_NDI_NAME: Lazy = Lazy::new(|| { #[cfg(feature = "reference-timestamps")] static TIMECODE_CAPS: Lazy = - Lazy::new(|| gst::Caps::new_simple("timestamp/x-ndi-timecode", &[])); + Lazy::new(|| gst::Caps::new_empty_simple("timestamp/x-ndi-timecode")); #[cfg(feature = "reference-timestamps")] static TIMESTAMP_CAPS: Lazy = - Lazy::new(|| gst::Caps::new_simple("timestamp/x-ndi-timestamp", &[])); + Lazy::new(|| gst::Caps::new_empty_simple("timestamp/x-ndi-timestamp")); gst::plugin_define!( ndi, diff --git a/src/ndisink/imp.rs b/src/ndisink/imp.rs index c43fb8b..9007c6c 100644 --- a/src/ndisink/imp.rs +++ b/src/ndisink/imp.rs @@ -64,13 +64,13 @@ impl ObjectSubclass for NdiSink { impl ObjectImpl for NdiSink { fn properties() -> &'static [glib::ParamSpec] { static PROPERTIES: Lazy> = Lazy::new(|| { - vec![glib::ParamSpecString::new( - "ndi-name", - "NDI Name", - "NDI Name to use", - Some(DEFAULT_SENDER_NDI_NAME.as_ref()), - glib::ParamFlags::READWRITE, - )] + vec![glib::ParamSpecString::builder("ndi-name") + .nick("NDI Name") + .blurb("NDI Name to use") + .default_value(Some(DEFAULT_SENDER_NDI_NAME.as_ref())) + .flags(glib::ParamFlags::READWRITE) + .build() + ] }); PROPERTIES.as_ref() @@ -78,7 +78,6 @@ impl ObjectImpl for NdiSink { fn set_property( &self, - _obj: &Self::Type, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec, @@ -94,7 +93,7 @@ impl ObjectImpl for NdiSink { }; } - fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { + fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { match pspec.name() { "ndi-name" => { let settings = self.settings.lock().unwrap(); @@ -176,7 +175,8 @@ impl ElementImpl for NdiSink { } impl BaseSinkImpl for NdiSink { - fn start(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> { + fn start(&self) -> Result<(), gst::ErrorMessage> { + let element = self.obj(); let mut state_storage = self.state.lock().unwrap(); let settings = self.settings.lock().unwrap(); @@ -200,25 +200,25 @@ impl BaseSinkImpl for NdiSink { Ok(()) } - fn stop(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> { + fn stop(&self) -> Result<(), gst::ErrorMessage> { let mut state_storage = self.state.lock().unwrap(); *state_storage = None; - info!(CAT, obj = element, "Stopped"); + info!(CAT, obj = self.obj(), "Stopped"); Ok(()) } - fn unlock(&self, _element: &Self::Type) -> Result<(), gst::ErrorMessage> { + fn unlock(&self) -> Result<(), gst::ErrorMessage> { Ok(()) } - fn unlock_stop(&self, _element: &Self::Type) -> Result<(), gst::ErrorMessage> { + fn unlock_stop(&self) -> Result<(), gst::ErrorMessage> { Ok(()) } - fn set_caps(&self, element: &Self::Type, caps: &gst::Caps) -> Result<(), gst::LoggableError> { - debug!(CAT, obj = element, "Setting caps {}", caps); + fn set_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> { + debug!(CAT, obj = self.obj(), "Setting caps {}", caps); let mut state_storage = self.state.lock().unwrap(); let state = match &mut *state_storage { @@ -246,9 +246,9 @@ impl BaseSinkImpl for NdiSink { fn render( &self, - element: &Self::Type, buffer: &gst::Buffer, ) -> Result { + let element = self.obj(); let mut state_storage = self.state.lock().unwrap(); let state = match &mut *state_storage { None => return Err(gst::FlowError::Error), diff --git a/src/ndisinkcombiner/imp.rs b/src/ndisinkcombiner/imp.rs index 1a033b2..2837756 100644 --- a/src/ndisinkcombiner/imp.rs +++ b/src/ndisinkcombiner/imp.rs @@ -43,7 +43,7 @@ impl ObjectSubclass for NdiSinkCombiner { fn with_class(klass: &Self::Class) -> Self { let templ = klass.pad_template("video").unwrap(); let video_pad = - gst::PadBuilder::::from_template(&templ, Some("video")) + gst::PadBuilder::::from_template(&templ).name("video") .build(); Self { @@ -55,10 +55,11 @@ impl ObjectSubclass for NdiSinkCombiner { } impl ObjectImpl for NdiSinkCombiner { - fn constructed(&self, obj: &Self::Type) { + fn constructed(&self) { + let obj = self.obj(); obj.add_pad(&self.video_pad).unwrap(); - self.parent_constructed(obj); + self.parent_constructed(); } } @@ -147,12 +148,12 @@ impl ElementImpl for NdiSinkCombiner { PAD_TEMPLATES.as_ref() } - fn release_pad(&self, element: &Self::Type, pad: &gst::Pad) { + fn release_pad(&self, pad: &gst::Pad) { let mut audio_pad_storage = self.audio_pad.lock().unwrap(); if audio_pad_storage.as_ref().map(|p| p.upcast_ref()) == Some(pad) { - debug!(CAT, obj = element, "Release audio pad"); - self.parent_release_pad(element, pad); + debug!(CAT, obj = self.obj(), "Release audio pad"); + self.parent_release_pad(pad); *audio_pad_storage = None; } } @@ -161,11 +162,11 @@ impl ElementImpl for NdiSinkCombiner { impl AggregatorImpl for NdiSinkCombiner { fn create_new_pad( &self, - agg: &Self::Type, templ: &gst::PadTemplate, _req_name: Option<&str>, _caps: Option<&gst::Caps>, ) -> Option { + let agg = self.obj(); let mut audio_pad_storage = self.audio_pad.lock().unwrap(); if audio_pad_storage.is_some() { @@ -180,7 +181,7 @@ impl AggregatorImpl for NdiSinkCombiner { } let pad = - gst::PadBuilder::::from_template(templ, Some("audio")).build(); + gst::PadBuilder::::from_template(templ).name("audio").build(); *audio_pad_storage = Some(pad.clone()); debug!(CAT, obj = agg, "Requested audio pad"); @@ -188,7 +189,7 @@ impl AggregatorImpl for NdiSinkCombiner { Some(pad) } - fn start(&self, agg: &Self::Type) -> Result<(), gst::ErrorMessage> { + fn start(&self) -> Result<(), gst::ErrorMessage> { let mut state_storage = self.state.lock().unwrap(); *state_storage = Some(State { audio_info: None, @@ -197,31 +198,31 @@ impl AggregatorImpl for NdiSinkCombiner { current_audio_buffers: Vec::new(), }); - debug!(CAT, obj = agg, "Started"); + debug!(CAT, obj = self.obj(), "Started"); Ok(()) } - fn stop(&self, agg: &Self::Type) -> Result<(), gst::ErrorMessage> { + fn stop(&self) -> Result<(), gst::ErrorMessage> { // Drop our state now let _ = self.state.lock().unwrap().take(); - debug!(CAT, obj = agg, "Stopped"); + debug!(CAT, obj = self.obj(), "Stopped"); Ok(()) } - fn next_time(&self, _agg: &Self::Type) -> Option { + fn next_time(&self) -> Option { // FIXME: What to do here? We don't really know when the next buffer is expected gst::ClockTime::NONE } fn clip( &self, - agg: &Self::Type, agg_pad: &gst_base::AggregatorPad, mut buffer: gst::Buffer, ) -> Option { + let agg = self.obj(); let segment = match agg_pad.segment().downcast::() { Ok(segment) => segment, Err(_) => { @@ -314,12 +315,12 @@ impl AggregatorImpl for NdiSinkCombiner { fn aggregate( &self, - agg: &Self::Type, timeout: bool, ) -> Result { // FIXME: Can't really happen because we always return NONE from get_next_time() but that // should be improved! assert!(!timeout); + let agg = self.obj(); // Because peek_buffer() can call into clip() and that would take the state lock again, // first try getting buffers from both pads here @@ -539,11 +540,11 @@ impl AggregatorImpl for NdiSinkCombiner { fn sink_event( &self, - agg: &Self::Type, pad: &gst_base::AggregatorPad, event: gst::Event, ) -> bool { use gst::EventView; + let agg = self.obj(); match event.view() { EventView::Caps(caps) => { @@ -604,19 +605,19 @@ impl AggregatorImpl for NdiSinkCombiner { _ => (), } - self.parent_sink_event(agg, pad, event) + self.parent_sink_event(pad, event) } fn sink_query( &self, - agg: &Self::Type, pad: &gst_base::AggregatorPad, query: &mut gst::QueryRef, ) -> bool { - use gst::QueryView; + use gst::QueryViewMut; + let agg = self.obj(); match query.view_mut() { - QueryView::Caps(_) if pad == &self.video_pad => { + QueryViewMut::Caps(_) if pad == &self.video_pad => { // Directly forward caps queries let srcpad = agg.static_pad("src").unwrap(); return srcpad.peer_query(query); @@ -624,10 +625,10 @@ impl AggregatorImpl for NdiSinkCombiner { _ => (), } - self.parent_sink_query(agg, pad, query) + self.parent_sink_query(pad, query) } - fn negotiate(&self, _agg: &Self::Type) -> bool { + fn negotiate(&self) -> bool { // No negotiation needed as the video caps are just passed through true } diff --git a/src/ndisrc/imp.rs b/src/ndisrc/imp.rs index bdf37ac..50dac8a 100644 --- a/src/ndisrc/imp.rs +++ b/src/ndisrc/imp.rs @@ -6,7 +6,7 @@ use gst_base::subclass::base_src::CreateSuccess; use gst_base::subclass::prelude::*; use std::sync::Mutex; -use std::{i32, u32}; +use std::u32; use once_cell::sync::Lazy; @@ -105,101 +105,89 @@ impl ObjectImpl for NdiSrc { fn properties() -> &'static [glib::ParamSpec] { static PROPERTIES: Lazy> = Lazy::new(|| { vec![ - glib::ParamSpecString::new( - "ndi-name", - "NDI Name", - "NDI stream name of the sender", - None, - glib::ParamFlags::READWRITE, - ), - glib::ParamSpecString::new( - "url-address", - "URL/Address", - "URL/address and port of the sender, e.g. 127.0.0.1:5961", - None, - glib::ParamFlags::READWRITE, - ), - glib::ParamSpecString::new( - "receiver-ndi-name", - "Receiver NDI Name", - "NDI stream name of this receiver", - Some(&*DEFAULT_RECEIVER_NDI_NAME), - glib::ParamFlags::READWRITE, - ), - glib::ParamSpecUInt::new( - "connect-timeout", - "Connect Timeout", - "Connection timeout in ms", - 0, - u32::MAX, - 10000, - glib::ParamFlags::READWRITE, - ), - glib::ParamSpecUInt::new( - "timeout", - "Timeout", - "Receive timeout in ms", - 0, - u32::MAX, - 5000, - glib::ParamFlags::READWRITE, - ), - glib::ParamSpecUInt::new( - "max-queue-length", - "Max Queue Length", - "Maximum receive queue length", - 0, - u32::MAX, - 10, - glib::ParamFlags::READWRITE, - ), - glib::ParamSpecInt::new( - "bandwidth", - "Bandwidth", - "Bandwidth, -10 metadata-only, 10 audio-only, 100 highest", - -10, - 100, - 100, - glib::ParamFlags::READWRITE, - ), - glib::ParamSpecEnum::new( - "color-format", - "Color Format", - "Receive color format", - RecvColorFormat::static_type(), - RecvColorFormat::UyvyBgra as u32 as i32, - glib::ParamFlags::READWRITE, - ), - glib::ParamSpecEnum::new( - "timestamp-mode", - "Timestamp Mode", - "Timestamp information to use for outgoing PTS", - TimestampMode::static_type(), - TimestampMode::ReceiveTimeTimecode as i32, - glib::ParamFlags::READWRITE, - ), + glib::ParamSpecString::builder("ndi-name") + .nick("NDI Name") + .blurb("NDI stream name of the sender") + .default_value(None) + .flags(glib::ParamFlags::READWRITE) + .build(), + glib::ParamSpecString::builder("url-address") + .nick("URL/Address") + .blurb("URL/address and port of the sender, e.g. 127.0.0.1:5961") + .default_value(None) + .flags(glib::ParamFlags::READWRITE) + .build(), + glib::ParamSpecString::builder("receiver-ndi-name") + .nick("Receiver NDI Name") + .blurb("NDI stream name of this receiver") + .default_value(Some(DEFAULT_RECEIVER_NDI_NAME.as_str())) + .flags(glib::ParamFlags::READWRITE) + .build(), + glib::ParamSpecUInt::builder("connect-timeout") + .nick("Connect Timeout") + .blurb("Connection timeout in ms") + .minimum(0) + .maximum(u32::MAX) + .default_value(10000) + .flags(glib::ParamFlags::READWRITE) + .build(), + glib::ParamSpecUInt::builder("timeout") + .nick("Timeout") + .blurb("Receive timeout in ms") + .minimum(0) + .maximum(u32::MAX) + .default_value(5000) + .flags(glib::ParamFlags::READWRITE) + .build(), + glib::ParamSpecUInt::builder("max-queue-length") + .nick("Max Queue Length") + .blurb("Maximum receive queue length") + .minimum(0) + .maximum(u32::MAX) + .default_value(10) + .flags(glib::ParamFlags::READWRITE) + .build(), + glib::ParamSpecInt::builder("bandwidth") + .nick("Bandwidth") + .blurb("Bandwidth, -10 metadata-only, 10 audio-only, 100 highest") + .minimum(-10) + .maximum(100) + .default_value(100) + .flags(glib::ParamFlags::READWRITE) + .build(), + glib::ParamSpecEnum::builder_with_default("color-format", RecvColorFormat::UyvyBgra) + .nick("Color Format") + .blurb("Receive color format") + .flags(glib::ParamFlags::READWRITE) + .build(), + glib::ParamSpecEnum::builder_with_default("timestamp-mode", TimestampMode::ReceiveTimeTimecode) + .nick("Timestamp Mode") + .blurb("Timestamp information to use for outgoing PTS") + .flags(glib::ParamFlags::READWRITE) + .build(), ] }); PROPERTIES.as_ref() } - fn constructed(&self, obj: &Self::Type) { - self.parent_constructed(obj); + fn constructed(&self) { + self.parent_constructed(); // Initialize live-ness and notify the base class that // we'd like to operate in Time format + let obj = self.obj(); obj.set_live(true); obj.set_format(gst::Format::Time); } fn set_property( &self, - obj: &Self::Type, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec, ) { + let obj= self.obj(); match pspec.name() { "ndi-name" => { let mut settings = self.settings.lock().unwrap(); @@ -309,7 +297,7 @@ impl ObjectImpl for NdiSrc { timestamp_mode ); if settings.timestamp_mode != timestamp_mode { - let _ = obj.post_message(gst::message::Latency::builder().src(obj).build()); + let _ = obj.post_message(gst::message::Latency::builder().src(&*obj).build()); } settings.timestamp_mode = timestamp_mode; } @@ -317,7 +305,7 @@ impl ObjectImpl for NdiSrc { } } - fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { + fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { match pspec.name() { "ndi-name" => { let settings = self.settings.lock().unwrap(); @@ -394,7 +382,6 @@ impl ElementImpl for NdiSrc { fn change_state( &self, - element: &Self::Type, transition: gst::StateChange, ) -> Result { match transition { @@ -416,34 +403,35 @@ impl ElementImpl for NdiSrc { _ => (), } - self.parent_change_state(element, transition) + self.parent_change_state(transition) } } impl BaseSrcImpl for NdiSrc { - fn negotiate(&self, element: &Self::Type) -> Result<(), gst::LoggableError> { - element + fn negotiate(&self) -> Result<(), gst::LoggableError> { + self.obj() .set_caps(&gst::Caps::builder("application/x-ndi").build()) .map_err(|_| gst::loggable_error!(CAT, "Failed to negotiate caps",)) } - fn unlock(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> { - debug!(CAT, obj = element, "Unlocking",); + fn unlock(&self) -> Result<(), gst::ErrorMessage> { + debug!(CAT, obj = self.obj(), "Unlocking",); if let Some(ref controller) = *self.receiver_controller.lock().unwrap() { controller.set_flushing(true); } Ok(()) } - fn unlock_stop(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> { - debug!(CAT, obj = element, "Stop unlocking",); + fn unlock_stop(&self) -> Result<(), gst::ErrorMessage> { + debug!(CAT, obj = self.obj(), "Stop unlocking",); if let Some(ref controller) = *self.receiver_controller.lock().unwrap() { controller.set_flushing(false); } Ok(()) } - fn start(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> { + fn start(&self) -> Result<(), gst::ErrorMessage> { + let element = self.obj(); *self.state.lock().unwrap() = Default::default(); let settings = self.settings.lock().unwrap().clone(); @@ -483,7 +471,7 @@ impl BaseSrcImpl for NdiSrc { } } - fn stop(&self, _element: &Self::Type) -> Result<(), gst::ErrorMessage> { + fn stop(&self) -> Result<(), gst::ErrorMessage> { if let Some(ref controller) = self.receiver_controller.lock().unwrap().take() { controller.shutdown(); } @@ -491,16 +479,16 @@ impl BaseSrcImpl for NdiSrc { Ok(()) } - fn query(&self, element: &Self::Type, query: &mut gst::QueryRef) -> bool { - use gst::QueryView; + fn query(&self, query: &mut gst::QueryRef) -> bool { + use gst::QueryViewMut; match query.view_mut() { - QueryView::Scheduling(ref mut q) => { + QueryViewMut::Scheduling(q) => { q.set(gst::SchedulingFlags::SEQUENTIAL, 1, -1, 0); q.add_scheduling_modes(&[gst::PadMode::Push]); true } - QueryView::Latency(ref mut q) => { + QueryViewMut::Latency(q) => { let state = self.state.lock().unwrap(); let settings = self.settings.lock().unwrap(); @@ -518,7 +506,7 @@ impl BaseSrcImpl for NdiSrc { debug!( CAT, - obj = element, + obj = self.obj(), "Returning latency min {} max {}", min, max @@ -529,17 +517,17 @@ impl BaseSrcImpl for NdiSrc { false } } - _ => BaseSrcImplExt::parent_query(self, element, query), + _ => BaseSrcImplExt::parent_query(self, query), } } fn create( &self, - element: &Self::Type, _offset: u64, _buffer: Option<&mut gst::BufferRef>, _length: u32, ) -> Result { + let element = self.obj(); let recv = { let mut state = self.state.lock().unwrap(); match state.receiver.take() { @@ -614,7 +602,7 @@ impl BaseSrcImpl for NdiSrc { drop(state); if latency_changed { let _ = element.post_message( - gst::message::Latency::builder().src(element).build(), + gst::message::Latency::builder().src(&*element).build(), ); } diff --git a/src/ndisrcdemux/imp.rs b/src/ndisrcdemux/imp.rs index 11a33ea..58937c6 100644 --- a/src/ndisrcdemux/imp.rs +++ b/src/ndisrcdemux/imp.rs @@ -39,20 +39,20 @@ impl ObjectSubclass for NdiSrcDemux { fn with_class(klass: &Self::Class) -> Self { let templ = klass.pad_template("sink").unwrap(); - let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + let sinkpad = gst::Pad::builder_from_template(&templ).name("sink") .flags(gst::PadFlags::FIXED_CAPS) .chain_function(|pad, parent, buffer| { NdiSrcDemux::catch_panic_pad_function( parent, || Err(gst::FlowError::Error), - |self_, element| self_.sink_chain(pad, element, buffer), + |self_| self_.sink_chain(pad, buffer), ) }) .event_function(|pad, parent, event| { NdiSrcDemux::catch_panic_pad_function( parent, || false, - |self_, element| self_.sink_event(pad, element, event), + |self_| self_.sink_event(pad, event), ) }) .build(); @@ -65,8 +65,9 @@ impl ObjectSubclass for NdiSrcDemux { } impl ObjectImpl for NdiSrcDemux { - fn constructed(&self, obj: &Self::Type) { - self.parent_constructed(obj); + fn constructed(&self) { + self.parent_constructed(); + let obj = self.obj(); obj.add_pad(&self.sinkpad).unwrap(); } @@ -126,10 +127,10 @@ impl ElementImpl for NdiSrcDemux { fn change_state( &self, - element: &Self::Type, transition: gst::StateChange, ) -> Result { - let res = self.parent_change_state(element, transition)?; + let res = self.parent_change_state(transition)?; + let element = self.obj(); match transition { gst::StateChange::PausedToReady => { @@ -153,10 +154,10 @@ impl NdiSrcDemux { fn sink_chain( &self, pad: &gst::Pad, - element: &super::NdiSrcDemux, mut buffer: gst::Buffer, ) -> Result { log!(CAT, obj = pad, "Handling buffer {:?}", buffer); + let element = self.obj(); let meta = buffer.make_mut().meta_mut::().ok_or_else(|| { error!(CAT, obj = element, "Buffer without NDI source meta"); @@ -178,7 +179,7 @@ impl NdiSrcDemux { let klass = element.element_class(); let templ = klass.pad_template("audio").unwrap(); - let pad = gst::Pad::builder_with_template(&templ, Some("audio")) + let pad = gst::Pad::builder_from_template(&templ).name("audio") .flags(gst::PadFlags::FIXED_CAPS) .build(); @@ -228,7 +229,7 @@ impl NdiSrcDemux { let klass = element.element_class(); let templ = klass.pad_template("video").unwrap(); - let pad = gst::Pad::builder_with_template(&templ, Some("video")) + let pad = gst::Pad::builder_from_template(&templ).name("video") .flags(gst::PadFlags::FIXED_CAPS) .build(); @@ -290,10 +291,10 @@ impl NdiSrcDemux { fn sink_event(&self, pad: &gst::Pad, - element: &super::NdiSrcDemux, event: gst::Event ) -> bool { use gst::EventView; + let element = self.obj(); log!(CAT, obj = pad, "Handling event {:?}", event); if let EventView::Eos(_) = event.view() { @@ -306,7 +307,7 @@ impl NdiSrcDemux { ); } } - pad.event_default(Some(element), event) + gst::Pad::event_default(pad, Some(&*element), event) } }