Closed entropin closed 1 year ago
Cool, looks useful so I will probably merge some form of it when I get time thanks
Also as a rational, most Reolink cameras do have a cgi-bin url to call to create a snap, the E1 and E1 Pro dose not, this can be used for a snapshot subcomand as well
I imagine that most use cases though such as a rtsp/onvif preview are pulling from the stream already and will just copy the next iframe, especially since you can't pull from the same connection twice.
Oki, so I added this "init_stream" toggle to my code in the PR for allowing the possibility of subscribing to frame capture first and than start the video stream later. or the reverse.
When trying to validate that this actually worked, I got into my first real big fight with the borrow checker....
I thought i caould just spawn a quick thread to test it out, so i added this to the rtps mod:
neolink\src\rtsp\mod.rs line 255
.........
info!(
"{}: Starting video stream {}",
camera_config.name, stream_name
);
let arc_cam = Arc::new(camera);
let sender = thread::spawn(move || {
let cam = &*arc_cam;
cam.capture_frame("mainStream", false);
});
arc_cam.start_video(outputs, stream_name).with_context(|| format!("Error while streaming {}", camera_config.name))
Am deep into research of Arc, Mutex and lifetimes so i don't need a deep explanation, i'll figure it out, but am wondering if what am trying to do is even possible. I have written like 50 variation of the code above, added 'static on 200 places and am starting to feel insane :D Is there a quick fix to this made up problem?
So arcs are about making sharable reference counted handles on something.
You make another copy with .clone
Have you tried:
let arc_cam = Arc::new(camera);
let cap_arc_cam = arc_cam.clone();
let sender = thread::spawn(move || {
cap_arc_cam.capture_frame("mainStream", false);
});
arc_cam.start_video(outputs, stream_name).with_context(|| format!("Error while streaming {}", camera_config.name))
It doesn't actually clone the underlying data just the increments the reference count.
Arc only works as read-only references &
never &mut
So if you want &mut
you have to combine it with something like a Mutex
which can lock an object to ensure that you are the sole user and therefore grant mutability. In this case though we don't need the mutability. So just Arc is fine.
You will run into another issue though because you can only subscribe to a msg id once.
And both your codes are trying to pull from msg id 3.
Thanks! Ah I have to look into the subscription code, not use if I'll need that on the Rust version so I'll just remove the toggle but later on you might see a PR for multiple receivers.
I have that in my c# client and it is handy in some cases.
Well I have an idea that will let us subscribe on the msg number rather then the message ID which will allow for this. But it will probably cause other issues if you try and request a HD stream twice.
It might be possible to just use a bus so that we can have one broadcaster and multiple consumers of the data
Hehe, so I have spent 6h now and am just about ready to give up on Rust :p Turn out my brain really needs static hashMaps or dicts when dealing with events.
Anyhow, it seams to me that I have to use a crossbeam or the like. So will try to play with that tomorrow :D
Neolink already links against crossbeam_channel
so yeah use it if you need it. If you want any specific help with something your welcome to post some code for discussion
Cool, I see that we use crossbeam in the RTSP mod, but I can't really understand why. Since we are using an arc_cam cant we just spawn "normal" threads? What magic powers does crossbeam give us? other than its awsome that's its inclouded since i need it :D
crossbeam also ensures rather nicely that all the threads close at the end of crossbeam::scope
although we could have done this with a std join instead.
Not sure if this makes sense for anyone else than me, but ill add it here anyhow, sine i use it in my branch and it seams harmless :)