Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nokwha::query(ApiBackend::MediaFoundation) causes panic on Windows w/ no cam plugged in #192

Open
njrogie opened this issue Dec 22, 2024 · 5 comments

Comments

@njrogie
Copy link

njrogie commented Dec 22, 2024

On windows, desktop PC, no builtin camera, I ran the following code:

let cameras = nokhwa::query(ApiBackend::MediaFoundation);
match cameras {
    Err(err) => {
        info!("No cameras present!");
    }, 
    Ok(cameras) => {
         for (idx, camera) in cameras.iter().enumerate() {
              info!("{}: {}", idx, camera.human_name())
         }
    }
}

When i plug my usb webcam in, i get the following output:

0: NexiGo N60 FHD Webcam

When no camera is plugged in, the windows bindings panic.

thread 'tests::test_print_info' panicked at core\src\panicking.rs:221:5:
unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`
stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/std\src\panicking.rs:662
   1: core::panicking::panic_nounwind_fmt::runtime
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/core\src\panicking.rs:112
   2: core::panicking::panic_nounwind_fmt
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/core\src\panicking.rs:122
   3: core::panicking::panic_nounwind
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/core\src\panicking.rs:221
   4: core::slice::raw::from_raw_parts::precondition_check
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library\core\src\ub_checks.rs:70
   5: core::slice::raw::from_raw_parts<enum2$<core::option::Option<windows::Windows::Win32::Media::MediaFoundation::IMFActivate> > >
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library\core\src\ub_checks.rs:77
   6: nokhwa_bindings_windows::wmf::query_activate_pointers
             at C:\Users\njrog\.cargo\registry\src\index.crates.io-6f17d22bba15001f\nokhwa-bindings-windows-0.4.1\src\lib.rs:278
   7: nokhwa_bindings_windows::wmf::query_media_foundation_descriptors
             at C:\Users\njrog\.cargo\registry\src\index.crates.io-6f17d22bba15001f\nokhwa-bindings-windows-0.4.1\src\lib.rs:365
   8: nokhwa::query::query_msmf
             at C:\Users\njrog\.cargo\registry\src\index.crates.io-6f17d22bba15001f\nokhwa-0.10.5\src\query.rs:269
   9: nokhwa::query::query
             at C:\Users\njrog\.cargo\registry\src\index.crates.io-6f17d22bba15001f\nokhwa-0.10.5\src\query.rs:98
  10: display_video::impl$0::default
             at .\src\lib.rs:12
  11: display_video::tests::test_print_info
             at .\src\lib.rs:39
  12: display_video::tests::test_print_info::closure$0
             at .\src\lib.rs:38
  13: core::ops::function::FnOnce::call_once<display_video::tests::test_print_info::closure_env$0,tuple$<> >
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library\core\src\ops\function.rs:250
  14: core::ops::function::FnOnce::call_once
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14\library/core\src\ops\function.rs:250

Seems like the windows bindings may need to be updated to handle a 'no-camera' state?

@njrogie njrogie changed the title nokwha::query(ApiBackend::MediaFoundation) causes panic on Windows nokwha::query(ApiBackend::MediaFoundation) causes panic on Windows w/ no cam plugged in Dec 22, 2024
@njrogie
Copy link
Author

njrogie commented Dec 22, 2024

I see now that this issue was fixed months ago in nokhwa-bindings-windows. However, when cargo installs the bindings crate to my registry (crates.io), it seems to install an older version of the lib.rs file.

@njrogie
Copy link
Author

njrogie commented Dec 22, 2024

On returning to this today, I'd really like to be able to compile from source in windows to be able to use the most recent code. However, the build for nokhwa-core is broken at the moment (errors attached). Is there a correct way to get the build to work?

PS G:\Code\nokhwa> cargo build
   Compiling num-traits v0.2.19
   Compiling cfg-if v1.0.0
   Compiling scopeguard v1.2.0
   Compiling bytemuck v1.20.0
   Compiling serde v1.0.197
   Compiling libc v0.2.153
   Compiling futures-sink v0.3.30
   Compiling futures-core v0.3.30
   Compiling byteorder v1.5.0
   Compiling syn v2.0.87
   Compiling arrayvec v0.7.4
   Compiling bytes v1.6.0
   Compiling lock_api v0.4.11                                                                                                                                                                
   Compiling getrandom v0.2.12                                                                                                                                                               
   Compiling mozjpeg-sys v2.1.0
   Compiling nanorand v0.7.0
   Compiling rgb v0.8.37
   Compiling spin v0.9.8
   Compiling mozjpeg v0.10.7
   Compiling flume v0.11.0
   Compiling num-integer v0.1.46
   Compiling image v0.25.0
   Compiling thiserror-impl v2.0.0
   Compiling thiserror-impl v1.0.69
   Compiling num-rational v0.4.2
   Compiling thiserror v1.0.69
   Compiling thiserror v2.0.0
   Compiling nokhwa-core v0.2.0 (G:\Code\nokhwa\nokhwa-core)
error[E0583]: file not found for module `query`
  --> nokhwa-core\src\lib.rs:32:1
   |
32 | pub mod query;
   | ^^^^^^^^^^^^^^
   |
   = help: to create the module `query`, create file "nokhwa-core\src\query.rs" or "nokhwa-core\src\query\mod.rs"
   = note: if there is a `mod query` elsewhere in the crate already, import it with `use crate::...` instead

error[E0432]: unresolved import `crate::camera::AsyncCamera`
  --> nokhwa-core\src\platform.rs:1:21
   |
1  | use crate::camera::{AsyncCamera, Camera};
   |                     ^^^^^^^^^^^ no `AsyncCamera` in `camera`
   |
note: found an item that was configured out
  --> nokhwa-core\src\camera.rs:65:11
   |
65 | pub trait AsyncCamera: Camera + AsyncSetting + AsyncStream {}
   |           ^^^^^^^^^^^
note: the item is gated behind the `r#async` feature
  --> nokhwa-core\src\camera.rs:64:7
   |
64 | #[cfg(feature = "async")]
   |       ^^^^^^^^^^^^^^^^^

error[E0432]: unresolved import `crate::types::ApiBackend`
  --> nokhwa-core\src\error.rs:16:40
   |
16 | use crate::{frame_format::FrameFormat, types::ApiBackend};
   |                                        ^^^^^^^^^^^^^^^^^ no `ApiBackend` in `types`

warning: unexpected `cfg` condition value: `test-fail-warning`
 --> nokhwa-core\src\lib.rs:6:13
  |
6 | #![cfg_attr(feature = "test-fail-warning", deny(warnings))]
  |             ^^^^^^^^^^-------------------
  |                       |
  |                       help: there is a expected value with a similar name: `"test-fail-warnings"`
  |
  = note: expected values for `feature` are: `async`, `async-trait`, `default`, `docs-features`, `futures`, `opencv`, `opencv-mat`, `serde`, `serialize`, `test-fail-warnings`, `wgpu`, and `wgpu-types`
  = help: consider adding `test-fail-warning` as a feature in `Cargo.toml`
  = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
  = note: `#[warn(unexpected_cfgs)]` on by default

error[E0599]: the method `as_display` exists for reference `&Backends`, but its trait bounds were not satisfied
   --> nokhwa-core\src\error.rs:59:13
    |
59  |     #[error("This operation is not supported by backend {0}.")]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `&Backends` due to unsatisfied trait bounds
    |
   ::: nokhwa-core\src\platform.rs:6:1
    |
6   | pub enum Backends {
    | ----------------- doesn't satisfy `Backends: std::fmt::Display`
    |
    = note: the following trait bounds were not satisfied:
            `Backends: std::fmt::Display`
            which is required by `&Backends: AsDisplay<'_>`
note: the trait `std::fmt::Display` must be implemented
   --> C:\Users\njrog\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\fmt\mod.rs:724:1
    |
724 | pub trait Display {
    | ^^^^^^^^^^^^^^^^^
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `as_display`, perhaps you need to implement it:
            candidate #1: `AsDisplay`

error[E0277]: the `?` operator can only be used on `ControlFlow`s in a method that returns `ControlFlow`
   --> nokhwa-core\src\properties.rs:198:42
    |
189 |     pub fn validate(&self, value: &ControlValue) -> ControlFlow<()> {
    |     --------------------------------------------------------------- this function returns a `ControlFlow`
...
198 |                     int_range.validate(i)?;
    |                                          ^ this `?` produces `Result<Infallible, RangeValidationFailure>`, which is incompatible with `ControlFlow<()>`
    |
    = help: the trait `FromResidual<Result<Infallible, RangeValidationFailure>>` is not implemented for `ControlFlow<()>`
    = help: the trait `FromResidual<ControlFlow<(), Infallible>>` is implemented for `ControlFlow<()>`
    = help: for that trait implementation, expected `ControlFlow<(), Infallible>`, found `Result<Infallible, RangeValidationFailure>`

error[E0277]: the `?` operator can only be used on `ControlFlow`s in a method that returns `ControlFlow`
   --> nokhwa-core\src\properties.rs:208:44
    |
189 |     pub fn validate(&self, value: &ControlValue) -> ControlFlow<()> {
    |     --------------------------------------------------------------- this function returns a `ControlFlow`
...
208 |                     float_range.validate(i)?;
    |                                            ^ this `?` produces `Result<Infallible, RangeValidationFailure>`, which is incompatible with `ControlFlow<()>`
    |
    = help: the trait `FromResidual<Result<Infallible, RangeValidationFailure>>` is not implemented for `ControlFlow<()>`
    = help: the trait `FromResidual<ControlFlow<(), Infallible>>` is implemented for `ControlFlow<()>`
    = help: for that trait implementation, expected `ControlFlow<(), Infallible>`, found `Result<Infallible, RangeValidationFailure>`

error[E0515]: cannot return value referencing temporary value
   --> nokhwa-core\src\properties.rs:335:9
    |
335 | /         match self {
336 | |             ControlValuePrimitive::Null => &ControlValue::Null,
337 | |             ControlValuePrimitive::Integer(i) => &ControlValue::Integer(*i),
    | |                                                   ------------------------- temporary value created here
338 | |             ControlValuePrimitive::BitMask(b) => &ControlValue::BitMask(*b),
...   |
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
342 | |         }
    | |_________^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing temporary value
   --> nokhwa-core\src\properties.rs:335:9
    |
335 | /         match self {
336 | |             ControlValuePrimitive::Null => &ControlValue::Null,
337 | |             ControlValuePrimitive::Integer(i) => &ControlValue::Integer(*i),
338 | |             ControlValuePrimitive::BitMask(b) => &ControlValue::BitMask(*b),
    | |                                                   ------------------------- temporary value created here
...   |
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
342 | |         }
    | |_________^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing temporary value
   --> nokhwa-core\src\properties.rs:335:9
    |
335 | /         match self {
336 | |             ControlValuePrimitive::Null => &ControlValue::Null,
337 | |             ControlValuePrimitive::Integer(i) => &ControlValue::Integer(*i),
338 | |             ControlValuePrimitive::BitMask(b) => &ControlValue::BitMask(*b),
339 | |             ControlValuePrimitive::Float(f) => &ControlValue::Float(*f),
    | |                                                 ----------------------- temporary value created here
340 | |             ControlValuePrimitive::String(s) => &ControlValue::String(s.clone()),
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
342 | |         }
    | |_________^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing temporary value
   --> nokhwa-core\src\properties.rs:335:9
    |
335 | /         match self {
336 | |             ControlValuePrimitive::Null => &ControlValue::Null,
337 | |             ControlValuePrimitive::Integer(i) => &ControlValue::Integer(*i),
338 | |             ControlValuePrimitive::BitMask(b) => &ControlValue::BitMask(*b),
339 | |             ControlValuePrimitive::Float(f) => &ControlValue::Float(*f),
340 | |             ControlValuePrimitive::String(s) => &ControlValue::String(s.clone()),
    | |                                                  ------------------------------- temporary value created here
    | |                                                  ------------------------------- temporary value created here
    | |                                                  ------------------------------- temporary value created here
    | |                                                  ------------------------------- temporary value created here
    | |                                                  ------------------------------- temporary value created here
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
    | |                                                  ------------------------------- temporary value created here
    | |                                                  ------------------------------- temporary value created here
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
    | |                                                  ------------------------------- temporary value created here
    | |                                                  ------------------------------- temporary value created here
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
    | |                                                  ------------------------------- temporary value created here
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
342 | |         }
    | |_________^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing temporary value
    | |                                                  ------------------------------- temporary value created here
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
342 | |         }
    | |_________^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing temporary value
   --> nokhwa-core\src\properties.rs:335:9
    |
335 | /         match self {
336 | |             ControlValuePrimitive::Null => &ControlValue::Null,
337 | |             ControlValuePrimitive::Integer(i) => &ControlValue::Integer(*i),
338 | |             ControlValuePrimitive::BitMask(b) => &ControlValue::BitMask(*b),
...   |
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
    | |                                                   ------------------------- temporary value created here
    | |                                                  ------------------------------- temporary value created here
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
342 | |         }
    | |_________^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing temporary value
   --> nokhwa-core\src\properties.rs:335:9
    |
335 | /         match self {
336 | |             ControlValuePrimitive::Null => &ControlValue::Null,
337 | |             ControlValuePrimitive::Integer(i) => &ControlValue::Integer(*i),
338 | |             ControlValuePrimitive::BitMask(b) => &ControlValue::BitMask(*b),
...   |
    | |                                                  ------------------------------- temporary value created here
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
342 | |         }
    | |_________^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing temporary value
   --> nokhwa-core\src\properties.rs:335:9
    |
335 | /         match self {
336 | |             ControlValuePrimitive::Null => &ControlValue::Null,
    | |                                                  ------------------------------- temporary value created here
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
342 | |         }
    | |_________^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing temporary value
   --> nokhwa-core\src\properties.rs:335:9
    |
    | |                                                  ------------------------------- temporary value created here
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
342 | |         }
    | |_________^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing temporary value
342 | |         }
    | |_________^ returns a value referencing data owned by the current function

    | |_________^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing temporary value
   --> nokhwa-core\src\properties.rs:335:9
    |
335 | /         match self {
336 | |             ControlValuePrimitive::Null => &ControlValue::Null,
337 | |             ControlValuePrimitive::Integer(i) => &ControlValue::Integer(*i),
338 | |             ControlValuePrimitive::BitMask(b) => &ControlValue::BitMask(*b),
...   |
341 | |             ControlValuePrimitive::Boolean(b) => &ControlValue::Boolean(*b),
    | |                                                   ------------------------- temporary value created here
342 | |         }
    | |_________^ returns a value referencing data owned by the current function

Some errors have detailed explanations: E0277, E0432, E0515, E0583, E0599.
For more information about an error, try `rustc --explain E0277`.
warning: `nokhwa-core` (lib) generated 1 warning
error: could not compile `nokhwa-core` (lib) due to 11 previous errors; 1 warning emitted

@l1npengtul
Copy link
Owner

senpai is broken, have you tried using cargo update and using nokhwa 0.10.7?

@njrogie
Copy link
Author

njrogie commented Dec 28, 2024

Here's my cargo.toml (the project is to try to display the camera feed in egui, which isn't quite relevant to this issue but it's worth mentioning).

[package]
name = "display-video"
version = "0.1.0"
edition = "2021"

[dependencies]
# egui
eframe = { version = "0.30.0", features = ["default"] }
epaint = { version = "0.30.0" }

# nokhwa  
nokhwa = { version = "0.10.7", features = ["input-msmf"]}

# Logging
env_logger = { version = "0.11.5", default-features = false, features = [
    "auto-color",
    "humantime",
] }
log = "0.4.22"

after running cargo update I still have the older nokwha-bindings-windows stored in .cargo\registry\src and .cargo\registry\cache. So i deleted the stored crate on my computer and re-downloaded it. The downloaded version from crates.io for nokwha-bindings-windows 0.4.2 continues to have the bug in it, even when the nokwha version is set to 0.10.7.

@njrogie
Copy link
Author

njrogie commented Dec 28, 2024

Also, I wanted to know whether you would be open to a PR for fixing the senpai build?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants