feat: only send pixel if different from previous frame
This commit is contained in:
parent
49de34f863
commit
37183665f0
|
@ -12,6 +12,7 @@ use gstreamer_base::subclass::prelude::*;
|
||||||
|
|
||||||
use gstreamer_video::prelude::*;
|
use gstreamer_video::prelude::*;
|
||||||
use gstreamer_video::subclass::prelude::*;
|
use gstreamer_video::subclass::prelude::*;
|
||||||
|
use gstreamer_video::video_frame::Readable;
|
||||||
use gstreamer_video::{VideoCapsBuilder, VideoFormat, VideoFrame, VideoInfo, VideoSink};
|
use gstreamer_video::{VideoCapsBuilder, VideoFormat, VideoFrame, VideoInfo, VideoSink};
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
@ -49,6 +50,7 @@ enum State {
|
||||||
pub struct PingxelflutSink {
|
pub struct PingxelflutSink {
|
||||||
caps: Mutex<Option<Caps>>,
|
caps: Mutex<Option<Caps>>,
|
||||||
info: Mutex<Option<VideoInfo>>,
|
info: Mutex<Option<VideoInfo>>,
|
||||||
|
prev_frame: Mutex<Option<VideoFrame<Readable>>>,
|
||||||
settings: Mutex<Settings>,
|
settings: Mutex<Settings>,
|
||||||
state: Mutex<State>,
|
state: Mutex<State>,
|
||||||
}
|
}
|
||||||
|
@ -230,6 +232,8 @@ impl VideoSinkImpl for PingxelflutSink {
|
||||||
VideoFrame::from_buffer_readable(buffer.clone(), info).map_err(|_| FlowError::Error)?;
|
VideoFrame::from_buffer_readable(buffer.clone(), info).map_err(|_| FlowError::Error)?;
|
||||||
let data = frame.plane_data(0).unwrap();
|
let data = frame.plane_data(0).unwrap();
|
||||||
|
|
||||||
|
let prev_frame = self.prev_frame.lock().unwrap().take();
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
let prefix = settings.prefix.as_ref().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;
|
(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 (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
|
prefix
|
||||||
|
@ -256,11 +268,15 @@ impl VideoSinkImpl for PingxelflutSink {
|
||||||
),
|
),
|
||||||
1337,
|
1337,
|
||||||
),
|
),
|
||||||
);
|
) {
|
||||||
|
gstreamer::warning!(CAT, imp = self, "{}", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.prev_frame.lock().unwrap().replace(frame);
|
||||||
|
|
||||||
Ok(FlowSuccess::Ok)
|
Ok(FlowSuccess::Ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue