Closed RReverser closed 1 year ago
Note: I know 0.10 branch is not the current one, but senpai branch is currently in an incompilable state on Windows (there are various errors) and I really just want to unblock myself, so hoping this can be backported at least into 0.10 for now.
UPD: also looks like cherry-pick applies almost cleanly onto senpai branch too, so porting to newer version won't be a problem either.
The only problem I'm having even after this PR is that my first example from #111 now outputs:
Querying...
Opening camera...
Waiting 1 sec...
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Trying to change format...
Got frame!
Changed format successfully!
Got frame!
And program exits and the callback is never called again. I thought maybe I need to camera.open_stream()?
again after changing parameters, but that fails with:
Error: Could not open device stream: Stream Already Open
I don't know what's going on here.
Slight coding oversight. Ill push a change to your PR to fix it to make it easier for me to cherry-pick later
I am away from my PC, unforunately making the edit hard. What you need to do is close the stream before you do any format operation than restart the stream.
What you need to do is close the stream before you do any format operation than restart the stream.
I tried that too, but same error (FWIW this is on Windows):
use nokhwa::pixel_format::RgbFormat;
use nokhwa::utils::{RequestedFormat, RequestedFormatType};
use nokhwa::CallbackCamera;
fn main() -> anyhow::Result<()> {
println!("Querying...");
let cameras = nokhwa::query(nokhwa::utils::ApiBackend::Auto)?;
println!("Opening camera...");
let mut camera = CallbackCamera::new(
cameras[0].index().clone(),
RequestedFormat::new::<RgbFormat>(RequestedFormatType::AbsoluteHighestResolution),
|_frame| {
println!("Got frame!");
},
)?;
camera.open_stream()?;
println!("Waiting 1 sec...");
std::thread::sleep(std::time::Duration::from_secs(1));
println!("Closing stream...");
camera.stop_stream()?;
println!("Trying to change format...");
camera.set_camera_requset(RequestedFormat::new::<RgbFormat>(
RequestedFormatType::AbsoluteHighestFrameRate,
))?;
println!("Changed format successfully!");
println!("Opening stream again...");
camera.open_stream()?;
Ok(())
}
Querying...
Opening camera...
Waiting 1 sec...
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Got frame!
Closing stream...
Got frame!
Trying to change format...
Got frame!
Changed format successfully!
Opening stream again...
Got frame!
Error: Could not open device stream: Stream Already Open
In fact, even if I don't do any config change but simply open stream - close stream - open stream again, it fails:
use nokhwa::pixel_format::RgbFormat;
use nokhwa::utils::{RequestedFormat, RequestedFormatType};
use nokhwa::CallbackCamera;
fn main() -> anyhow::Result<()> {
println!("Querying...");
let cameras = nokhwa::query(nokhwa::utils::ApiBackend::Auto)?;
println!("Opening camera...");
let mut camera = CallbackCamera::new(
cameras[0].index().clone(),
RequestedFormat::new::<RgbFormat>(RequestedFormatType::AbsoluteHighestResolution),
|_frame| {
println!("Got frame!");
},
)?;
camera.open_stream()?;
println!("Closing stream...");
camera.stop_stream()?;
println!("Opening stream again...");
camera.open_stream()?;
Ok(())
}
Querying...
Opening camera...
Closing stream...
Opening stream again...
Got frame!
Error: Could not open device stream: Stream Already Open
Looks like closing stream is not doing anything?
Probably some spaghetti stuck in thr closing stream code in nokhwa-bindings-windows...
I'll take a further look
-------- Original Message -------- On Apr. 17, 2023, 7:07 p.m., Ingvar Stepanyan wrote:
In fact, even if I don't do any config change but simply open stream - close stream - open stream again, it fails:
use
nokhwa
::
pixel_format
::
RgbFormat
;
use
nokhwa
::
utils
::
{
RequestedFormat
,
RequestedFormatType
}
;
use
nokhwa
::
CallbackCamera
;
fn
main
(
)
-> anyhow
::
Result
<
(
)
{
println
!
(
"Querying..."
)
;
let
cameras = nokhwa
::
query
(
nokhwa
::
utils
::
ApiBackend
::
Auto
)
?
;
println
!
(
"Opening camera..."
)
;
let
mut
camera =
CallbackCamera
::
new
(
cameras
[
0
]
.
index
(
)
.
clone
(
)
,
RequestedFormat
::
new
::
<
RgbFormat
(
RequestedFormatType
::
AbsoluteHighestResolution
)
,
|_frame|
{
println
!
(
"Got frame!"
)
;
}
,
)
?
;
camera
.
open_stream
(
)
?
;
println
!
(
"Closing stream..."
)
;
camera
.
stop_stream
(
)
?
;
println
!
(
"Opening stream again..."
)
;
camera
.
open_stream
(
)
?
;
Ok
(
(
)
)
}
Querying... Opening camera... Closing stream... Opening stream again... Got frame! Error: Could not open device stream: Stream Already Open
Looks like closing stream is not doing anything?
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
Looks like closing stream is not doing anything?
Yeah I think this is the problem: https://github.com/l1npengtul/nokhwa/blob/3f570ee0e5b72ec7957d8bc02fb83aae2392ff07/nokhwa-bindings-windows/src/lib.rs#L1187-L1189
This only sets a flag instead of really closing the stream, so when I try to open stream again, it tries to actually open it and fails.
As a temporary workaround, found that I can at least throw away the existing Camera and create a new one with desired format.
Any update on this, I'm experiencing the same issues with v4l2?
Too busy with other things lately, I think I'll restart development of 0.11 next week and hopefully it will be done by the end of summer. I'll merge this for now so you can point at git for Cargo.
This fixes lock contention that prevented any operations on the camera once capture loop is started by using a fair mutex instead of a regular one.
It's slightly more expensive, but this usecase - trying to access a shared resource that is repeatedly locked/unlocked by someone else - is exactly what it's designed for, and indeed it fixes the deadlock issue.
Fixes #111.