diff --git a/src/pingxelflutsink/imp.rs b/src/pingxelflutsink/imp.rs index 1701202..6cc2830 100644 --- a/src/pingxelflutsink/imp.rs +++ b/src/pingxelflutsink/imp.rs @@ -12,6 +12,7 @@ use gstreamer_base::subclass::prelude::*; use gstreamer_video::prelude::*; use gstreamer_video::subclass::prelude::*; +use gstreamer_video::video_frame::Readable; use gstreamer_video::{VideoCapsBuilder, VideoFormat, VideoFrame, VideoInfo, VideoSink}; use std::cmp; @@ -49,6 +50,7 @@ enum State { pub struct PingxelflutSink { caps: Mutex>, info: Mutex>, + prev_frame: Mutex>>, settings: Mutex, state: Mutex, } @@ -230,6 +232,8 @@ impl VideoSinkImpl for PingxelflutSink { VideoFrame::from_buffer_readable(buffer.clone(), info).map_err(|_| FlowError::Error)?; let data = frame.plane_data(0).unwrap(); + let prev_frame = self.prev_frame.lock().unwrap().take(); + let settings = self.settings.lock().unwrap(); let prefix = settings.prefix.as_ref().unwrap(); @@ -240,7 +244,15 @@ impl VideoSinkImpl for PingxelflutSink { (y * frame.plane_stride()[0] as u32 + x * frame.n_components()) as usize; let (r, g, b) = (data[i] as u16, data[i + 1] as u16, data[i + 2] as u16); - let _ = socket.send_to( + if prev_frame.as_ref().map_or(false, |f| { + f.plane_data(0).is_ok_and(|d| { + d[i] as u16 == r && d[i + 1] as u16 == g && d[i + 2] as u16 == b + }) + }) { + continue; + } + + if let Err(err) = socket.send_to( &[], ( prefix @@ -256,11 +268,15 @@ impl VideoSinkImpl for PingxelflutSink { ), 1337, ), - ); + ) { + gstreamer::warning!(CAT, imp = self, "{}", err); + } } } } + self.prev_frame.lock().unwrap().replace(frame); + Ok(FlowSuccess::Ok) } }