Giter Club home page Giter Club logo

libuvc-rs's People

Contributors

fpalvolgyi avatar kjetijor avatar l1npengtul avatar mulimoen avatar palladinium avatar raymanfx 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

libuvc-rs's Issues

Maintenence

Hello, I am willing to take over maintaining this crate.

cargo build failed

Hi,

I tried to build from my Monterey MacBook. The cargo build failed with the following trace. Appreciate for any suggestions. Thanks a lot!

Compiling uvc v0.2.0 (/Users/jack/dev/spaces/ruspaces/gitz/gitzlib/camera/libuvc)
error[E0425]: cannot find function uvc_mjpeg2rgb in this scope
--> src/frame.rs:39:39
|
39 | FrameFormat::MJPEG => uvc_mjpeg2rgb(self.frame.as_ptr(), new_frame.frame.as_ptr()),
| ^^^^^^^^^^^^^ not found in this scope

For more information about this error, try rustc --explain E0425.
error: could not compile uvc due to previous error

Segfault when attempting to start stream

When attempting to start a stream (I am trying to stream video from a Logitech C920), the program segfaults.

Code:

let ctx = uvc::Context::new().unwrap();
let dev = ctx.find_device(None, None, None).unwrap();

let handle = dev.open().unwrap();

let format = uvc::StreamFormat {
    width: WIDTH,
    height: HEIGHT,
    fps: FPS,
    format: FrameFormat::MJPEG
};

let mut stream_handle = handle.get_stream_handle_with_format(format).unwrap();

let (mjpeg_sender, mut mjpeg_receiver) = watch::channel(Vec::new());

let _stream = stream_handle.start_stream(
    |frame, sender| {
        let frame_vec = frame.to_bytes().to_vec();
        // not sure if safe to panic
        let _ = sender.broadcast(frame_vec);
    },
    mjpeg_sender,
).unwrap();

// use channel at this point

When running it, I get:

unsupported descriptor subtype VS_COLORFORMAT
unsupported descriptor subtype VS_COLORFORMAT
attempt to claim already-claimed interface 1

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

Some other program is must be using my camera for some reason, which probably should be causing either a panic or causing a function to return an error, but should probably not be causing a segfault from safe Rust.

If you'd like, I can try and debug this from my machine, and I can try and potentially pull request a fix in.

Building libuvc-rs on aarch64 fails with "error[E0425]: cannot find function `uvc_mjpeg2rgb` in this scope"

Hi, I am currently building libuvc-rs on an aarch64 architecture. I think my build fails since it cant find libjpeg on my system.
If I run cmake to compile a test app I can see what the current path of libjpeg is:
JPEG_INCLUDE_DIR: /usr/include | JPEG_LIBRARIES: /usr/lib/aarch64-linux-gnu/libjpeg.so

Any idea how I can let cargo know of the exact libjpeg path?

And here is a detailed cargo build output:
Compiling uvc v0.2.0 Running CARGO=/home/root/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/bin/cargo CARGO_CRATE_NAME=uvc CARGO_MANIFEST_DIR=/home/root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/uvc-0.2.0 CARGO_PKG_AUTHORS='Magnus Ulimoen <[email protected]>' CARGO_PKG_DESCRIPTION='Safe and ergonomic wrapper around libuvc, allowing capture of webcam streams' CARGO_PKG_HOMEPAGE='' CARGO_PKG_LICENSE=MIT CARGO_PKG_LICENSE_FILE='' CARGO_PKG_NAME=uvc CARGO_PKG_README=README.md CARGO_PKG_REPOSITORY='https://github.com/mulimoen/libuvc-rs.git' CARGO_PKG_RUST_VERSION='' CARGO_PKG_VERSION=0.2.0 CARGO_PKG_VERSION_MAJOR=0 CARGO_PKG_VERSION_MINOR=2 CARGO_PKG_VERSION_PATCH=0 CARGO_PKG_VERSION_PRE='' LD_LIBRARY_PATH='/home/root/rust-uvc-server/target/debug/deps:/home/root/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib' /home/root/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/bin/rustc --crate-name uvc --edition=2018 /home/root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/uvc-0.2.0/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=171 --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 -C metadata=83bfea8dfb414f43 -C extra-filename=-83bfea8dfb414f43 --out-dir /home/root/rust-uvc-server/target/debug/deps -L dependency=/home/root/rust-uvc-server/target/debug/deps --extern uvc_sys=/home/root/rust-uvc-server/target/debug/deps/libuvc_sys-c9d07d5665601a18.rmeta --cap-lints warn error[E0425]: cannot find function 'uvc_mjpeg2rgb' in this scope --> /home/root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/uvc-0.2.0/src/frame.rs:39:39 | 39 | FrameFormat::MJPEG => uvc_mjpeg2rgb(self.frame.as_ptr(), new_frame.frame.as_ptr()), | ^^^^^^^^^^^^^ not found in this scope
For more information about this error, try 'rustc --explain E0425'. error: could not compile 'uvc' (lib) due to 1 previous error
Caused by:
process didn't exit successfully: 'CARGO=/home/root/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/bin/cargo CARGO_CRATE_NAME=uvc CARGO_MANIFEST_DIR=/home/root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/uvc-0.2.0 CARGO_PKG_AUTHORS='Magnus Ulimoen [email protected]' CARGO_PKG_DESCRIPTION='Safe and ergonomic wrapper around libuvc, allowing capture of webcam streams' CARGO_PKG_HOMEPAGE='' CARGO_PKG_LICENSE=MIT CARGO_PKG_LICENSE_FILE='' CARGO_PKG_NAME=uvc CARGO_PKG_README=README.md CARGO_PKG_REPOSITORY='https://github.com/mulimoen/libuvc-rs.git' CARGO_PKG_RUST_VERSION='' CARGO_PKG_VERSION=0.2.0 CARGO_PKG_VERSION_MAJOR=0 CARGO_PKG_VERSION_MINOR=2 CARGO_PKG_VERSION_PATCH=0 CARGO_PKG_VERSION_PRE='' LD_LIBRARY_PATH='/home/root/rust-uvc-server/target/debug/deps:/home/root/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib' /home/root/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/bin/rustc --crate-name uvc --edition=2018 /home/root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/uvc-0.2.0/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=171 --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 -C metadata=83bfea8dfb414f43 -C extra-filename=-83bfea8dfb414f43 --out-dir /home/root/rust-uvc-server/target/debug/deps -L dependency=/home/root/rust-uvc-server/target/debug/deps --extern uvc_sys=/home/root/rust-uvc-server/target/debug/deps/libuvc_sys-c9d07d5665601a18.rmeta --cap-lints warn (exit status: 1)

PTZ Control

I'm trying to control the PTZ of my camera and from this doc of libuvc it seems there are functions to do it in libuvc.
Does the rust library can do it too? Because from what I tried I'm not sure it is implemented

Add support for windows

I don't currently have a windows computer, but implementing support for windows should not be an insurmountable task. Would be nice to have both msvc and gnu targets enabled on the CI.

Make a consolidated `Camera` struct

Make a consolidated camera struct to make use in other crates easier without the use of self-referencing structs.

  • Consolidate
  • Polling frame function

Help Troubleshooting Error: Other

I'm basically trying out the example code, and fails with the following message:

Could not get context: Other
the line indicated points to first line where the context is created.

The 'Other' error seems to come directly from libuvc and there are no more details, so can't really continue troubleshooting on my own.

I'm using Windows 10, but running over WSL2, so basically ubuntu 20.
uvc is loaded as vendor:

uvc = {version = "0.2.0",default-features = false, features = ["vendor"]}

as that was the only way I was able to make it compile.

Do you know any other thing I can do to continue troubleshooting?

Locate and bind appropriate library

In #12 the library was not found under a system path. We should search for the appropriate library and emit the correct include and search flags for uvc. This could be done using e.g. pkg-config, predefined paths, or an environment variable.

compile failure: uvc_mjpeg2rgb not found

Howdy.. thanks for writing this library!

I tried to write a little test program (using the vendored form of libuvc), but something failed during the compile (this is on linux, Debian "buster", with libusb-1.0.0-dev installed but not libuvc):

   Compiling uvc v0.1.6
error[E0425]: cannot find function `uvc_mjpeg2rgb` in this scope
  --> /home/warner/.cargo/registry/src/github.com-1ecc6299db9ec823/uvc-0.1.6/src/frame.rs:39:39
   |
39 |                 FrameFormat::MJPEG => uvc_mjpeg2rgb(self.frame.as_ptr(), new_frame.frame.as_ptr()),
   |                                       ^^^^^^^^^^^^^ not found in this scope

error: aborting due to previous error

(I looked at the repo to see if maybe this was a change since the last released version, but there don't appear to be any git tags in the repository. Could you maybe add one for the 0.1.6 release? It looks like this repository has multiple crates in it, so I guess the tag would need to cite the package it's for, like libuvc-rs-0.1.6)

I'm not sure what the problem is.. it feels like some header file is missing a couple of function definitions.

In case it helps, my test program is just a cargo new plus the following dependency:

[dependencies]
uvc = { version = "0.1.6", default-features = false, features = ["vendor"] }

thanks!
-Brian

Getting "Corrupt JPEG data: 1 extraneous bytes before marker 0xd4" at runtime, but library still works. Can I get pre-encoded jpeg streams?

My use case for this library is to get a stream of jpeg images, and I was expecting to have to encode them myself (or, rather, integrate with another library to do it). But, I noticed that, although the example still displays exactly as it should, messages of the form "Corrupt JPEG data: 1 extraneous bytes before marker 0xd4" (the marker's hex and number of extraneous bytes varies) spam the terminal when I run the mirror example, suggesting that libuvc is decoding jpeg images internally. Obviously, it's less than idea to have the library decode jpeg images only for them to be immediately re-encoded back into jpeg. As such, is there some way to access these images as jpeg?

ctx.devices() panics at end of device list

A small test program:

fn main() {
    // Get a libuvc context
    let ctx = uvc::Context::new().expect("Could not get context");

    for dev in ctx.devices().expect("Could not enumerate devices") {
        let desc = dev.description().expect("could not get description");
        println!("device [{}.{}] id=({:04x}/{:04x}): {}", dev.bus_number(), dev.device_address(),
                 desc.vendor_id, desc.product_id,
                 desc.product.unwrap_or("<unknown>".to_string()));
    }
}

shows me the camera device I expected, but then panics before it gets out of the loop:

device [20.23] id=(0bda/58bb): FULL HD 1080P Webcam
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', /Users/warner/stuff/rust/libuvc-rs/src/device.rs:78:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

It's happening in the unwrap here:

impl<'a> Device<'a> {
    pub(crate) unsafe fn from_raw(dev: *mut uvc_device) -> Self {
        Device {
            dev: NonNull::new(dev).unwrap(),
            _dev: PhantomData,
        }
    }

Is the C code maybe returning a list of pointers, and using NULL to indicate the end of the list? I don't know how to read the unsafe code (I'm still pretty new at rust). I'm looking at DeviceList and it's Iterator.. am I correct in thinking that the DeviceList can only be iterated once? It looks like the reached_end state flag lives in the DeviceList, rather than the iterator. Would it be possible for ctx.devices() to build the Device structs right away, and store them in a regular Vec, rather than constructing those structs during iteration?

thanks,
-Brian

Lifetime Issues with modified example

I was working with your example and it works great. But when I tried to move the necessary code to create the streamh variable into an independent function I ran into lifetime issues, with the compiler telling me that the borrowed value does not live long enough, that in only lives to the end of the function. I need to ask: Am I doing something wrong?

Code:

#[macro_use]
extern crate glium;
extern crate uvc;

use std::error::Error;
use std::sync::{Arc, Mutex};

use glium::Surface;
use uvc::{Context, Frame, StreamHandle};

fn frame_to_raw_image(
    frame: &Frame,
) -> Result<glium::texture::RawImage2d<'static, u8>, Box<dyn Error>> {
    let new_frame = frame.to_rgb()?;
    let data = new_frame.to_bytes();

    let image = glium::texture::RawImage2d::from_raw_rgb(
        data.to_vec(),
        (new_frame.width(), new_frame.height()),
    );

    Ok(image)
}

fn callback_frame_to_image(
    frame: &Frame,
    data: &mut Arc<Mutex<Option<glium::texture::RawImage2d<u8>>>>,
) {
    let image = frame_to_raw_image(frame);
    match image {
        Err(x) => println!("{:#?}", x),
        Ok(x) => {
            let mut data = Mutex::lock(&data).unwrap();
            *data = Some(x);
        }
    }
}

fn get_stream <'a, 'b> () -> StreamHandle<'a, 'b> {
    let ctx = Context::new().expect("Could not create context");
    let dev = ctx
        .find_device(None, None, None)
        .expect("Could not find device");

    let description = dev.description().unwrap();
    println!(
        "Found device: Bus {:03} Device {:03} : ID {:04x}:{:04x} {} ({})",
        dev.bus_number(),
        dev.device_address(),
        description.vendor_id,
        description.product_id,
        description.product.unwrap_or_else(|| "Unknown".to_owned()),
        description
            .manufacturer
            .unwrap_or_else(|| "Unknown".to_owned())
    );

    // Open multiple devices by enumerating:
    // let mut list = ctx.devices().expect("Could not get devices");
    // let dev = list.next().expect("No device available");

    let devh = dev.open().expect("Could not open device");

    let format = devh
        .get_preferred_format(|x, y| {
            if x.fps >= y.fps && x.width * x.height >= y.width * y.height {
                x
            } else {
                y
            }
        }).unwrap();

    println!("Best format found: {:?}", format);
    let streamh = devh.get_stream_handle_with_format(format).unwrap();

    streamh
}

fn main() {
    let mut streamh = get_stream();

    println!(
            "Scanning mode: {:?}\nAuto-exposure mode: {:?}\nAuto-exposure priority: {:?}\nAbsolute exposure: {:?}\nRelative exposure: {:?}\nAboslute focus: {:?}\nRelative focus: {:?}",
            devh.scanning_mode(),
            devh.ae_mode(),
            devh.ae_priority(),
            devh.exposure_abs(),
            devh.exposure_rel(),
            devh.focus_abs(),
            devh.focus_rel(),
        );

    let frame = Arc::new(Mutex::new(None));
    let _stream = streamh
        .start_stream(callback_frame_to_image, frame.clone())
        .unwrap();

    use glium::glutin;
    let mut events_loop = glium::glutin::EventsLoop::new();
    let window = glium::glutin::WindowBuilder::new().with_title("Mirror");
    let context = glium::glutin::ContextBuilder::new();
    let display = glium::Display::new(window, context, &events_loop).unwrap();

    #[derive(Copy, Clone)]
    pub struct QuadVertex {
        pos: (f32, f32),
    }

    implement_vertex!(QuadVertex, pos);

    let vertices: [QuadVertex; 4] = [
        QuadVertex { pos: (-1.0, -1.0) },
        QuadVertex { pos: (-1.0, 1.0) },
        QuadVertex { pos: (1.0, -1.0) },
        QuadVertex { pos: (1.0, 1.0) },
    ];

    let indices: [u8; 6] = [0, 1, 2, 1, 3, 2];

    let vertex_shader_source = r#"
    #version 140

    in vec2 pos;

    out vec2 v_position;

    void main() {
        v_position = (pos + 1.0)/2.0;
        gl_Position = vec4(-pos.x, -pos.y, 0.0, 1.0);
    }
    "#;

    let fragment_shader_source = r#"
    #version 140

    in vec2 v_position;

    out vec4 colour;

    uniform sampler2D u_image;

    void main() {
        vec2 pos = v_position;

        colour = texture(u_image, pos);
    }
    "#;

    let vertices = glium::VertexBuffer::new(&display, &vertices).unwrap();
    let indices = glium::IndexBuffer::new(
        &display,
        glium::index::PrimitiveType::TrianglesList,
        &indices,
    ).unwrap();
    let program =
        glium::Program::from_source(&display, vertex_shader_source, fragment_shader_source, None)
            .unwrap();

    let mut closed = false;
    let mut buffer: Option<glium::texture::SrgbTexture2d> = None;
    while !closed {
        events_loop.poll_events(|ev| match ev {
            glutin::Event::WindowEvent { event, .. } => match event {
                glutin::WindowEvent::CloseRequested => closed = true,
                _ => {}
            },
            _ => {}
        });

        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 1.0, 1.0);

        let mut mutex = Mutex::lock(&frame).unwrap();

        match mutex.take() {
            None => {
                // No new frame to render
            }
            Some(image) => {
                let image = glium::texture::SrgbTexture2d::new(&display, image)
                    .expect("Could not use image");
                buffer = Some(image);
            }
        }

        if let Some(ref b) = buffer {
            let uniforms = uniform! { u_image: b };
            target
                .draw(
                    &vertices,
                    &indices,
                    &program,
                    &uniforms,
                    &Default::default(),
                ).unwrap();
        }

        target.finish().unwrap();
    }
}

Failed to build on Ubuntu

$ git clone --recurse-submodules [email protected]:mulimoen/libuvc-rs.git
$ cd libuvc-rs
$ cargo build --features vendor
    Updating crates.io index
   Compiling libc v0.2.79
   ...
   Compiling uvc-src v0.2.0 (/home/justin/libuvc-rs/uvc-src)
The following warnings were emitted during compilation:

warning: couldn't execute `llvm-config --prefix` (error: No such file or directory (os error 2))
warning: set the LLVM_CONFIG_PATH environment variable to the full path to a valid `llvm-config` executable (including the executable itself)

error: failed to run custom build command for `uvc-sys v0.1.4 (/home/justin/libuvc-rs/uvc-sys)`

Caused by:
  process didn't exit successfully: `/home/justin/libuvc-rs/target/debug/build/uvc-sys-6d3c0da2305fc1f2/build-script-build` (exit code: 101)
  --- stdout
  cargo:rustc-link-lib=uvc
  cargo:warning=couldn't execute `llvm-config --prefix` (error: No such file or directory (os error 2))
  cargo:warning=set the LLVM_CONFIG_PATH environment variable to the full path to a valid `llvm-config` executable (including the executable itself)

  --- stderr
  wrapper.h:1:10: fatal error: 'libuvc/libuvc.h' file not found
  wrapper.h:1:10: fatal error: 'libuvc/libuvc.h' file not found, err: true
  thread 'main' panicked at 'Failed to generate bindings: ()', uvc-sys/build.rs:14:10
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
error: build failed

Can't build on Windows

Are there any instructions to build it on Windows?

  1. I run 'cargo build' but failed with wrapper.h:1:10: fatal error: 'libuvc/libuvc.h' file not found.
  2. I download libuvc source code and extracted to uvc-src/source, ran 'cargo build' in uvc-src, but end up with the error:
  error occurred: Command "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.27.29110\\bin\\HostX64\\x64\\cl.exe" "-nologo" "-MD" "-Z7" "-Brepro" "-I" "d:\\workspace\\libuvc-rs\\target\\debug\\build\\uvc-src-4dd37a42ddbc29e6\\out\\include" "-I" "d:\\workspace\\libuvc-rs\\target\\debug\\build\\libusb1-sys-aaea21a84a91340c\\out\\include" "-Fod:\\workspace\\libuvc-rs\\target\\debug\\build\\uvc-src-4dd37a42ddbc29e6\\out\\source/src/ctrl.o" "-c" "source/src/ctrl.c" with args "cl.exe" did not execute successfully (status code exit code: 2).

Apple M1 support

I'm creating this issue to track support for Apple M1 silicon machines.

Currently, there are two outstanding issues which need to be solved:

  1. winit = "0.26"
    This will come with the glium "0.29" release which should be released next week.
  2. libusb1-sys needs to be vendored (features = ["vendored"])
    The only "real" package manager for macOS is brew, but it's not fully supported on Apple aarch64 yet. That means there is no "easy" way to get libusbinstalled for libusb1-sys to link against.

The first item is obviously just needed to get the mirror.rs example working, so it's not vital to the library itself. Would you be fine with making libusb1-sys vendored? Maybe we could just enable it automatically when the "vendor" feature is enabled for this crate (uvc).

Vendor libuvc

Many systems do not have libuvc available, including docs.rs builders. Note that you should add it as a submodule instead of fetching the source in build.rs, as docs.rs stopped allowing network access a few months ago.

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.