GithubHelp home page GithubHelp logo

l1npengtul / nokhwa Goto Github PK

View Code? Open in Web Editor NEW
444.0 16.0 97.0 7.09 MB

Cross Platform Rust Library for Powerful Webcam/Camera Capture

License: Apache License 2.0

Rust 99.83% Shell 0.17%
avfoundation camera camera-api cross-platform linux macos mediafoundation rust v4l2 webcam

nokhwa's Introduction

cargo version docs.rs version

nokhwa

Nokhwa(녹화): Korean word meaning "to record".

A Simple-to-use, cross-platform Rust Webcam Capture Library

Using nokhwa

Nokhwa can be added to your crate by adding it to your Cargo.toml:

[dependencies.nokhwa]
version = "0.10.0"
# Use the native input backends, enable WGPU integration
features = ["input-native", "output-wgpu"]

Most likely, you will only use functionality provided by the Camera struct. If you need lower-level access, you may instead opt to use the raw capture backends found at nokhwa::backends::capture::*.

Example

// first camera in system
let index = CameraIndex::Index(0); 
// request the absolute highest resolution CameraFormat that can be decoded to RGB.
let requested = RequestedFormat::new::<RgbFormat>(RequestedFormatType::AbsoluteHighestFrameRate);
// make the camera
let mut camera = Camera::new(index, requested).unwrap();

// get a frame
let frame = camera.frame().unwrap();
println!("Captured Single Frame of {}", frame.buffer().len());
// decode into an ImageBuffer
let decoded = frame.decode_image::<RgbFormat>().unwrap();
println!("Decoded Frame of {}", decoded.len());

A command line app made with nokhwa can be found in the examples folder.

API Support

The table below lists current Nokhwa API support.

  • The Backend column signifies the backend.
  • The Input column signifies reading frames from the camera
  • The Query column signifies system device list support
  • The Query-Device column signifies reading device capabilities
  • The Platform column signifies what Platform this is availible on.
Backend Input Query Query-Device Platform
Video4Linux(input-native) Linux
MSMF(input-native) Windows
AVFoundation(input-native) Mac
OpenCV(input-opencv)^ Linux, Windows, Mac
WASM(input-wasm) Browser(Web)

✅: Working, 🔮 : Experimental, ❌ : Not Supported, 🚧: Planned/WIP

^ = May be bugged. Also supports IP Cameras.

Feature

The default feature includes nothing. Anything starting with input-* is a feature that enables the specific backend.

input-* features:

  • input-native: Uses either V4L2(Linux), MSMF(Windows), or AVFoundation(Mac OS)
  • input-opencv: Enables the opencv backend. (cross-platform)
  • input-jscam: Enables the use of the JSCamera struct, which uses browser APIs. (Web)

Conversely, anything that starts with output-* controls a feature that controls the output of something (usually a frame from the camera)

output-* features:

  • output-wgpu: Enables the API to copy a frame directly into a wgpu texture.
  • output-threaded: Enable the threaded/callback based camera.

Other features:

  • decoding: Enables mozjpeg decoding. Enabled by default.
  • docs-only: Documentation feature. Enabled for docs.rs builds.
  • docs-nolink: Build documentation without linking to any libraries. Enabled for docs.rs builds.
  • test-fail-warning: Fails on warning. Enabled in CI.

You many want to pick and choose to reduce bloat.

Issues

If you are making an issue, please make sure that

  • It has not been made yet
  • Attach what you were doing, your environment, steps to reproduce, and backtrace. Thank you!

Contributing

Contributions are welcome!

  • Please rustfmt all your code and adhere to the clippy lints (unless necessary not to do so)
  • Please limit use of unsafe
  • All contributions are under the Apache 2.0 license unless otherwise specified

Minimum Service Rust Version

nokhwa may build on older versions of rustc, but there is no guarantee except for the latest stable rust.

Sponsors

Please consider donating! It helps me not look like a failure to my parents!

nokhwa's People

Contributors

aleokdev avatar aprilwade avatar bookshiyi avatar chemicalxandco avatar danielmschmidt avatar foxzool avatar gennyble avatar hanguk0726 avatar joepio avatar josephcatrambone avatar kuy avatar l1npengtul avatar leofidus avatar marc2332 avatar michivi avatar oskargustafsson avatar otak avatar payload avatar quartzo avatar roughack avatar sayanarijit avatar someguynamedjosh avatar starccy avatar stefan-muc avatar valeth avatar yamt avatar ytanimura avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nokhwa's Issues

Memory leakage occurs when too much delay per frame using `input-gst`

Hi, I'm a fan of nokhwa library.

Problem

  • When using the input-gst feature, I found a problem that the memory usage increases indefinitely as the computation time per frame is longer than fps.
use nokhwa::{Camera, CameraFormat, FrameFormat};

fn main() {
    // set up the Camera
    let mut camera = Camera::new(
        0,
        Some(CameraFormat::new_from(640, 480, FrameFormat::MJPEG, 30)),
    )
    .unwrap();

    // open stream
    camera.open_stream().unwrap();
    loop {
        let frame = camera.frame().unwrap();
        println!("{}, {}", frame.width(), frame.height());

        // FIXME: Memory leakage occurs when too much delay per frame using `input-gst`
        std::thread::sleep(std::time::Duration::from_secs(9999));
    }
}

Environment

  • OS: Linux (ArchLinux)
  • gstreamer: 1.18.5-1
  • rustc: 1.56.1

Expected reason

  • There is no constraint on the frame buffer.

Expected solution

  • Set the size constraint of the frame buffer, and let the user control it.

Can't get frame from camera

I can't get frame from camera, it says

ReadFrameError("Input/output error (os error 5)")'

after like 15-30 seconds on this line:

let frame = camera.frame().unwrap();

I'm on Linux and specified v4l backend

Error building latest commit with msmf

The latest commit does not compile correctly with msmf feature enable.

To fix, fourcc needs to become guid on line 171 in lib.rs, as well as frame_rate_min being changed to frame_rate in the same file.

ThreadedCamera::open_stream type mismatch

Ran across this type mismatch error when creating a callback function for ThreadedCamera::open_stream. Looks like it's requiring the ImageBuffer struct from the private image::buffer_ module as a callback parameter type rather than the public struct in image. I poked around in threaded.rs, but it looks like it's just importing the regular struct. Not sure wth is going on here. This is pretty much a direct copy of the Threaded example

image
image
image

Only get last frame, ignoring missed frames

I'm making an app with nannou, but my webcam gets lagged behind quite a bit when my drawing cannot keep up with it's framerate.

Is there a way to get only the latest frame available, and ignore any other frames that might've been missed?

0.10.0-rc1 `output-threaded` no longer compiles

I am receiving the following errors when trying to compile a project which depends upon nokhwa on version 0.10.0-rc1.

error[E0507]: cannot move out of a shared reference
  --> /home/antony/.cargo/registry/src/github.com-1ecc6299db9ec823/nokhwa-0.10.0-rc.1/src/threaded.rs:87:12
   |
87 |           Ok(*self
   |  ____________^
88 | |             .camera
89 | |             .lock()
90 | |             .map_err(|why| NokhwaError::GeneralError(why.to_string()))?
91 | |             .index())
   | |____________________^ move occurs because value has type `CameraIndex`, which does not implement the `Copy` trait
error[E0507]: cannot move out of a shared reference
   --> /home/antony/.cargo/registry/src/github.com-1ecc6299db9ec823/nokhwa-0.10.0-rc.1/src/threaded.rs:125:12
    |
125 |           Ok(*self
    |  ____________^
126 | |             .camera
127 | |             .lock()
128 | |             .map_err(|why| NokhwaError::GeneralError(why.to_string()))?
129 | |             .info())
    | |___________________^ move occurs because value has type `CameraInfo`, which does not implement the `Copy` trait
error[E0596]: cannot borrow `last_frame` as mutable, as it is not declared as mutable
   --> /home/antony/.cargo/registry/src/github.com-1ecc6299db9ec823/nokhwa-0.10.0-rc.1/src/threaded.rs:490:22
    |
