chore: Restore Wayland ashpd setup and mock PipeWire stream
This commit is contained in:
parent
9e6b30abad
commit
2d623daa99
8 changed files with 104 additions and 112 deletions
|
|
@ -1,82 +0,0 @@
|
|||
--- src/bin/vrec-daemon.rs
|
||||
+++ src/bin/vrec-daemon.rs
|
||||
@@ -1,13 +1,6 @@
|
||||
-pub mod capture;
|
||||
-pub mod encoder;
|
||||
-pub mod ring;
|
||||
-pub mod muxer;
|
||||
-pub mod hotkey;
|
||||
-pub mod debug;
|
||||
-
|
||||
-use capture::{Frame, FrameSource};
|
||||
-use encoder::VaapiEncoder;
|
||||
-use ring::Packet;
|
||||
-use muxer::Muxer;
|
||||
+use vrec::capture::{Frame, FrameSource};
|
||||
+use vrec::encoder::VaapiEncoder;
|
||||
+use vrec::ring::Packet;
|
||||
+use vrec::muxer::Muxer;
|
||||
+use vrec::ipc::Command;
|
||||
use ringbuf::HeapRb;
|
||||
use ringbuf::traits::{RingBuffer, Consumer};
|
||||
use crossbeam_channel::bounded;
|
||||
@@ -15,6 +8,9 @@
|
||||
use std::env;
|
||||
+use std::os::unix::net::UnixListener;
|
||||
+use std::io::Read;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let session_type = env::var("XDG_SESSION_TYPE").unwrap_or_else(|_| "x11".to_string());
|
||||
@@ -23,10 +19,10 @@
|
||||
let mut source: Box<dyn FrameSource> = if session_type.to_lowercase() == "wayland" {
|
||||
println!("Initializing Wayland capture...");
|
||||
- Box::new(capture::wayland::WaylandCapture::new().await?)
|
||||
+ Box::new(vrec::capture::wayland::WaylandCapture::new().await?)
|
||||
} else {
|
||||
println!("Initializing X11 capture...");
|
||||
- Box::new(capture::x11::X11Capture::new()?)
|
||||
+ Box::new(vrec::capture::x11::X11Capture::new()?)
|
||||
};
|
||||
|
||||
@@ -118,10 +114,35 @@
|
||||
});
|
||||
|
||||
- // 5. Hotkey listener
|
||||
- println!("Starting hotkey listener...");
|
||||
- if let Err(e) = hotkey::run_hotkey_listener(trigger_tx) {
|
||||
- eprintln!("Failed to start hotkey listener: {}", e);
|
||||
+ // 5. IPC Unix Socket Listener
|
||||
+ let socket_path = format!("{}/vrec.sock", env::var("XDG_RUNTIME_DIR").unwrap_or_else(|_| "/tmp".to_string()));
|
||||
+ let _ = std::fs::remove_file(&socket_path); // Remove old socket if exists
|
||||
+ let listener = UnixListener::bind(&socket_path)?;
|
||||
+ println!("Daemon listening on IPC socket: {}", socket_path);
|
||||
+
|
||||
+ for stream in listener.incoming() {
|
||||
+ match stream {
|
||||
+ Ok(mut stream) => {
|
||||
+ let mut len_buf = [0u8; 4];
|
||||
+ if stream.read_exact(&mut len_buf).is_ok() {
|
||||
+ let len = u32::from_le_bytes(len_buf) as usize;
|
||||
+ let mut payload = vec![0u8; len];
|
||||
+ if stream.read_exact(&mut payload).is_ok() {
|
||||
+ if let Ok(cmd) = serde_json::from_slice::<Command>(&payload) {
|
||||
+ match cmd {
|
||||
+ Command::SaveReplay => {
|
||||
+ let _ = trigger_tx.try_send(());
|
||||
+ },
|
||||
+ Command::StopDaemon => {
|
||||
+ break;
|
||||
+ },
|
||||
+ _ => {}
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ Err(err) => {
|
||||
+ eprintln!("Socket error: {}", err);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
2
scratch/pw.rs
Normal file
2
scratch/pw.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
use pipewire as pw;
|
||||
fn main() {}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
--- src/capture/mod.rs
|
||||
+++ src/capture/mod.rs
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
pub mod wayland;
|
||||
pub mod x11;
|
||||
+#[cfg(target_os = "windows")]
|
||||
+pub mod windows;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Frame {
|
||||
@@ -19,6 +21,11 @@
|
||||
stride: u32,
|
||||
data: Vec<u8>,
|
||||
},
|
||||
+ /// Zero-copy DirectX 11 Texture handle. Used by Windows DXGI capture.
|
||||
+ #[cfg(target_os = "windows")]
|
||||
+ D3D11Texture {
|
||||
+ handle: usize, // Placeholder for ID3D11Texture2D raw pointer
|
||||
+ },
|
||||
}
|
||||
|
||||
pub trait FrameSource: Send {
|
||||
30
scratch/wl.patch
Normal file
30
scratch/wl.patch
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
--- src/capture/wayland.rs
|
||||
+++ src/capture/wayland.rs
|
||||
@@ -4,8 +4,7 @@
|
||||
use ashpd::desktop::screencast::{Screencast, CursorMode, PersistMode, SourceType};
|
||||
use std::os::unix::io::RawFd;
|
||||
|
||||
pub struct WaylandCapture {
|
||||
- fd: RawFd,
|
||||
- node_id: u32,
|
||||
+ stream: crate::capture::wayland_stream::PipeWireStream,
|
||||
}
|
||||
|
||||
@@ -37,13 +36,13 @@
|
||||
node_id = stream.node_id();
|
||||
}
|
||||
|
||||
- Ok(Self { fd, node_id })
|
||||
+ let stream = crate::capture::wayland_stream::PipeWireStream::new(node_id, fd)?;
|
||||
+ Ok(Self { stream })
|
||||
}
|
||||
}
|
||||
|
||||
impl FrameSource for WaylandCapture {
|
||||
fn next_frame(&mut self) -> Result<Frame, Box<dyn std::error::Error + Send + Sync>> {
|
||||
- // Wait, Wayland capture requires a pipewire stream running in a background thread to yield buffers.
|
||||
- // For Phase 1, we are mocking this out until Phase 2 is built.
|
||||
- Ok(Frame::DmaBuf { width: 1920, height: 1080, format: 0, fd: self.fd, stride: 0, offset: 0 })
|
||||
+ self.stream.receiver.recv().map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)
|
||||
}
|
||||
}
|
||||
30
scratch/wl2.patch
Normal file
30
scratch/wl2.patch
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
--- src/capture/wayland.rs
|
||||
+++ src/capture/wayland.rs
|
||||
@@ -4,8 +4,7 @@
|
||||
use ashpd::desktop::PersistMode;
|
||||
use std::os::unix::io::{RawFd, IntoRawFd};
|
||||
|
||||
pub struct WaylandCapture {
|
||||
- fd: RawFd,
|
||||
- node_id: u32,
|
||||
+ stream: crate::capture::wayland_stream::PipeWireStream,
|
||||
}
|
||||
|
||||
@@ -29,14 +28,15 @@
|
||||
let fd = proxy.open_pipe_wire_remote(&session, Default::default()).await?;
|
||||
|
||||
- Ok(Self {
|
||||
- fd: fd.into_raw_fd(),
|
||||
- node_id,
|
||||
- })
|
||||
+ let stream = crate::capture::wayland_stream::PipeWireStream::new(node_id, fd.into_raw_fd())?;
|
||||
+ Ok(Self { stream })
|
||||
}
|
||||
}
|
||||
|
||||
impl FrameSource for WaylandCapture {
|
||||
fn next_frame(&mut self) -> Result<Frame, Box<dyn std::error::Error + Send + Sync>> {
|
||||
- Err("Wayland/Pipewire frame extraction not fully implemented yet".into())
|
||||
+ self.stream.next_frame().map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
use std::os::unix::io::RawFd;
|
||||
|
||||
pub mod wayland;
|
||||
pub mod wayland_stream;
|
||||
pub mod x11;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub mod windows;
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ use ashpd::desktop::PersistMode;
|
|||
use std::os::unix::io::{RawFd, IntoRawFd};
|
||||
|
||||
pub struct WaylandCapture {
|
||||
fd: RawFd,
|
||||
node_id: u32,
|
||||
stream: crate::capture::wayland_stream::PipeWireStream,
|
||||
}
|
||||
|
||||
impl WaylandCapture {
|
||||
|
|
@ -28,15 +27,14 @@ impl WaylandCapture {
|
|||
|
||||
let fd = proxy.open_pipe_wire_remote(&session, Default::default()).await?;
|
||||
|
||||
Ok(Self {
|
||||
fd: fd.into_raw_fd(),
|
||||
node_id,
|
||||
})
|
||||
let stream = crate::capture::wayland_stream::PipeWireStream::new(node_id, fd.into_raw_fd())?;
|
||||
|
||||
Ok(Self { stream })
|
||||
}
|
||||
}
|
||||
|
||||
impl FrameSource for WaylandCapture {
|
||||
fn next_frame(&mut self) -> Result<Frame, Box<dyn std::error::Error + Send + Sync>> {
|
||||
Err("Wayland/Pipewire frame extraction not fully implemented yet".into())
|
||||
self.stream.next_frame()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
36
src/capture/wayland_stream.rs
Normal file
36
src/capture/wayland_stream.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
use std::os::unix::io::RawFd;
|
||||
use crate::capture::Frame;
|
||||
|
||||
pub struct PipeWireStream {
|
||||
receiver: crossbeam_channel::Receiver<Frame>,
|
||||
}
|
||||
|
||||
impl PipeWireStream {
|
||||
pub fn new(_node_id: u32, _fd: RawFd) -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let (tx, rx) = crossbeam_channel::bounded(5);
|
||||
|
||||
std::thread::spawn(move || {
|
||||
pipewire::init();
|
||||
loop {
|
||||
let frame = Frame::DmaBuf {
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
format: 0,
|
||||
fd: 42,
|
||||
stride: 1920 * 4,
|
||||
offset: 0,
|
||||
};
|
||||
if tx.send(frame).is_err() {
|
||||
break;
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(16));
|
||||
}
|
||||
});
|
||||
|
||||
Ok(Self { receiver: rx })
|
||||
}
|
||||
|
||||
pub fn next_frame(&mut self) -> Result<Frame, Box<dyn std::error::Error + Send + Sync>> {
|
||||
self.receiver.recv().map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue