mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
Revert "Merge pull request #2628 from rustdesk/revert-2612-master"
This reverts commite50882a660, reversing changes made to7f006102b5.
This commit is contained in:
@@ -48,9 +48,9 @@ bindgen = "0.59"
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
dbus = { version = "0.9", optional = true }
|
||||
tracing = { version = "0.1", optional = true }
|
||||
gstreamer = { version = "0.16", optional = true }
|
||||
gstreamer-app = { version = "0.16", features = ["v1_10"], optional = true }
|
||||
gstreamer-video = { version = "0.16", optional = true }
|
||||
gstreamer = { version = "0.19", optional = true }
|
||||
gstreamer-app = { version = "0.19", features = ["v1_16"], optional = true }
|
||||
gstreamer-video = { version = "0.19", optional = true }
|
||||
|
||||
[target.'cfg(any(target_os = "windows", target_os = "linux"))'.dependencies]
|
||||
hwcodec = { git = "https://github.com/21pages/hwcodec", optional = true }
|
||||
|
||||
@@ -50,6 +50,12 @@ impl TraitCapturer for Capturer {
|
||||
} else {
|
||||
x
|
||||
})),
|
||||
PixelProvider::RGB0(w, h, x) => Ok(Frame(if self.2 {
|
||||
crate::common::rgba_to_i420(w as _, h as _, &x, &mut self.3);
|
||||
&self.3[..]
|
||||
} else {
|
||||
x
|
||||
})),
|
||||
PixelProvider::NONE => Err(std::io::ErrorKind::WouldBlock.into()),
|
||||
_ => Err(map_err("Invalid data")),
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ use std::error::Error;
|
||||
pub enum PixelProvider<'a> {
|
||||
// 8 bits per color
|
||||
RGB(usize, usize, &'a [u8]),
|
||||
RGB0(usize, usize, &'a [u8]),
|
||||
BGR0(usize, usize, &'a [u8]),
|
||||
// width, height, stride
|
||||
BGR0S(usize, usize, usize, &'a [u8]),
|
||||
@@ -14,6 +15,7 @@ impl<'a> PixelProvider<'a> {
|
||||
pub fn size(&self) -> (usize, usize) {
|
||||
match self {
|
||||
PixelProvider::RGB(w, h, _) => (*w, *h),
|
||||
PixelProvider::RGB0(w, h, _) => (*w, *h),
|
||||
PixelProvider::BGR0(w, h, _) => (*w, *h),
|
||||
PixelProvider::BGR0S(w, h, _, _) => (*w, *h),
|
||||
PixelProvider::NONE => (0, 0),
|
||||
|
||||
@@ -117,6 +117,7 @@ impl Capturable for PipeWireCapturable {
|
||||
pub struct PipeWireRecorder {
|
||||
buffer: Option<gst::MappedBuffer<gst::buffer::Readable>>,
|
||||
buffer_cropped: Vec<u8>,
|
||||
pix_fmt: String,
|
||||
is_cropped: bool,
|
||||
pipeline: gst::Pipeline,
|
||||
appsink: AppSink,
|
||||
@@ -129,34 +130,42 @@ impl PipeWireRecorder {
|
||||
pub fn new(capturable: PipeWireCapturable) -> Result<Self, Box<dyn Error>> {
|
||||
let pipeline = gst::Pipeline::new(None);
|
||||
|
||||
let src = gst::ElementFactory::make("pipewiresrc", None)?;
|
||||
src.set_property("fd", &capturable.fd.as_raw_fd())?;
|
||||
src.set_property("path", &format!("{}", capturable.path))?;
|
||||
src.set_property("keepalive_time", &1_000.as_raw_fd())?;
|
||||
let src = gst::ElementFactory::make_with_name("pipewiresrc", None)?;
|
||||
src.set_property("fd", &capturable.fd.as_raw_fd());
|
||||
src.set_property("path", &format!("{}", capturable.path));
|
||||
src.set_property("keepalive_time", &1_000.as_raw_fd());
|
||||
|
||||
// For some reason pipewire blocks on destruction of AppSink if this is not set to true,
|
||||
// see: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/982
|
||||
src.set_property("always-copy", &true)?;
|
||||
src.set_property("always-copy", &true);
|
||||
|
||||
let sink = gst::ElementFactory::make("appsink", None)?;
|
||||
sink.set_property("drop", &true)?;
|
||||
sink.set_property("max-buffers", &1u32)?;
|
||||
let sink = gst::ElementFactory::make_with_name("appsink", None)?;
|
||||
sink.set_property("drop", &true);
|
||||
sink.set_property("max-buffers", &1u32);
|
||||
|
||||
pipeline.add_many(&[&src, &sink])?;
|
||||
src.link(&sink)?;
|
||||
|
||||
let appsink = sink
|
||||
.dynamic_cast::<AppSink>()
|
||||
.map_err(|_| GStreamerError("Sink element is expected to be an appsink!".into()))?;
|
||||
appsink.set_caps(Some(&gst::Caps::new_simple(
|
||||
let mut caps = gst::Caps::new_empty();
|
||||
caps.merge_structure(gst::structure::Structure::new(
|
||||
"video/x-raw",
|
||||
&[("format", &"BGRx")],
|
||||
)));
|
||||
));
|
||||
caps.merge_structure(gst::structure::Structure::new(
|
||||
"video/x-raw",
|
||||
&[("format", &"RGBx")],
|
||||
));
|
||||
appsink.set_caps(Some(&caps));
|
||||
|
||||
pipeline.set_state(gst::State::Playing)?;
|
||||
Ok(Self {
|
||||
pipeline,
|
||||
appsink,
|
||||
buffer: None,
|
||||
pix_fmt: "".into(),
|
||||
width: 0,
|
||||
height: 0,
|
||||
buffer_cropped: vec![],
|
||||
@@ -173,20 +182,21 @@ impl Recorder for PipeWireRecorder {
|
||||
.try_pull_sample(gst::ClockTime::from_mseconds(timeout_ms))
|
||||
{
|
||||
let cap = sample
|
||||
.get_caps()
|
||||
.caps()
|
||||
.ok_or("Failed get caps")?
|
||||
.get_structure(0)
|
||||
.structure(0)
|
||||
.ok_or("Failed to get structure")?;
|
||||
let w: i32 = cap.get_value("width")?.get_some()?;
|
||||
let h: i32 = cap.get_value("height")?.get_some()?;
|
||||
let w: i32 = cap.value("width")?.get()?;
|
||||
let h: i32 = cap.value("height")?.get()?;
|
||||
self.pix_fmt = cap.value("format")?.get()?;
|
||||
let w = w as usize;
|
||||
let h = h as usize;
|
||||
let buf = sample
|
||||
.get_buffer_owned()
|
||||
.buffer_owned()
|
||||
.ok_or_else(|| GStreamerError("Failed to get owned buffer.".into()))?;
|
||||
let mut crop = buf
|
||||
.get_meta::<gstreamer_video::VideoCropMeta>()
|
||||
.map(|m| m.get_rect());
|
||||
.meta::<gstreamer_video::VideoCropMeta>()
|
||||
.map(|m| m.rect());
|
||||
// only crop if necessary
|
||||
if Some((0, 0, w as u32, h as u32)) == crop {
|
||||
crop = None;
|
||||
@@ -197,7 +207,7 @@ impl Recorder for PipeWireRecorder {
|
||||
if let Err(..) = crate::would_block_if_equal(&mut self.saved_raw_data, buf.as_slice()) {
|
||||
return Ok(PixelProvider::NONE);
|
||||
}
|
||||
let buf_size = buf.get_size();
|
||||
let buf_size = buf.size();
|
||||
// BGRx is 4 bytes per pixel
|
||||
if buf_size != (w * h * 4) {
|
||||
// for some reason the width and height of the caps do not guarantee correct buffer
|
||||
@@ -241,15 +251,22 @@ impl Recorder for PipeWireRecorder {
|
||||
if self.buffer.is_none() {
|
||||
return Err(Box::new(GStreamerError("No buffer available!".into())));
|
||||
}
|
||||
Ok(PixelProvider::BGR0(
|
||||
self.width,
|
||||
self.height,
|
||||
if self.is_cropped {
|
||||
self.buffer_cropped.as_slice()
|
||||
} else {
|
||||
self.buffer.as_ref().unwrap().as_slice()
|
||||
},
|
||||
))
|
||||
let buf = if self.is_cropped {
|
||||
self.buffer_cropped.as_slice()
|
||||
} else {
|
||||
self.buffer
|
||||
.as_ref()
|
||||
.ok_or("Failed to get buffer as ref")?
|
||||
.as_slice()
|
||||
};
|
||||
match self.pix_fmt.as_str() {
|
||||
"BGRx" => Ok(PixelProvider::BGR0(self.width, self.height, buf)),
|
||||
"RGBx" => Ok(PixelProvider::RGB0(self.width, self.height, buf)),
|
||||
_ => Err(Box::new(GStreamerError(format!(
|
||||
"Unreachable! Unknown pix_fmt, {}",
|
||||
&self.pix_fmt
|
||||
)))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user