489 |                 if let Ok(last_frame) = last_frame_captured.lock() {
    |                           ---------- help: consider changing this to be mutable: `mut last_frame`
490 |                     *last_frame = frame.clone();
    |                      ^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `cb` as mutable, as it is not declared as mutable
   --> /home/antony/.cargo/registry/src/github.com-1ecc6299db9ec823/nokhwa-0.10.0-rc.1/src/threaded.rs:492:25
    |
491 |                     if let Ok(cb) = frame_callback.lock() {
    |                               -- help: consider changing this to be mutable: `mut cb`
492 |                         cb(frame);
    |                         ^^ cannot borrow as mutable

info: The currently active `rustc` version is `rustc 1.65.0 (897e37553 2022-11-02)`

I believe this is the commit which last made changes to this code: 4677ce0

Please let me know if any further information is needed.

Does not build on Mac

Hi, thank you for maintaining this crate!

It seems there is symbol(s) not found for architecture arm64 when building on a MacBook with an M1 processor (update: the same issue is encountered while trying to build on x86-64 mac, so CPU architecture does not matter here).

Here is the code I use:

use {
    std::{thread::sleep, time::Duration},
    nokhwa::{Camera, nokhwa_initialize, query},
};

fn main() {
    nokhwa_initialize(|result| {
        println!("on_complete: {}, query: {:?}", result, query()); 
        let camera = Camera::new(1, None).unwrap();
        println!("camera: {:?}", camera.info());
    });
    sleep(Duration::from_secs(10));
}

Cargo.toml:

[package]
name = "nokhwa-testing"
version = "0.1.0"
edition = "2021"

[dependencies]
nokhwa = { version = "0.9.4", features = ["input-avfoundation"] }

Here is a linker error I encounter:

error: linking with `cc` failed: exit status: 1
  |
  = note: "cc" "-arch" "arm64" "/var/folders/k8/tc8kf6997r9gwl156j5b0g1h0000gn/T/rustcad2hl8/symbols.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.11b26thxr2zkmh75.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.14ju9lp2uv7xhil7.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.1isbi16a1tjg7o5f.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.3157rqi1un27yfph.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.339giqviijkbdou6.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.3kwn36whf96wn4nw.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.3oypbmz1qu6dv53c.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.3p3ucd0uz6i9kmmt.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.3q1aqfnimpcwrq6k.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.3qmqqgs3zmfmeqas.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.3wb3sk0nl9iivagx.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.417cdvo4hhcqac1g.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.49s8netqzp6lphje.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.4zqfqkynbefkt7uy.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.51smx5yvu2pz9xip.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.54eb0f5x3en2jk52.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.8wxashage992bxm.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.nfdq08phd3fnq4o.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.x7vl8kune1u8ikw.rcgu.o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8.3yj7iby9c11nidld.rcgu.o" "-L" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps" "-L" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/build/mozjpeg-sys-f582892835282850/out" "-L" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/build/mozjpeg-sys-f582892835282850/out" "-L" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/build/objc_exception-c7958e843b8e62bd/out" "-L" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libnokhwa-1a079bdbbb5589a9.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libmozjpeg-6634d948351acdd4.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/librgb-480af82697f3e438.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libfallible_collections-3309b696366dad20.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libhashbrown-1d8e74aeb478f341.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libahash-5f759626124e5b0b.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libonce_cell-4e22a751c4ad0e53.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libarrayvec-efc691a55c0983c5.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libmozjpeg_sys-09fe7e07ea2f7db4.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libnokhwa_bindings_macos-4cd999170c2a10bf.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libflume-ed4efa3fd1d7557e.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libspin-2407881c60aa70b0.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/liblock_api-7fbb72b6cfc1b0c6.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libscopeguard-eb1e61010332a1cf.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libpin_project-a98907d1fcb05856.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libfutures_sink-40b09e67990431db.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libfutures_core-1b3a27dc641a732a.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libnanorand-a27a2d340e69126f.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libgetrandom-732ae10a5aefa5d2.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libdashmap-a83262b3454e3e27.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libnum_cpus-3b913b51fe59fbf0.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libcfg_if-e6509c5f025d8702.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libcocoa_foundation-f4d5900a80da637b.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libforeign_types-b1a73fdbd94e948a.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libforeign_types_shared-b2b813634eacbc55.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libcore_graphics_types-2e141c6049806b3c.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libcore_foundation-8928320c492b4635.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libcore_foundation_sys-a98884409e1a2efe.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libbitflags-295066ef4f1a08fb.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libblock-54d07849328ebd85.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libcore_media_sys-06f8f5185bcc4631.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libcore_foundation_sys-d16b009260a549e9.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libcfg_if-504e5b6598191998.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libthiserror-0b5d3046e86037a8.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/liblazy_static-f75dab69ff4510ec.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libobjc-0959b0f3a1d78466.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libobjc_exception-08e7865472ccbbe2.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libmalloc_buf-36827c8d724d6279.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/liblibc-1b5ce4b92aa38abf.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libimage-79c28f91dd58bf9a.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libcolor_quant-22192260062230e7.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libnum_iter-7d6461ad6c5f1c6d.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libbytemuck-88e115a31e194307.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libnum_rational-84c9edafed28713c.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libnum_integer-824e1dd12fc03d2b.rlib" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/libnum_traits-4b4376f67277d6cf.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libstd-af3f3292c66eb7cc.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libpanic_unwind-bc47a5a819240eac.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libobject-5fa6d29c50391a26.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libmemchr-9f34659cc49c55cf.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libaddr2line-0ca0691d5024e0e7.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libgimli-8b09daf3a02ae894.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/librustc_demangle-c8e6e1ad4a56d084.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libstd_detect-cc5bb2a5896a5a35.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libhashbrown-ba2ca40bd5b846ac.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libminiz_oxide-eddbbfd8a1284efa.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libadler-0d5fdbc7da87a8dd.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/librustc_std_workspace_alloc-94febd0ddea042d3.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libunwind-9231f6f457586171.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libcfg_if-3e833ccda9a92f6a.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/liblibc-e2416b3132f6fa90.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/liballoc-a8cb71066dca08ca.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/librustc_std_workspace_core-95a7e52c78a3fba1.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libcore-dd6de681850a671c.rlib" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libcompiler_builtins-aa21927f5da4d4a2.rlib" "-framework" "CoreMedia" "-framework" "AVFoundation" "-framework" "Foundation" "-framework" "CoreGraphics" "-framework" "CoreFoundation" "-lSystem" "-framework" "CoreMedia" "-framework" "CoreFoundation" "-lobjc" "-liconv" "-lSystem" "-lresolv" "-lc" "-lm" "-liconv" "-L" "/Users/nikitavbv/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib" "-o" "/Users/nikitavbv/dev/nokhwa-testing/target/debug/deps/nokhwa_testing-ee6d6ca36fb7e9d8" "-Wl,-dead_strip" "-nodefaultlibs"
  = note: Undefined symbols for architecture arm64:
            "_CVPixelBufferLockBaseAddress", referenced from:
                _$LT$nokhwa_bindings_macos..avfoundation..CALLBACK_CLASS$u20$as$u20$core..ops..deref..Deref$GT$::deref::__static_ref_initialize::capture_out_callback::hbcd689a01a46737c in libnokhwa_bindings_macos-4cd999170c2a10bf.rlib(nokhwa_bindings_macos-4cd999170c2a10bf.nokhwa_bindings_macos.51d10249-cgu.1.rcgu.o)
            "_CVPixelBufferGetPixelFormatType", referenced from:
                _$LT$nokhwa_bindings_macos..avfoundation..CALLBACK_CLASS$u20$as$u20$core..ops..deref..Deref$GT$::deref::__static_ref_initialize::capture_out_callback::hbcd689a01a46737c in libnokhwa_bindings_macos-4cd999170c2a10bf.rlib(nokhwa_bindings_macos-4cd999170c2a10bf.nokhwa_bindings_macos.51d10249-cgu.1.rcgu.o)
            "_CVPixelBufferGetBaseAddress", referenced from:
                _$LT$nokhwa_bindings_macos..avfoundation..CALLBACK_CLASS$u20$as$u20$core..ops..deref..Deref$GT$::deref::__static_ref_initialize::capture_out_callback::hbcd689a01a46737c in libnokhwa_bindings_macos-4cd999170c2a10bf.rlib(nokhwa_bindings_macos-4cd999170c2a10bf.nokhwa_bindings_macos.51d10249-cgu.1.rcgu.o)
            "_CVPixelBufferGetDataSize", referenced from:
                _$LT$nokhwa_bindings_macos..avfoundation..CALLBACK_CLASS$u20$as$u20$core..ops..deref..Deref$GT$::deref::__static_ref_initialize::capture_out_callback::hbcd689a01a46737c in libnokhwa_bindings_macos-4cd999170c2a10bf.rlib(nokhwa_bindings_macos-4cd999170c2a10bf.nokhwa_bindings_macos.51d10249-cgu.1.rcgu.o)
            "_CVPixelBufferUnlockBaseAddress", referenced from:
                _$LT$nokhwa_bindings_macos..avfoundation..CALLBACK_CLASS$u20$as$u20$core..ops..deref..Deref$GT$::deref::__static_ref_initialize::capture_out_callback::hbcd689a01a46737c in libnokhwa_bindings_macos-4cd999170c2a10bf.rlib(nokhwa_bindings_macos-4cd999170c2a10bf.nokhwa_bindings_macos.51d10249-cgu.1.rcgu.o)
          ld: symbol(s) not found for architecture arm64
          clang: error: linker command failed with exit code 1 (use -v to see invocation)


error: could not compile `nokhwa-testing` due to previous error

Any ideas on a possible workaround? Thank you!

Example possibly misleading

I wasn't sure, but I think the example might be misleading. In this code:

loop {
    println!(
        "{:?}, {:?}",
        camera.get_frame().unwrap().width(),
        camera.get_frame().unwrap().height()
    );
}

Wouldn't it be getting the width of frame N, and the height of frame N + 1?

So instead it should be:

loop {
    let frame = camera.get_frame().unwrap();
    println!("{}, {}", frame.width(), frame.height());
}

(Also switched to use Display instead of Debug, since I don't think it's necessary here.)

Saving frame fails with .save(), but not with image::save_buffer()?

use nokhwa::*;

fn main() {
    let mut camera = Camera::new(
        0, 
        Some(CameraFormat::new_from(1280, 720, FrameFormat::MJPEG, 30)),
    )
    .unwrap();

    let frame_width = camera.resolution().width_x;
    let frame_height = camera.resolution().height_y;    

    camera.open_stream().unwrap();

    let updated_frame = camera.frame()
        .expect("could not get latest frame");

    // This works
    //image::save_buffer("frame.jpg", &updated_frame, frame_width, frame_height, image::ColorType::Rgb8)
    //    .expect("save_buffer");

    // This fails for some reason
    updated_frame.save("frame.jpg").unwrap();
}

With the latter direct .save() I get this error:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Unsupported(UnsupportedError { format: Exact(Jpeg), kind: Format(Exact(Jpeg)) })', src/main.rs:24:37

I'm not exactly sure why that happens (don't know enough about Rust yet to figure that out)?

Edit: this is on Linux with input-v4l, nokhwa 0.9.4, rust 1.64.0

Can't use controls on windows

All requests to consult camera parameters (controls) are returning an error using input-msmf. I'm still trying to discover what is the problem...

I'm getting:

Err(GUIDSetError("MEDIA_FOUNDATION_FIRST_VIDEO_STREAM", "MF_MEDIASOURCE_SERVICE", "O objeto não oferece suporte ao serviço especificado."))

Probably from here:

pub fn control(&self, control: MediaFoundationControls) -> Result<MFControl, BindingError> {
            let media_source = unsafe {
                let mut receiver: MaybeUninit<IMFMediaSource> = MaybeUninit::uninit();
                let mut ptr_receiver = receiver.as_mut_ptr();
                if let Err(why) = self.source_reader.GetServiceForStream(
                    MEDIA_FOUNDATION_FIRST_VIDEO_STREAM,
                    &MF_MEDIASOURCE_SERVICE,
                    &IMFMediaSource::IID,
                    (&mut ptr_receiver as *mut *mut IMFMediaSource).cast::<*mut std::ffi::c_void>(),
                ) {
                    return Err(BindingError::GUIDSetError(
                        "MEDIA_FOUNDATION_FIRST_VIDEO_STREAM".to_string(),
                        "MF_MEDIASOURCE_SERVICE".to_string(),
                        why.to_string(),
                    ));
                }
                receiver.assume_init()
            };

[Feature request] Support for greyscale captures

Hey, thanks for creating this!
I'm trying to use this for capturing frames from the IR camera on my laptop (using v4l2), which gives 8-bit Greyscale stream.

Nokhwa errors out in get_frame since it expects an rgb888 buffer. Using Opencv doesn't cause an error, but the captured image is still junk.

Would it be possible to handle (preferably automatically) different color formats (rgb24 vs grey8)?

Update image to 0.24.2

Follow up to #43

Update the image crate to the latest version, or note the required crate version in the docs for external dependencies.

Capture example fails on invalid color format

OS: MacOS 12.3.1
Hardware: Apple Macbook Pro (14 inch, 2021), M1 Pro Chip
Rust Version: rustc 1.62.0 (a8314ef7d 2022-06-27)
Nokhwa Commit: 5a8d9c3 (0.9.4)

Example invocation:

cargo run --release --features "input-avfoundation" -- --format YUYV

Output:

thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: GetPropertyError { property: "875704438", error: "Invalid Value" }', src/main.rs:195:88
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a8314ef7d0ec7b75c336af2c9857bfaf43002bfc/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/a8314ef7d0ec7b75c336af2c9857bfaf43002bfc/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /rustc/a8314ef7d0ec7b75c336af2c9857bfaf43002bfc/library/core/src/result.rs:1785:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Thread terminated, closing!

875704438 corresponds to a FourCC of 420v, or CV420YpCbCr8BiPlanarVideoRange

This error comes from this match block:

let fourcc = match fcc_raw {
kCMVideoCodecType_422YpCbCr8 | kCMPixelFormat_422YpCbCr8_yuvs => AVFourCC::YUV2,
kCMVideoCodecType_JPEG | kCMVideoCodecType_JPEG_OpenDML => AVFourCC::MJPEG,
kCMPixelFormat_8IndexedGray_WhiteIsZero => AVFourCC::GRAY8,
_ => {
return Err(AVFError::InvalidValue {
found: fcc_raw.to_string(),
})
}
};

I suppose this is due to the newer facetime camera in the 2021 macbook pros?

If it's just a matter of adding support for an extra color format then I'd be happy to take a crack at it. Let me know if you need any help testing on apple hardware, I have a macbook pro 2014 (intel), macbook pro 2021 (M1 pro), and an M1 mac mini.

cargo build failed

Hi,

I failed to build the cargo. Various errors relating to CameraFormat emerge (see trace below). Appreciate for any advice and enlightenment. Thanks a lot!

....
Compiling nokhwa-core v0.1.0 (/Users/jack/dev/spaces/ruspaces/gitz/gitzlib/camera/nokhwa/nokhwa-core)
warning: unused import: std::borrow::Cow
--> nokhwa-core/src/buffer.rs:26:5
|
26 | use std::borrow::Cow;
| ^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_imports)] on by default

error[E0271]: type mismatch resolving <Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]> as Iterator>::Item == &_
--> nokhwa-core/src/types.rs:48:22
|
48 | .copied()
| ^^^^^^ expected reference, found struct CameraFormat
|
= note: expected reference &_
found struct CameraFormat
note: required by a bound in copied
--> /Users/jack/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:3189:32
|
3189 | Self: Sized + Iterator<Item = &'a T>,
| ^^^^^^^^^^^^ required by this bound in copied

error[E0599]: the method collect exists for struct Copied<Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]>>, but its trait bounds were not satisfied
--> nokhwa-core/src/types.rs:49:22
|
49 | .collect::<Vec>();
| ^^^^^^^ method cannot be called on Copied<Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]>> due to unsatisfied trait bounds
|
::: /Users/jack/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/copied.rs:17:1
|
17 | pub struct Copied {
| -------------------- doesn't satisfy _: Iterator
|
::: /Users/jack/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/filter.rs:15:1
|
15 | pub struct Filter<I, P> {
| ----------------------- doesn't satisfy <_ as Iterator>::Item = &_
|
= note: the following trait bounds were not satisfied:
<Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]> as Iterator>::Item = &_
which is required by Copied<Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]>>: Iterator
Copied<Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]>>: Iterator
which is required by &mut Copied<Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]>>: Iterator

error[E0308]: mismatched types
--> nokhwa-core/src/types.rs:66:68
|
66 | let dist_no_sqrt = (x_diff.abs()).pow(2) + (y_diff.abs()).pow(2) as u32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found u32

error[E0277]: cannot add u32 to i32
--> nokhwa-core/src/types.rs:66:66
|
66 | let dist_no_sqrt = (x_diff.abs()).pow(2) + (y_diff.abs()).pow(2) as u32;
| ^ no implementation for i32 + u32
|
= help: the trait Add<u32> is not implemented for i32
= help: the following other types implement trait Add<Rhs>:
<&'a f32 as Add>
<&'a f64 as Add>
<&'a i128 as Add>
<&'a i16 as Add>
<&'a i32 as Add>
<&'a i64 as Add>
<&'a i8 as Add>
<&'a isize as Add>
and 48 others

error[E0277]: a value of type Vec<(u32, Resolution)> cannot be built from an iterator over elements of type (i32, Resolution)
--> nokhwa-core/src/types.rs:69:22
|
69 | .collect::<Vec<(u32, Resolution)>>();
| ^^^^^^^ value of type Vec<(u32, Resolution)> cannot be built from std::iter::Iterator<Item=(i32, Resolution)>
|
= help: the trait FromIterator<(i32, Resolution)> is not implemented for Vec<(u32, Resolution)>
= help: the trait FromIterator<T> is implemented for Vec<T>
note: required by a bound in collect
--> /Users/jack/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:1788:19
|
1788 | fn collect<B: FromIteratorSelf::Item>(self) -> B
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in collect

error[E0614]: type u32 cannot be dereferenced
--> nokhwa-core/src/types.rs:70:55
|
70 | resolution_map.sort_by(|a, b| a.0.cmp(*b.0));
| ^^^^

error[E0277]: the trait bound CameraFormat: Ord is not satisfied
--> nokhwa-core/src/types.rs:21:11
|
16 | #[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
| --- in this derive macro expansion
...
21 | Exact(CameraFormat),
| ^^^^^^^^^^^^ the trait Ord is not implemented for CameraFormat
|
= note: this error originates in the derive macro Ord (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating CameraFormat with #[derive(Ord)]
|
301| #[derive(Ord)]
|

error[E0277]: the trait bound CameraFormat: Ord is not satisfied
--> nokhwa-core/src/types.rs:22:13
|
16 | #[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
| --- in this derive macro expansion
...
22 | Closest(CameraFormat),
| ^^^^^^^^^^^^ the trait Ord is not implemented for CameraFormat
|
= note: this error originates in the derive macro Ord (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating CameraFormat with #[derive(Ord)]
|
301| #[derive(Ord)]
|

error[E0277]: the trait bound CameraFormat: Eq is not satisfied
--> nokhwa-core/src/types.rs:21:11
|
16 | #[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
| -- in this derive macro expansion
...
21 | Exact(CameraFormat),
| ^^^^^^^^^^^^ the trait Eq is not implemented for CameraFormat
|
note: required by a bound in AssertParamIsEq
--> /Users/jack/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/cmp.rs:317:31
|
317 | pub struct AssertParamIsEq<T: Eq + ?Sized> {
| ^^ required by this bound in AssertParamIsEq
= note: this error originates in the derive macro Eq (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating CameraFormat with #[derive(Eq)]
|
301 | #[derive(Eq)]
|

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

Wrong Platform - Not Selected Error on Example, Windows 10

Hi,

I've ended up copy-pasting the code from the example to make sure it's not something I introduced by mistake.

Same behaviour for 0.6.0 and 0.7.0.

I am not able to figure out what it is, just wondering if it is an access problem, but not finding a way to fix it.

I got logitech UVC webcam, windows 10 Home, Gstreamer and OpenCV installed, not from WSL, admin cmd, made sure python from the same terminal could capture from the webcam with opencv-for-python.

Does it sound like a classic rust - Windows 10 problem you know of or something?

Error when running 0.10 example with AVFoundation

OS: 12.3.1 (21E258)
Machine: MacBook Pro (13-inch, M1, 2020)
rustc: 1.61.0 (fe5b13d68 2022-05-18)

I execute this command:

nokhwa/examples/capture on  senpai via 🦀 v1.61.0
❯ cargo run --features "input-avfoundation"

and it gives 14 errors:

 cargo run --features "input-avfoundation"

   Compiling nokhwa v0.10.0 (/Users/mo/dev/nokhwa)
error[E0412]: cannot find type `Output` in module `crate::pixel_format`
   --> /Users/mo/dev/nokhwa/src/backends/capture/avfoundation.rs:275:50
    |
275 |     ) -> Result<ImageBuffer<crate::pixel_format::Output, Vec<u8>>, NokhwaError> {
    |                                                  ^^^^^^ not found in `crate::pixel_format`
    |
help: consider importing this struct
    |
17  | use std::process::Output;
    |

error[E0425]: cannot find value `cp` in this scope
   --> /Users/mo/dev/nokhwa/src/camera.rs:454:44
    |
454 |                           Ok(cap) => Some(Ok(cp.into())),
    |                                              ^^ help: a local variable with a similar name exists: `cap`
...
549 | / cap_impl_fn! {
550 | |     // (GStreamerCaptureDevice, new, feature = "input-gst", gst),
551 | |     (OpenCvCaptureDevice, new_autopref, feature = "input-opencv", opencv),
552 | |     // (UVCCaptureDevice, create, feature = "input-uvc", uvc),
...   |
555 | |     (AVFoundationCaptureDevice, new, all(feature = "input-avfoundation", any(target_os = "macos", target_os = "ios")), avfoundation)
556 | | }
    | |_- in this macro invocation
    |
    = note: this error originates in the macro `cap_impl_fn` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0412]: cannot find type `MSMF` in this scope
  --> /Users/mo/dev/nokhwa/src/camera_traits.rs:37:5
   |
37 |     MSMF,
   |     ^^^^ not found in this scope
   |
help: there is an enum variant `crate::BackendsEnum::MSMF`; try using the variant's enum
   |
37 |     crate::BackendsEnum,
   |     ~~~~~~~~~~~~~~~~~~~

error[E0412]: cannot find type `AVF` in this scope
  --> /Users/mo/dev/nokhwa/src/camera_traits.rs:38:5
   |
38 |     AVF,
   |     ^^^ not found in this scope
   |
help: there is an enum variant `crate::BackendsEnum::AVF`; try using the variant's enum
   |
38 |     crate::BackendsEnum,
   |     ~~~~~~~~~~~~~~~~~~~

error[E0412]: cannot find type `V4L2` in this scope
  --> /Users/mo/dev/nokhwa/src/camera_traits.rs:39:5
   |
39 |     V4L2,
   |     ^^^^ not found in this scope
   |
help: there is an enum variant `crate::BackendsEnum::V4L2`; try using the variant's enum
   |
39 |     crate::BackendsEnum,
   |     ~~~~~~~~~~~~~~~~~~~

error[E0412]: cannot find type `OCV` in this scope
  --> /Users/mo/dev/nokhwa/src/camera_traits.rs:40:5
   |
40 |     OCV,
   |     ^^^ not found in this scope
   |
help: there is an enum variant `crate::BackendsEnum::OCV`; try using the variant's enum
   |
40 |     crate::BackendsEnum,
   |     ~~~~~~~~~~~~~~~~~~~

error[E0412]: cannot find type `MSMF` in this scope
  --> /Users/mo/dev/nokhwa/src/camera_traits.rs:50:1
   |
50 | #[enum_dispatch(BackendsEnum)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
   |
   = note: this error originates in the attribute macro `enum_dispatch` (in Nightly builds, run with -Z macro-backtrace for more info)
help: there is an enum variant `crate::BackendsEnum::MSMF`; try using the variant's enum
   |
50 | crate::BackendsEnum
   |

error[E0412]: cannot find type `AVF` in this scope
  --> /Users/mo/dev/nokhwa/src/camera_traits.rs:50:1
   |
50 | #[enum_dispatch(BackendsEnum)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
   |
   = note: this error originates in the attribute macro `enum_dispatch` (in Nightly builds, run with -Z macro-backtrace for more info)
help: there is an enum variant `crate::BackendsEnum::AVF`; try using the variant's enum
   |
50 | crate::BackendsEnum
   |

error[E0412]: cannot find type `V4L2` in this scope
  --> /Users/mo/dev/nokhwa/src/camera_traits.rs:50:1
   |
50 | #[enum_dispatch(BackendsEnum)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
   |
   = note: this error originates in the attribute macro `enum_dispatch` (in Nightly builds, run with -Z macro-backtrace for more info)
help: there is an enum variant `crate::BackendsEnum::V4L2`; try using the variant's enum
   |
50 | crate::BackendsEnum
   |

error[E0412]: cannot find type `OCV` in this scope
  --> /Users/mo/dev/nokhwa/src/camera_traits.rs:50:1
   |
50 | #[enum_dispatch(BackendsEnum)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
   |
   = note: this error originates in the attribute macro `enum_dispatch` (in Nightly builds, run with -Z macro-backtrace for more info)
help: there is an enum variant `crate::BackendsEnum::OCV`; try using the variant's enum
   |
50 | crate::BackendsEnum
   |

error[E0412]: cannot find type `ControlValue` in this scope
   --> /Users/mo/dev/nokhwa/src/utils.rs:984:40
    |
984 |     pub fn set_value(&mut self, value: ControlValue) -> Result<(), NokhwaError> {
    |                                        ^^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type `ControlValue` in this scope
   --> /Users/mo/dev/nokhwa/src/utils.rs:994:36
    |
994 |     pub fn with_value(self, value: ControlValue) -> Result<Self, NokhwaError> {
    |                                    ^^^^^^^^^^^^ not found in this scope

error[E0574]: expected struct, variant or union type, found enum `ControlDescription`
   --> /Users/mo/dev/nokhwa/src/utils.rs:997:12
    |
997 |         Ok(ControlDescription {
    |            ^^^^^^^^^^^^^^^^^^ not a struct, variant or union type

warning: unused import: `nokhwa_initialize`
  --> /Users/mo/dev/nokhwa/src/backends/capture/avfoundation.rs:18:33
   |
18 |     mjpeg_to_rgb, nokhwa_check, nokhwa_initialize, yuyv422_to_rgb, CameraControl, CameraFormat,
   |                                 ^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(unused_imports)]` on by default

warning: unused import: `std::process::Output`
  --> /Users/mo/dev/nokhwa/src/backends/capture/avfoundation.rs:27:5
   |
27 | use std::process::Output;
   |     ^^^^^^^^^^^^^^^^^^^^

warning: unused imports: `any::Any`, `ops::Deref`
  --> /Users/mo/dev/nokhwa/src/backends/capture/avfoundation.rs:28:11
   |
28 | use std::{any::Any, borrow::Borrow, borrow::Cow, collections::HashMap, ops::Deref};
   |           ^^^^^^^^                                                     ^^^^^^^^^^

warning: unused import: `pixel_format::PixelFormat`
  --> /Users/mo/dev/nokhwa/src/camera.rs:18:21
   |
18 |     buffer::Buffer, pixel_format::PixelFormat, BackendsEnum, CameraControl, CameraFormat,
   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^

warning: unused import: `frame_formats`
  --> /Users/mo/dev/nokhwa/src/camera_traits.rs:19:5
   |
19 |     frame_formats,
   |     ^^^^^^^^^^^^^

warning: unused imports: `RgbaImage`, `buffer::ConvertBuffer`
  --> /Users/mo/dev/nokhwa/src/camera_traits.rs:26:13
   |
26 | use image::{buffer::ConvertBuffer, ImageBuffer, RgbaImage};
   |             ^^^^^^^^^^^^^^^^^^^^^               ^^^^^^^^^

error[E0204]: the trait `Copy` may not be implemented for this type
   --> /Users/mo/dev/nokhwa/src/utils.rs:941:10
    |
941 | #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
    |          ^^^^
...
945 |     name: String,
    |     ------------ this field does not implement `Copy`
946 |     value: ControlDescription,
    |     ------------------------- this field does not implement `Copy`
947 |     flag: Vec<KnownCameraControlFlag>,
    |     --------------------------------- this field does not implement `Copy`
    |
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)

Some errors have detailed explanations: E0204, E0412, E0425, E0574.
For more information about an error, try `rustc --explain E0204`.
warning: `nokhwa` (lib) generated 6 warnings
error: could not compile `nokhwa` due to 14 previous errors; 6 warnings emitted

I'm new to Rust and after digging for an hour didn't know what I should do. Thanks!

Error during compilation

[INFO]: Checking for the Wasm target...
[INFO]: Compiling to Wasm...
   Compiling wasm-bindgen v0.2.80
   Compiling futures v0.3.21
   Compiling js-sys v0.3.57
   Compiling wasm-rs-async-executor v0.9.0
   Compiling wasm-bindgen-futures v0.4.30
   Compiling web-sys v0.3.57
   Compiling nokhwa v0.10.0 (/var/www/dev.stacktotal.com/www/wasm/nokhwa)
error: it is currently not sound to use lifetimes in function signatures
   --> src/utils.rs:497:34
    |
497 |     pub fn human_name(&self) -> &'_ str {
    |                                  ^^

error: can't #[wasm_bindgen] functions with lifetime or type parameters
   --> src/utils.rs:508:26
    |
508 |     pub fn set_human_name<S: AsRef<str>>(&mut self, human_name: S) {
    |                          ^^^^^^^^^^^^^^^

error: it is currently not sound to use lifetimes in function signatures
   --> src/utils.rs:517:35
    |
517 |     pub fn description(&self) -> &'_ str {
    |                                   ^^

error: can't #[wasm_bindgen] functions with lifetime or type parameters
   --> src/utils.rs:525:27
    |
525 |     pub fn set_description<S: AsRef<str>>(&mut self, description: S) {
    |                           ^^^^^^^^^^^^^^^

error: it is currently not sound to use lifetimes in function signatures
   --> src/utils.rs:534:28
    |
534 |     pub fn misc(&self) -> &'_ str {
    |                            ^^

error: can't #[wasm_bindgen] functions with lifetime or type parameters
   --> src/utils.rs:542:20
    |
542 |     pub fn set_misc<S: AsRef<str>>(&mut self, misc: S) {
    |                    ^^^^^^^^^^^^^^^

error: cannot return a borrowed ref with #[wasm_bindgen]
   --> src/utils.rs:551:28
    |
551 |     pub fn index(&self) -> &CameraIndex {
    |                            ^^^^^^^^^^^^

error[E0667]: `impl Trait` is not allowed in path parameters
   --> src/utils.rs:476:23
    |
476 |         human_name: &(impl AsRef<str> + ?Sized),
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0667]: `impl Trait` is not allowed in path parameters
   --> src/utils.rs:477:24
    |
477 |         description: &(impl AsRef<str> + ?Sized),
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0667]: `impl Trait` is not allowed in path parameters
   --> src/utils.rs:478:17
    |
478 |         misc: &(impl AsRef<str> + ?Sized),
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in path
   --> src/utils.rs:476:23
    |
476 |         human_name: &(impl AsRef<str> + ?Sized),
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in path
   --> src/utils.rs:477:24
    |
477 |         description: &(impl AsRef<str> + ?Sized),
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in path
   --> src/utils.rs:478:17
    |
478 |         misc: &(impl AsRef<str> + ?Sized),
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: the trait bound `impl AsRef<str> + ?Sized: RefFromWasmAbi` is not satisfied
   --> src/utils.rs:468:37
    |
468 | #[cfg_attr(feature = "output-wasm", wasm_bindgen(js_class = JSCameraInfo))]
    |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `RefFromWasmAbi` is not implemented for `impl AsRef<str> + ?Sized`
    |
    = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting this bound
    |
476 |         human_name: &(impl AsRef<str> + ?Sized + wasm_bindgen::convert::RefFromWasmAbi),
    |                                                +++++++++++++++++++++++++++++++++++++++

error[E0277]: the trait bound `utils::CameraIndex: FromWasmAbi` is not satisfied
   --> src/utils.rs:468:37
    |
468 | #[cfg_attr(feature = "output-wasm", wasm_bindgen(js_class = JSCameraInfo))]
    |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromWasmAbi` is not implemented for `utils::CameraIndex`
    |
    = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `Result<u32, NokhwaError>: ReturnWasmAbi` is not satisfied
   --> src/utils.rs:468:37
    |
468 | #[cfg_attr(feature = "output-wasm", wasm_bindgen(js_class = JSCameraInfo))]
    |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ReturnWasmAbi` is not implemented for `Result<u32, NokhwaError>`
    |
    = help: the following implementations were found:
              <Result<T, E> as ReturnWasmAbi>
    = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` (in Nightly builds, run with -Z macro-backtrace for more info)

wasm-pack build --release -- --features "input-jscam, output-wasm, test-fail-warning" --no-default-features

Example in README is doesn't work

Hi!
The presented example (in README) doesn't contain an up-to-date version of the code.
In current time struct of Camera doesn't have the get_frame() function.

Thanks for great library (:

unresolved import `windows::Win32::Foundation::PWSTR`

   Compiling nokhwa-bindings-windows v0.3.4 (https://github.com/l1npengtul/nokhwa?branch=senpai#41abb00f)
error[E0432]: unresolved import `windows::Win32::Foundation::PWSTR`
   --> C:\Users\avlin\.cargo\git\checkouts\nokhwa-66b597f0abb1b795\41abb00\nokhwa-bindings-windows\src\lib.rs:382:13
    |
382 |             Foundation::PWSTR,
    |             ^^^^^^^^^^^^^^^^^ no `PWSTR` in `Windows::Win32::Foundation`
error: could not compile `nokhwa-bindings-windows` due to previous error

is there a plan to provide a python lib of nokhwa

hello, i want to use nokhwa to capture images from usb camera on windows, as the opencv didn't support MSMF backends well
i found this lib based on nokhwa provided a python lib, yet it did not support control settings until now.
i wonder is it possible to use nokhwa in python in the future?
i think it will be more popular than the opencv-python or pycamera, which can not compare nokhwa on options abundance and stability

UnsupportedOperatorError on query_devices

Hello, I am having an UnsupportedOperatorError when I call query_device. The error has no internal message. I tried with the Auto backend and then on several other backends but I ended up having the same error everytime.

match nokhwa::query_devices(nokhwa::CaptureAPIBackend::Auto) {
    Ok(cameras) => {
        // Never gets here
    },
    Err(err) => {
        // Always an error
    }
}

image

  • Version used: nokhwa 0.9.4
  • OS: Windows 11 x64
  • Dell XPS 15" from 2020

Any idea of what could go wrong?

how to close or release a camera

hello, i have 2 camera on my win10, i found they can not open at the same time, it will block infinitely, is there a way to release a camera like in opencv cap.release(), how to switch the camera in nokhwa

Not able to access camera controls

The docs show a struct called CameraControls, which contains a lot of useful functionality. Particularly, I'm interested in setting the exposure of a camera.

The problem is that I can't figure out how to access a camera's controls. Is it possible somehow?

Platform requirements not satisfied. (No Selection)

I'm trying to use this library on NixOS, but I'm hitting the following error:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: NotImplementedError("Platform requirements not satisfied. (No Selection)")', src/main.rs:9:10
stack backtrace:
   0: rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::result::unwrap_failed
   3: core::result::Result<T,E>::unwrap
             at /build/rustc-1.62.1-src/library/core/src/result.rs:1078:23
   4: nannou_webcam::main
             at ./src/main.rs:5:22
   5: core::ops::function::FnOnce::call_once
             at /build/rustc-1.62.1-src/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace

I guess it's missing a dynamic library? My Cargo.toml looks like this:

[package]
name = "example"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
nokhwa = { git = "https://github.com/l1npengtul/nokhwa", rev = "0.9.4" }

And my flake.nix looks like this:

{
  description = "A very basic flake";

  inputs.nixpkgs.url = github:NixOS/nixpkgs;

  outputs = { self, nixpkgs }:
  let
    system = "x86_64-linux";
    pkgs = import nixpkgs { inherit system; };
    lib = pkgs.lib;
    buildInputs = with pkgs; [
      clippy
      rustc
      cargo
      cargo-watch
      rustfmt
      rust-analyzer

      # for nannou
      xorg.libX11
      xorg.libXcursor
      xorg.libXrandr
      xorg.libXi
      vulkan-tools vulkan-headers vulkan-loader vulkan-validation-layers
      # wayland
      # xwayland
    ];
  in {
    devShell.${system} = pkgs.mkShell {
      inherit buildInputs;
      RUST_BACKTRACE = 1;
    };
  };
}

Any help would be greatly appreciated. Thanks!

Consider using Fn* traits rather than function pointers

Various callbacks in this crate are defined with fn pointers, e.g.:

pub fn nokhwa_initialize(on_complete: fn(_: bool));

This prevents passing a closure that captures anything, so makes simple patterns much more complicated. For example, you can't do this to wait for AVFoundation init to complete before proceeding at the start of an async program:

let (init_tx, init_rx) = tokio::sync::oneshot::channel();
nokhwa_initialize(|success| init_tx.send(success).unwrap());
if !init_rx.await? {
  panic!("camera init failed");
}
error[E0308]: mismatched types
  --> tests/tests.rs:24:21
   |
24 |   nokhwa_initialize(|success| init_tx.send(success).unwrap());
   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found closure
   |
   = note: expected fn pointer `fn(bool)`
                 found closure `[closure@tests/tests.rs:24:21: 24:61]`
note: closures can only be coerced to `fn` types if they do not capture any variables
  --> tests/tests.rs:24:31
   |
24 |   nokhwa_initialize(|success| init_tx.send(success).unwrap());
   |                               ^^^^^^^ `init_tx` captured here

Similarly, ThreadedCamera's callback is not very usable because you can't capture anything into it in order to e.g. send the frames out on a channel or store them into a data structure.

Consider using Fn/FnOnce/FnMut traits as appropriate in each situation rather than using fn pointers, to make the API more generally useful.

Poor performance with v4l backend

I'm trying to port a library I wrote from my custom V4L2 bindings (https://github.com/SludgePhD/LinuxVideo) to nokhwa and am seeing reduced performance:

[2022-05-01T12:53:43Z DEBUG zaru::webcam] trying #3 'Logitech BRIO' (Video4Linux Device @ /dev/video3)
[2022-05-01T12:53:43Z INFO  zaru::webcam] started stream at 1280x720@90Hz
[2022-05-01T12:53:44Z DEBUG zaru::timer] webcam: 3 FPS (dequeue: 3x333.5ms, decode: 3x6.8ms)
[2022-05-01T12:53:45Z DEBUG zaru::timer] webcam: 29 FPS (dequeue: 29x25.3ms, decode: 29x9.8ms)
[2022-05-01T12:53:46Z DEBUG zaru::timer] webcam: 29 FPS (dequeue: 29x25.1ms, decode: 29x9.8ms)
[2022-05-01T12:53:47Z DEBUG zaru::timer] webcam: 29 FPS (dequeue: 29x22.9ms, decode: 29x11.7ms)
[2022-05-01T12:53:48Z DEBUG zaru::timer] webcam: 29 FPS (dequeue: 29x28.3ms, decode: 29x6.6ms)
[2022-05-01T12:53:49Z DEBUG zaru::timer] webcam: 29 FPS (dequeue: 29x28.5ms, decode: 29x6.6ms)
[2022-05-01T12:53:50Z DEBUG zaru::timer] webcam: 29 FPS (dequeue: 29x28.1ms, decode: 29x6.8ms)

dequeue is the average time taken by camera.frame_raw(), decode is the time mozjpeg needs to decode the JPEG frame (which I do by hand, hence frame_raw()). The result of this is correct, and the decode times remained about the same, but the performance of dequeue is a lot worse than before (and much lower than what the webcam can deliver or what was requested).

For comparison, with LinuxVideo I have no problems running at 86 FPS, which I think is as fast as the webcam outputs frames when requesting 90 Hz. Note that LinuxVideo sidesteps libv4l and directly calls the device ioctls. The dequeue time is essentially completely spent blocking on the device read.

It could be that libv4l does some expensive conversion, or that something with setting the frame rate is going wrong (though camera.frame_rate() does correctly return 90).

This is with nokhwa 0.9.4, not latest git, but I don't see much that could affect performance (EDIT: now tested with git, same behavior).

(side note, I have tried the gstreamer backend instead of input-v4l, but it fails with a nondescript UnsupportedOperationError(Auto))

Can't find attribute MF_MT_FRAME_RATE_RANGE_MAX on Windows Media Foundation

I have some code that works great with my external webcam. However, my internal laptop webcam panics when nokhwa attempts to obtain the MF_MT_FRAME_RATE_RANGE_MAX attribute from wmf. The exact code where the issue originates is below in the screenshot.

image

image

I don't know what you need to know from this. I'm happy to help support by contributing code fixes myself... but I've never really interfaced with unsafe code or really anything like this.

Again, when I plug in my usb external webcam and target that device id, nokhwa grabs it just fine and can stream frames. I've double-checked that Windows Media Player is already installed as a OS feature. Help!

cargo build failed

Hi,

I failed to build the cargo on ny MacBook (Monetary). See trace below. Appreciate any advice. Thanks a lot.

Compiling nokhwa-core v0.1.0 (/Users/jack/dev/spaces/ruspaces/gitz/gitzlib/camera/nokhwa/nokhwa-core)
Compiling spin v0.9.4
warning: unused import: std::borrow::Cow
--> nokhwa-core/src/buffer.rs:26:5
|
26 | use std::borrow::Cow;
| ^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_imports)] on by default

Compiling flume v0.10.14
error[E0271]: type mismatch resolving <Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]> as Iterator>::Item == &_
--> nokhwa-core/src/types.rs:48:22
|
48 | .copied()
| ^^^^^^ expected reference, found struct CameraFormat
|
= note: expected reference &_
found struct CameraFormat
note: required by a bound in copied
--> /Users/jack/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:3189:32
|
3189 | Self: Sized + Iterator<Item = &'a T>,
| ^^^^^^^^^^^^ required by this bound in copied

error[E0599]: the method collect exists for struct Copied<Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]>>, but its trait bounds were not satisfied
--> nokhwa-core/src/types.rs:49:22
|
49 | .collect::<Vec>();
| ^^^^^^^ method cannot be called on Copied<Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]>> due to unsatisfied trait bounds
|
::: /Users/jack/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/copied.rs:17:1
|
17 | pub struct Copied {
| -------------------- doesn't satisfy _: Iterator
|
::: /Users/jack/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/filter.rs:15:1
|
15 | pub struct Filter<I, P> {
| ----------------------- doesn't satisfy <_ as Iterator>::Item = &_
|
= note: the following trait bounds were not satisfied:
<Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]> as Iterator>::Item = &_
which is required by Copied<Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]>>: Iterator
Copied<Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]>>: Iterator
which is required by &mut Copied<Filter<std::vec::IntoIter<CameraFormat>, [closure@nokhwa-core/src/types.rs:47:29: 47:78]>>: Iterator

error[E0308]: mismatched types
--> nokhwa-core/src/types.rs:66:68
|
66 | let dist_no_sqrt = (x_diff.abs()).pow(2) + (y_diff.abs()).pow(2) as u32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found u32

error[E0277]: cannot add u32 to i32
--> nokhwa-core/src/types.rs:66:66
|
66 | let dist_no_sqrt = (x_diff.abs()).pow(2) + (y_diff.abs()).pow(2) as u32;
| ^ no implementation for i32 + u32
|
= help: the trait Add<u32> is not implemented for i32
= help: the following other types implement trait Add<Rhs>:
<&'a f32 as Add>
<&'a f64 as Add>
<&'a i128 as Add>
<&'a i16 as Add>
<&'a i32 as Add>
<&'a i64 as Add>
<&'a i8 as Add>
<&'a isize as Add>
and 48 others

error[E0277]: a value of type Vec<(u32, Resolution)> cannot be built from an iterator over elements of type (i32, Resolution)
--> nokhwa-core/src/types.rs:69:22
|
69 | .collect::<Vec<(u32, Resolution)>>();
| ^^^^^^^ value of type Vec<(u32, Resolution)> cannot be built from std::iter::Iterator<Item=(i32, Resolution)>
|
= help: the trait FromIterator<(i32, Resolution)> is not implemented for Vec<(u32, Resolution)>
= help: the trait FromIterator<T> is implemented for Vec<T>
note: required by a bound in collect
--> /Users/jack/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:1788:19
|
1788 | fn collect<B: FromIteratorSelf::Item>(self) -> B
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in collect

error[E0614]: type u32 cannot be dereferenced
--> nokhwa-core/src/types.rs:70:55
|
70 | resolution_map.sort_by(|a, b| a.0.cmp(*b.0));
| ^^^^

error[E0277]: the trait bound CameraFormat: Ord is not satisfied
--> nokhwa-core/src/types.rs:21:11
|
16 | #[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
| --- in this derive macro expansion
...
21 | Exact(CameraFormat),
| ^^^^^^^^^^^^ the trait Ord is not implemented for CameraFormat
|
= note: this error originates in the derive macro Ord (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating CameraFormat with #[derive(Ord)]
|
301| #[derive(Ord)]
|

error[E0277]: the trait bound CameraFormat: Ord is not satisfied
--> nokhwa-core/src/types.rs:22:13
|
16 | #[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
| --- in this derive macro expansion
...
22 | Closest(CameraFormat),
| ^^^^^^^^^^^^ the trait Ord is not implemented for CameraFormat
|
= note: this error originates in the derive macro Ord (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating CameraFormat with #[derive(Ord)]
|
301| #[derive(Ord)]
|

error[E0277]: the trait bound CameraFormat: Eq is not satisfied
--> nokhwa-core/src/types.rs:21:11
|
16 | #[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
| -- in this derive macro expansion
...
21 | Exact(CameraFormat),
| ^^^^^^^^^^^^ the trait Eq is not implemented for CameraFormat
|
note: required by a bound in AssertParamIsEq
--> /Users/jack/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/cmp.rs:317:31
|
317 | pub struct AssertParamIsEq<T: Eq + ?Sized> {
| ^^ required by this bound in AssertParamIsEq
= note: this error originates in the derive macro Eq (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating CameraFormat with #[derive(Eq)]
|
301 | #[derive(Eq)]
|

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

Can't set camera format, read format is wrong

Hi I'm not sure how to make this actionable as I suspect it is a combination issue between the camera on my machine (Surface Laptop, win 10) and the software, here is what I can tell you:

Using Camera::new(0, None), I get

CameraFormat w:640 h:480 fmt:MJPEG,
CameraInfo: human_name Microsoft Camera Front desc MediaFoundation Camera Device misc \\?\display#int3470#4&1835d135&0&uid13424#{e5323777-f976-4f5b-9b55-b94699c46e44}\{bf89b5a5-61f7-4127-a279-e187013d7caf} index 0

However, Camera.frame_raw() is about 3MB consistently the same size and so not an MJPEG which is confirmed in that
Camera.frame() crashes with
thread 'test::test_camera' panicked at 'libjpeg fatal error: Not a JPEG file: starts with 0x94 0x94', C:\Users\james\.cargo\registry\src\github.com-1ecc6299db9ec823\mozjpeg-0.8.24\src\errormgr.rs:39:5

The combination of these issues means I can't get frames in a knowable in advance format, and I don't know how to determine what the format is it give me if it isn't what it tells me when do Camera.camera_format(). Given I get this on the first camera I test i.e. my local machine, and I need this to work for any camera, I'm concluding the library is not usable. Or am I making some stupid mistake?

Do let me know if I can help with any further info.

Camera::frame_texture returns wgpu::TextureHandle instead of wgpu::Texture

I'm trying to use nokhwa in combination with nannou and I need to get a frame as a wgpu::Texture. As far I can see in the documentation, Camera::frame_capture returns a WgpuTexture which is an alias of wgpu::Texture.

In theory that would be alright. But when I call frame_capture, the compiler throws me the following error.

mismatched types
expected struct `nannou::wgpu::Texture`, found struct `TextureHandle`

As if the function is really returning a wgpu::TextureHandle object instead.

I'm using:

  • macOS 11.4 Big Sur
  • nannou v0.17.1
  • nokhwa v0.3.2
    • Features: input-gst, output-wgpu

Access Violation Error on Windows 10

I'm having this issue with the latest stable release (0.7.0) on Windows 10.

Here is my dependency in Cargo.toml:

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

Here is the error I'm getting when running the example code:

C:\msmf-test>cargo run
   Compiling msmf-test v0.0.1 (C:\msmf-test)
    Finished dev [unoptimized + debuginfo] target(s) in 1.14s
     Running `target\debug\msmf-test.exe`
error: process didn't exit successfully: `target\debug\msmf-test.exe` (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)

I have tried running the application as admin and allowed app access to my webcam through control panel.

Example crashes on MacOS

Hi! I tried to run the example on my MacBook, but encountered following error:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: CouldntOpenDevice("Device at 0 not found")', src/main.rs:10:6
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

How to enumerate compatible formats of a camera index

Hello! I have a webcam of unknown parameters and I'd like to have a list of its supported formats and resolutions. How can you achieve that with the crate? I see there's compatible_camera_formats, but to call it you need a Camera already constructed. I can't construct it because I don't know the format I need to provide. What should I do? (BTW: I'm only using the v4l backend)

Control Revamp

CameraControl revamp in order to support more controls

missing linkage to CoreVideo framework

in Cargo.toml:

nokhwa = {
  version = "0.9", optional = true, default-features = false, features = [
    "decoding", "flume", "input-v4l", "input-msmf", "input-avfoundation", "output-threaded"
  ]
}

when running cargo build:

  = note: Undefined symbols for architecture arm64:
            "_CVPixelBufferLockBaseAddress", referenced from:
                _$LT$nokhwa_bindings_macos..avfoundation..CALLBACK_CLASS$u20$as$u20$core..ops..deref..Deref$GT$::deref::__static_ref_initialize::capture_out_callback::h96ec85fdab100000 in libnokhwa_bindings_macos-0e9400fda68c51e0.rlib(nokhwa_bindings_macos-0e9400fda68c51e0.nokhwa_bindings_macos.0da1d717-cgu.1.rcgu.o)
            "_CVPixelBufferGetPixelFormatType", referenced from:
                _$LT$nokhwa_bindings_macos..avfoundation..CALLBACK_CLASS$u20$as$u20$core..ops..deref..Deref$GT$::deref::__static_ref_initialize::capture_out_callback::h96ec85fdab100000 in libnokhwa_bindings_macos-0e9400fda68c51e0.rlib(nokhwa_bindings_macos-0e9400fda68c51e0.nokhwa_bindings_macos.0da1d717-cgu.1.rcgu.o)
            "_CVPixelBufferGetBaseAddress", referenced from:
                _$LT$nokhwa_bindings_macos..avfoundation..CALLBACK_CLASS$u20$as$u20$core..ops..deref..Deref$GT$::deref::__static_ref_initialize::capture_out_callback::h96ec85fdab100000 in libnokhwa_bindings_macos-0e9400fda68c51e0.rlib(nokhwa_bindings_macos-0e9400fda68c51e0.nokhwa_bindings_macos.0da1d717-cgu.1.rcgu.o)
            "_CVPixelBufferGetDataSize", referenced from:
                _$LT$nokhwa_bindings_macos..avfoundation..CALLBACK_CLASS$u20$as$u20$core..ops..deref..Deref$GT$::deref::__static_ref_initialize::capture_out_callback::h96ec85fdab100000 in libnokhwa_bindings_macos-0e9400fda68c51e0.rlib(nokhwa_bindings_macos-0e9400fda68c51e0.nokhwa_bindings_macos.0da1d717-cgu.1.rcgu.o)
            "_CVPixelBufferUnlockBaseAddress", referenced from:
                _$LT$nokhwa_bindings_macos..avfoundation..CALLBACK_CLASS$u20$as$u20$core..ops..deref..Deref$GT$::deref::__static_ref_initialize::capture_out_callback::h96ec85fdab100000 in libnokhwa_bindings_macos-0e9400fda68c51e0.rlib(nokhwa_bindings_macos-0e9400fda68c51e0.nokhwa_bindings_macos.0da1d717-cgu.1.rcgu.o)
          ld: symbol(s) not found for architecture arm64
          clang-11: error: linker command failed with exit code 1 (use -v to see invocation)

I think the fix would just be to add to nokhwa-bindings-macos/build.rs:

println!("cargo:rustc-link-lib=framework=CoreVideo");

Get error Frame Cow Too Small from frame_to_buffer

Try to get RGBA image from camera, but get error:
thread 'main' panicked at 'called Result::unwrap() on an Err value: ReadFrameError("Frame Cow Too Small")'

let mut camera = nokhwa::Camera::new(
        0, // index
        Some(nokhwa::CameraFormat::new_from(640, 480, nokhwa::FrameFormat::MJPEG, 30)), // format
    )
    .unwrap();

camera.open_stream().unwrap();

let mut buffer2: Vec<u8> = vec![0; camera.min_buffer_size(true)];

camera.frame_to_buffer(&mut buffer2, true).unwrap();

As I understand, I should receive 6404804 bytes. But when I increase the size of a vector, I get this error as well.

Camera frame freezes on input-gst

tldr

Running the example

with input-gst feature, the thread does not reach the line after let frame = camera.frame().unwrap();.

expected behaviour

The frame() function should return an error.

my debug output

Debugging gstreamer using GST_DEBUG=3 environment:

pi@raspberrypi:~/rusty_pi_cam $ GST_DEBUG=3 cargo run
0:00:00.002334331  2125  0x1473680 WARN         GST_PERFORMANCE gstbuffer.c:496:_priv_gst_buffer_initialize: No 64-bit atomic int defined for this platform/toolchain!
[0:17:39.631913261] [2125]  INFO Camera camera_manager.cpp:293 libcamera v0.0.0+3406-e96d0201
[0:17:39.651998905] [2140] ERROR CameraSensor camera_sensor.cpp:551 'ov5647 10-0036': Camera sensor does not support test pattern modes.
[0:17:39.689511536] [2140]  INFO RPI raspberrypi.cpp:1326 Registered camera /base/soc/i2c0mux/i2c@1/ov5647@36 to Unicam device /dev/media3 and ISP device /dev/media0
0:00:00.179102088  2125  0x1473680 WARN                 default gstlibcamera-utils.cpp:99:gst_libcamera_stream_formats_to_caps: Unsupported DRM format XB24
0:00:00.179439068  2125  0x1473680 WARN                 default gstlibcamera-utils.cpp:99:gst_libcamera_stream_formats_to_caps: Unsupported DRM format XR24
0:00:00.179481776  2125  0x1473680 WARN                 default gstlibcamera-utils.cpp:99:gst_libcamera_stream_formats_to_caps: Unsupported DRM format RG16
0:00:00.225580323  2125  0x1473680 WARN                 v4l2src gstv4l2src.c:694:gst_v4l2src_query:<v4l2src0> Can't give latency since framerate isn't fixated !
0:00:00.225886522  2125  0x1473680 WARN                 v4l2src gstv4l2src.c:694:gst_v4l2src_query:<v4l2src0> Can't give latency since framerate isn't fixated !
()
tik
0:00:00.226465743  2125  0x1628a70 WARN                 basesrc gstbasesrc.c:3127:gst_base_src_loop:<v4l2src0> error: Internal data stream error.
0:00:00.226511993  2125  0x1628a70 WARN                 basesrc gstbasesrc.c:3127:gst_base_src_loop:<v4l2src0> error: streaming stopped, reason not-negotiated (-4)

my setup

#Cargo.toml
[dependencies]
image = { version = "0.23.14", default-features = false, features = [
    "png",
    "jpeg",
] }
nokhwa = { version = "0.9.4", features = ["input-gst"] }
// main.rs
use nokhwa::Camera;
use nokhwa::CameraFormat;
use nokhwa::FrameFormat;

fn main() {
    let mut camera = Camera::new(
        0,                                                                // index
        Some(CameraFormat::new_from(1920, 1080, FrameFormat::MJPEG, 30)), // format
    )
    .unwrap();
    let res = camera.open_stream().unwrap();
    println!("{:?}", res);
    loop {
        let frame = camera.frame().unwrap();
        println!("{}, {}", frame.width(), frame.height());
        frame.save("frame.jpg").unwrap();
    }
}
# Raspi OS Bullseye
pi@raspberrypi:~/rusty_pi_cam $ uname -a
Linux raspberrypi 5.10.92-v7+ #1514 SMP Mon Jan 17 17:36:39 GMT 2022 armv7l GNU/Linux
pi@raspberrypi:~/rusty_pi_cam $ libcamera-hello --list-cameras
[0:22:46.343048546] [2411]  INFO Camera camera_manager.cpp:293 libcamera v0.0.0+3406-e96d0201
[0:22:46.373515405] [2412] ERROR CameraSensor camera_sensor.cpp:551 'ov5647 10-0036': Camera sensor does not support test pattern modes.
[0:22:46.424995085] [2412]  INFO RPI raspberrypi.cpp:1326 Registered camera /base/soc/i2c0mux/i2c@1/ov5647@36 to Unicam device /dev/media3 and ISP device /dev/media0
Available cameras
-----------------
0 : ov5647 [2592x1944] (/base/soc/i2c0mux/i2c@1/ov5647@36)
    Modes: 'SGBRG10_CSI2P' : 640x480 1296x972 1920x1080 2592x1944 
           'SGBRG8' : 640x480

Thanks for this project!

Could not compile `nokhwa-bindings-windows`

I'm having this issue on both the latest stable and nightly branch.

Here's my dependencies section of my Cargo.toml:
nokhwa = { version = "0.4.3", features = ["input-msmf", "decoding", "output-wgpu"] }

And here's the error in more detail:

error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
   --> C:\Users\pizzajess\.cargo\registry\src\github.com-1ecc6299db9ec823\nokhwa-bindings-windows-0.2.4\src\lib.rs:372:47
    |
372 |     static mut INITIALIZED: Arc<AtomicBool> = Arc::new(AtomicBool::new(false));
    |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0015`.
error: could not compile `nokhwa-bindings-windows` due to previous error

Relicense to MIT/APL-2.0

I currently want to change the license to MIT/APL2 for integration with nannou. For this I require your signatures.
Sorry for the ping.

Reply with "I agree" or something similar to indicate that you are okay with this change.

How to use nokhwa together with iced

Hi there 👋

I'm trying to use nokhwa (built from this main branch) to show my webcam video in an iced application. I am pretty new to this ecosystem, so sorry if this is a dumb question, but how do I use the camera output with the image widget of iced.

My application looks like this:

use iced::widget::{column, image, text};
use iced::{executor, Subscription};
use iced::{Alignment, Application, Command, Element, Settings, Theme};
use nokhwa::pixel_format::RgbFormat;
use nokhwa::utils::{ApiBackend, CameraInfo, RequestedFormat, RequestedFormatType};
use nokhwa::{query, Camera};

// TODO: set these via environment variables
const CAMERA_QUERY_INTERVAL: u64 = 2000;

pub fn main() -> iced::Result {
    MediaHub::run(Settings::default())
}

struct MediaHub {
    cameras: Box<Vec<CameraInfo>>,
}

#[derive(Debug, Clone)]
enum Message {
    CamerasListed(Box<Vec<CameraInfo>>),
}

fn query_all_cameras() -> Box<Vec<CameraInfo>> {
    Box::new(query(ApiBackend::Auto).unwrap())
}

impl Application for MediaHub {
    type Message = Message;
    type Executor = executor::Default;
    type Flags = ();
    type Theme = Theme;

    fn new(_flags: ()) -> (Self, Command<Self::Message>) {
        (
            Self {
                cameras: query_all_cameras(),
            },
            Command::none(),
        )
    }

    fn update(&mut self, message: Message) -> Command<Self::Message> {
        match message {
            Message::CamerasListed(new_cams) => self.cameras = new_cams,
        }
        Command::none()
    }

    fn subscription(&self) -> Subscription<Message> {
        iced::time::every(std::time::Duration::from_millis(CAMERA_QUERY_INTERVAL))
            .map(|_| Message::CamerasListed(query_all_cameras()))
    }

    fn title(&self) -> String {
        String::from("MediaHub - Iced")
    }

    fn view(&self) -> Element<Message> {
        if self.cameras.len() > 0 {
            let camera_info = self
                .cameras
                .iter()
                .map(|cam| cam.human_name())
                .collect::<Vec<String>>()
                .join(", ");

            let requested = RequestedFormat::new(RequestedFormatType::AbsoluteHighestFrameRate);

            let cam = Camera::new(nokhwa::utils::CameraIndex::Index(0), requested).unwrap();
            let frame = cam.frame().unwrap().decode_image().unwrap();

            let img = image::Handle::from_pixels(frame.width(), frame.height(), frame); // the last argument is wrong, it throws an error

            column![text(camera_info).size(50), image::viewer(img)]
                .padding(20)
                .align_items(Alignment::Center)
                .into()
        } else {
            column![text("No camera found").size(50)]
                .padding(20)
                .align_items(Alignment::Center)
                .into()
        }
    }
}

I can contribute an example for this integration if you like :)

GetPropertyError when opening some cameras on Windows (MSMF backend)

I get this error when attempting to open some cameras using the MSMF backend and I can't quite figure out what's going on.

Minimal code here:

[package]
name = "camdebug"
version = "1.0.0"
edition = "2021"

[dependencies]
nokhwa = { version = "0.9", features = ["input-msmf"] }
use nokhwa::*;

fn main() {
    let cameras = query().expect("can query cameras");
    println!("cameras: {:#?}", cameras);
    let camera = Camera::new(0, None);
    if let Err(e) = camera {
        eprintln!("camera open error: {:?}", e);
    }
}

This outputs the following:

    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
     Running `target\debug\camdebug.exe`
cameras: [
    CameraInfo {
        human_name: "Iriun Webcam",
        description: "Media Foundation Device",
        misc: "\\\\?\\root#camera#0000#{e5323777-f976-4f5b-9b55-b94699c46e44}\\{2a1f7d28-c666-4848-a04c-3b1a9f2546a2}",
        index: 0,
    },
    CameraInfo {
        human_name: "Integrated Webcam",
        description: "Media Foundation Device",
        misc: "\\\\?\\usb#vid_0c45&pid_672e&mi_00#6&18c3862&0&0000#{e5323777-f976-4f5b-9b55-b94699c46e44}\\global",
        index: 1,
    },
]
camera open error: GetPropertyError { property: "Devices", error: "Not Found" }

Any ideas what is going on and/or how to solve it? Thanks!

Callback/Async/Iterator based capture

  • Figure out the best way to do this
  • Wrap for backends that natively supporrt this
  • Make a threaded(perhaps using may) or some other solution for frameworks that don't
  • Gate behind a feature

Read order error in yuyv422_to_rgb888

Was experimenting with capturing in FrameFormat::YUYV and the picture I got was green and pink.
The conversion function yuyv422_to_rgb888 seems to read the color components in the wrong order.
It currently reads it as UYVY which mixes up the Chroma and Luma planes.

Here is a patch that solves it, with it my captured picture has the expected colors.

index 061bed8..c10c58e 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -340,7 +340,7 @@ pub fn yuyv422_to_rgb888(data: &[u8]) -> Result<Vec<u8>, NokhwaError> {
     let mut rgb_vec: Vec<u8> = vec![];
     if data.len() % 4 == 0 {
         for px_idx in (0..data.len()).step_by(4) {
-            let u = match data.get(px_idx) {
+            let y1 = match data.get(px_idx) {
                 Some(px) => match i32::try_from(*px) {
                     Ok(i) => i,
                     Err(why) => {
@@ -359,7 +359,7 @@ pub fn yuyv422_to_rgb888(data: &[u8]) -> Result<Vec<u8>, NokhwaError> {
                 }
             };
 
-            let y1 = match data.get(px_idx + 1) {
+            let u = match data.get(px_idx + 1) {
                 Some(px) => match i32::try_from(*px) {
                     Ok(i) => i,
                     Err(why) => {
@@ -378,7 +378,7 @@ pub fn yuyv422_to_rgb888(data: &[u8]) -> Result<Vec<u8>, NokhwaError> {
                 }
             };
 
-            let v = match data.get(px_idx + 2) {
+            let y2 = match data.get(px_idx + 2) {
                 Some(px) => match i32::try_from(*px) {
                     Ok(i) => i,
                     Err(why) => {
@@ -397,7 +397,7 @@ pub fn yuyv422_to_rgb888(data: &[u8]) -> Result<Vec<u8>, NokhwaError> {
                 }
             };
 
-            let y2 = match data.get(px_idx + 3) {
+            let v = match data.get(px_idx + 3) {
                 Some(px) => match i32::try_from(*px) {
                     Ok(i) => i,
                     Err(why) => {

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.