updates
This commit is contained in:
parent
dbdfbe5aaa
commit
45987c7ff5
@ -10,7 +10,7 @@ use tonic::Request;
|
|||||||
use tracing::{debug, error, info, warn};
|
use tracing::{debug, error, info, warn};
|
||||||
use winit::{
|
use winit::{
|
||||||
event_loop::EventLoopBuilder,
|
event_loop::EventLoopBuilder,
|
||||||
platform::x11::EventLoopBuilderExtX11,
|
// platform::x11::EventLoopBuilderExtX11,
|
||||||
platform::wayland::EventLoopBuilderExtWayland,
|
platform::wayland::EventLoopBuilderExtWayland,
|
||||||
event::Event,
|
event::Event,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -26,7 +26,7 @@ impl MonitorWindow {
|
|||||||
|
|
||||||
// appsrc -> decode -> convert -> waylandsink
|
// appsrc -> decode -> convert -> waylandsink
|
||||||
let desc = "appsrc name=src is-live=true format=time do-timestamp=true ! \
|
let desc = "appsrc name=src is-live=true format=time do-timestamp=true ! \
|
||||||
queue ! h264parse ! avdec_h264 ! videoconvert ! \
|
queue ! h264parse ! decodebin ! videoconvert ! \
|
||||||
waylandsink name=sink sync=false";
|
waylandsink name=sink sync=false";
|
||||||
|
|
||||||
let pipeline = gst::parse::launch(desc)?
|
let pipeline = gst::parse::launch(desc)?
|
||||||
|
|||||||
@ -18,18 +18,6 @@ options uvcvideo quirks=0x200 timeout=10000
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
echo "==> 2b. Predictable /dev names for each capture card"
|
echo "==> 2b. Predictable /dev names for each capture card"
|
||||||
# sudo tee /etc/udev/rules.d/85-gc311.rules >/dev/null <<'RULES'
|
|
||||||
# # RIGHT eye (video index 0)
|
|
||||||
# SUBSYSTEM=="video4linux", ATTRS{idVendor}=="07ca", ATTRS{idProduct}=="3311", \
|
|
||||||
# ATTRS{serial}=="5313550401897", ATTR{index}=="0", \
|
|
||||||
# SYMLINK+="lesavka_r_eye"
|
|
||||||
|
|
||||||
# # LEFT eye (video index 0)
|
|
||||||
# SUBSYSTEM=="video4linux", ATTRS{idVendor}=="07ca", ATTRS{idProduct}=="3311", \
|
|
||||||
# ATTRS{serial}=="1200655409098", ATTR{index}=="0", \
|
|
||||||
# SYMLINK+="lesavka_l_eye"
|
|
||||||
# RULES
|
|
||||||
|
|
||||||
# probe all v4l2 devices, keep only the two GC311 capture cards
|
# probe all v4l2 devices, keep only the two GC311 capture cards
|
||||||
mapfile -t GC_VIDEOS < <(
|
mapfile -t GC_VIDEOS < <(
|
||||||
sudo v4l2-ctl --list-devices |
|
sudo v4l2-ctl --list-devices |
|
||||||
|
|||||||
@ -81,6 +81,7 @@ struct Handler {
|
|||||||
|
|
||||||
impl Handler {
|
impl Handler {
|
||||||
async fn make(gadget: UsbGadget) -> anyhow::Result<Self> {
|
async fn make(gadget: UsbGadget) -> anyhow::Result<Self> {
|
||||||
|
gadget.cycle().ok();
|
||||||
let kb = OpenOptions::new().write(true).open("/dev/hidg0").await?;
|
let kb = OpenOptions::new().write(true).open("/dev/hidg0").await?;
|
||||||
let ms = OpenOptions::new().write(true)
|
let ms = OpenOptions::new().write(true)
|
||||||
.custom_flags(libc::O_NONBLOCK)
|
.custom_flags(libc::O_NONBLOCK)
|
||||||
@ -101,7 +102,7 @@ impl Relay for Handler {
|
|||||||
&self,
|
&self,
|
||||||
req: Request<tonic::Streaming<KeyboardReport>>,
|
req: Request<tonic::Streaming<KeyboardReport>>,
|
||||||
) -> Result<Response<Self::StreamKeyboardStream>, Status> {
|
) -> Result<Response<Self::StreamKeyboardStream>, Status> {
|
||||||
self.gadget.cycle().map_err(|e| Status::internal(e.to_string()))?;
|
// self.gadget.cycle().map_err(|e| Status::internal(e.to_string()))?;
|
||||||
let (tx, rx) = tokio::sync::mpsc::channel(32);
|
let (tx, rx) = tokio::sync::mpsc::channel(32);
|
||||||
let kb = self.kb.clone();
|
let kb = self.kb.clone();
|
||||||
|
|
||||||
@ -155,17 +156,24 @@ impl Relay for Handler {
|
|||||||
) -> Result<Response<Self::CaptureVideoStream>, Status> {
|
) -> Result<Response<Self::CaptureVideoStream>, Status> {
|
||||||
let r = req.into_inner();
|
let r = req.into_inner();
|
||||||
|
|
||||||
let devs = loop {
|
// let devs = loop {
|
||||||
let list = list_gc311_devices()
|
// let list = list_gc311_devices()
|
||||||
.map_err(|e| Status::internal(format!("enum v4l2: {e}")))?;
|
// .map_err(|e| Status::internal(format!("enum v4l2: {e}")))?;
|
||||||
if !list.is_empty() { break list; }
|
// if !list.is_empty() { break list; }
|
||||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
// tokio::time::sleep(Duration::from_secs(1)).await;
|
||||||
};
|
// };
|
||||||
|
|
||||||
let dev = devs
|
// let dev = devs
|
||||||
.get(r.id as usize)
|
// .get(r.id as usize)
|
||||||
.ok_or_else(|| Status::invalid_argument(format!("monitor id {} absent", r.id)))?
|
// .ok_or_else(|| Status::invalid_argument(format!("monitor id {} absent", r.id)))?
|
||||||
.to_owned();
|
// .to_owned();
|
||||||
|
|
||||||
|
let dev = match r.id {
|
||||||
|
0 => "/dev/lesavka_l_eye",
|
||||||
|
1 => "/dev/lesavka_r_eye",
|
||||||
|
_ => return Err(Status::invalid_argument("monitor id must be 0 or 1")),
|
||||||
|
}
|
||||||
|
.to_string();
|
||||||
|
|
||||||
info!("🎥 streaming {dev} at ≤{} kb/s", r.max_bitrate);
|
info!("🎥 streaming {dev} at ≤{} kb/s", r.max_bitrate);
|
||||||
|
|
||||||
@ -191,8 +199,6 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
// tokio::spawn(async { monitor_gc311_disconnect().await.ok(); });
|
// tokio::spawn(async { monitor_gc311_disconnect().await.ok(); });
|
||||||
|
|
||||||
let gadget = UsbGadget::new("lesavka");
|
let gadget = UsbGadget::new("lesavka");
|
||||||
gadget.cycle().ok();
|
|
||||||
|
|
||||||
let handler = Handler::make(gadget.clone()).await?;
|
let handler = Handler::make(gadget.clone()).await?;
|
||||||
|
|
||||||
// tokio::spawn({
|
// tokio::spawn({
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user