From ebd09ab1c8f890d0004b6e786a09e13a2caeceeb Mon Sep 17 00:00:00 2001 From: ardocrat Date: Sat, 26 Oct 2024 23:25:55 +0300 Subject: [PATCH] camera: update nokhwa, eye for macos, ability to switch camera when another camera not loaded --- Cargo.lock | 447 ++++++++++++++++++-------------- Cargo.toml | 15 +- src/gui/platform/desktop/mod.rs | 197 ++++++++++---- src/gui/views/camera.rs | 43 +-- 4 files changed, 430 insertions(+), 272 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c3a78f..9daca1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -408,8 +408,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df099ccb16cd014ff054ac1bf392c67feeef57164b05c42f037cd40f5d4357f4" dependencies = [ "clipboard-win", - "core-graphics 0.23.2", - "image 0.25.2", + "core-graphics", + "image", "log", "objc2", "objc2-app-kit", @@ -983,9 +983,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2da379dbebc0b76ef63ca68d8fc6e71c0f13e59432e0987e508c1820e6ab5239" dependencies = [ "bitflags 1.3.2", - "cexpr", + "cexpr 0.4.0", "clang-sys", - "clap", + "clap 2.34.0", "env_logger 0.8.4", "lazy_static", "lazycell", @@ -996,7 +996,53 @@ dependencies = [ "regex", "rustc-hash", "shlex 0.1.1", - "which", + "which 3.1.1", +] + +[[package]] +name = "bindgen" +version = "0.60.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" +dependencies = [ + "bitflags 1.3.2", + "cexpr 0.6.0", + "clang-sys", + "clap 3.2.25", + "env_logger 0.9.3", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2 1.0.87", + "quote 1.0.37", + "regex", + "rustc-hash", + "shlex 1.3.0", + "which 4.4.2", +] + +[[package]] +name = "bindgen" +version = "0.65.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +dependencies = [ + "bitflags 1.3.2", + "cexpr 0.6.0", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "prettyplease", + "proc-macro2 1.0.87", + "quote 1.0.37", + "regex", + "rustc-hash", + "shlex 1.3.0", + "syn 2.0.79", + "which 4.4.2", ] [[package]] @@ -1326,6 +1372,15 @@ dependencies = [ "nom 5.1.3", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom 7.1.3", +] + [[package]] name = "cfg-expr" version = "0.15.8" @@ -1450,11 +1505,35 @@ dependencies = [ "atty", "bitflags 1.3.2", "strsim 0.8.0", - "textwrap", + "textwrap 0.11.0", "unicode-width", "vec_map", ] +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_lex", + "indexmap 1.9.3", + "strsim 0.10.0", + "termcolor", + "textwrap 0.16.1", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "clipboard-win" version = "5.4.0" @@ -1473,6 +1552,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "cmake" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" +dependencies = [ + "cc", +] + [[package]] name = "coarsetime" version = "0.1.34" @@ -1484,35 +1572,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "cocoa" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c49e86fc36d5704151f5996b7b3795385f50ce09e3be0f47a0cfde869681cf8" -dependencies = [ - "bitflags 1.3.2", - "block", - "core-foundation 0.7.0", - "core-graphics 0.19.2", - "foreign-types 0.3.2", - "libc", - "objc", -] - -[[package]] -name = "cocoa-foundation" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" -dependencies = [ - "bitflags 1.3.2", - "block", - "core-foundation 0.9.4", - "core-graphics-types", - "libc", - "objc", -] - [[package]] name = "codespan-reporting" version = "0.11.1" @@ -1657,18 +1716,6 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "core-graphics" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.7.0", - "foreign-types 0.3.2", - "libc", -] - [[package]] name = "core-graphics" version = "0.23.2" @@ -1693,31 +1740,6 @@ dependencies = [ "libc", ] -[[package]] -name = "core-media-sys" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "273bf3fc5bf51fd06a7766a84788c1540b6527130a0bce39e00567d6ab9f31f1" -dependencies = [ - "cfg-if 0.1.10", - "core-foundation-sys 0.7.0", - "libc", -] - -[[package]] -name = "core-video-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" -dependencies = [ - "cfg-if 0.1.10", - "core-foundation-sys 0.7.0", - "core-graphics 0.19.2", - "libc", - "metal 0.18.0", - "objc", -] - [[package]] name = "cpufeatures" version = "0.2.14" @@ -2395,7 +2417,7 @@ dependencies = [ [[package]] name = "ecolor" version = "0.29.1" -source = "git+https://github.com/emilk/egui?rev=23728e145ec52bd1193f6f0123973763de4dbb3d#23728e145ec52bd1193f6f0123973763de4dbb3d" +source = "git+https://github.com/emilk/egui?rev=5b846b4554fe47269affb43efef2cad8710a8a47#5b846b4554fe47269affb43efef2cad8710a8a47" dependencies = [ "bytemuck", "emath", @@ -2465,7 +2487,7 @@ dependencies = [ [[package]] name = "eframe" version = "0.29.1" -source = "git+https://github.com/emilk/egui?rev=23728e145ec52bd1193f6f0123973763de4dbb3d#23728e145ec52bd1193f6f0123973763de4dbb3d" +source = "git+https://github.com/emilk/egui?rev=5b846b4554fe47269affb43efef2cad8710a8a47#5b846b4554fe47269affb43efef2cad8710a8a47" dependencies = [ "ahash", "bytemuck", @@ -2477,7 +2499,7 @@ dependencies = [ "glow 0.14.1", "glutin", "glutin-winit", - "image 0.25.2", + "image", "js-sys", "log", "objc2", @@ -2501,7 +2523,7 @@ dependencies = [ [[package]] name = "egui" version = "0.29.1" -source = "git+https://github.com/emilk/egui?rev=23728e145ec52bd1193f6f0123973763de4dbb3d#23728e145ec52bd1193f6f0123973763de4dbb3d" +source = "git+https://github.com/emilk/egui?rev=5b846b4554fe47269affb43efef2cad8710a8a47#5b846b4554fe47269affb43efef2cad8710a8a47" dependencies = [ "accesskit", "ahash", @@ -2514,7 +2536,7 @@ dependencies = [ [[package]] name = "egui-wgpu" version = "0.29.1" -source = "git+https://github.com/emilk/egui?rev=23728e145ec52bd1193f6f0123973763de4dbb3d#23728e145ec52bd1193f6f0123973763de4dbb3d" +source = "git+https://github.com/emilk/egui?rev=5b846b4554fe47269affb43efef2cad8710a8a47#5b846b4554fe47269affb43efef2cad8710a8a47" dependencies = [ "ahash", "bytemuck", @@ -2532,7 +2554,7 @@ dependencies = [ [[package]] name = "egui-winit" version = "0.29.1" -source = "git+https://github.com/emilk/egui?rev=23728e145ec52bd1193f6f0123973763de4dbb3d#23728e145ec52bd1193f6f0123973763de4dbb3d" +source = "git+https://github.com/emilk/egui?rev=5b846b4554fe47269affb43efef2cad8710a8a47#5b846b4554fe47269affb43efef2cad8710a8a47" dependencies = [ "accesskit_winit", "ahash", @@ -2549,12 +2571,12 @@ dependencies = [ [[package]] name = "egui_extras" version = "0.29.1" -source = "git+https://github.com/emilk/egui?rev=23728e145ec52bd1193f6f0123973763de4dbb3d#23728e145ec52bd1193f6f0123973763de4dbb3d" +source = "git+https://github.com/emilk/egui?rev=5b846b4554fe47269affb43efef2cad8710a8a47#5b846b4554fe47269affb43efef2cad8710a8a47" dependencies = [ "ahash", "egui", "enum-map", - "image 0.25.2", + "image", "log", "mime_guess2", "resvg", @@ -2563,7 +2585,7 @@ dependencies = [ [[package]] name = "egui_glow" version = "0.29.1" -source = "git+https://github.com/emilk/egui?rev=23728e145ec52bd1193f6f0123973763de4dbb3d#23728e145ec52bd1193f6f0123973763de4dbb3d" +source = "git+https://github.com/emilk/egui?rev=5b846b4554fe47269affb43efef2cad8710a8a47#5b846b4554fe47269affb43efef2cad8710a8a47" dependencies = [ "ahash", "bytemuck", @@ -2604,7 +2626,7 @@ dependencies = [ [[package]] name = "emath" version = "0.29.1" -source = "git+https://github.com/emilk/egui?rev=23728e145ec52bd1193f6f0123973763de4dbb3d#23728e145ec52bd1193f6f0123973763de4dbb3d" +source = "git+https://github.com/emilk/egui?rev=5b846b4554fe47269affb43efef2cad8710a8a47#5b846b4554fe47269affb43efef2cad8710a8a47" dependencies = [ "bytemuck", ] @@ -2730,6 +2752,19 @@ dependencies = [ "termcolor", ] +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime 2.1.0", + "log", + "regex", + "termcolor", +] + [[package]] name = "env_logger" version = "0.11.5" @@ -2746,7 +2781,7 @@ dependencies = [ [[package]] name = "epaint" version = "0.29.1" -source = "git+https://github.com/emilk/egui?rev=23728e145ec52bd1193f6f0123973763de4dbb3d#23728e145ec52bd1193f6f0123973763de4dbb3d" +source = "git+https://github.com/emilk/egui?rev=5b846b4554fe47269affb43efef2cad8710a8a47#5b846b4554fe47269affb43efef2cad8710a8a47" dependencies = [ "ab_glyph", "ahash", @@ -2762,7 +2797,7 @@ dependencies = [ [[package]] name = "epaint_default_fonts" version = "0.29.1" -source = "git+https://github.com/emilk/egui?rev=23728e145ec52bd1193f6f0123973763de4dbb3d#23728e145ec52bd1193f6f0123973763de4dbb3d" +source = "git+https://github.com/emilk/egui?rev=5b846b4554fe47269affb43efef2cad8710a8a47#5b846b4554fe47269affb43efef2cad8710a8a47" [[package]] name = "equivalent" @@ -2814,7 +2849,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" dependencies = [ "bit_field", - "flume 0.11.0", + "flume", "half", "lebe", "miniz_oxide 0.7.4", @@ -2823,6 +2858,28 @@ dependencies = [ "zune-inflate", ] +[[package]] +name = "eye" +version = "0.5.0" +source = "git+https://github.com/raymanfx/eye-rs?rev=5b7e3f7a1e79966091692896c568aab042e449ef#5b7e3f7a1e79966091692896c568aab042e449ef" +dependencies = [ + "eye-hal", + "ffimage", + "ffimage_yuv", +] + +[[package]] +name = "eye-hal" +version = "0.2.0" +source = "git+https://github.com/raymanfx/eye-rs?rev=5b7e3f7a1e79966091692896c568aab042e449ef#5b7e3f7a1e79966091692896c568aab042e449ef" +dependencies = [ + "bitflags 2.6.0", + "openpnp_capture", + "openpnp_capture_sys", + "uvc", + "v4l", +] + [[package]] name = "fake-simd" version = "0.1.2" @@ -2866,6 +2923,25 @@ dependencies = [ "subtle", ] +[[package]] +name = "ffimage" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed0a72fa07ae1c1c2d50f9caeb30890b23596b73d1c2f6cd229a2ae658a15d36" +dependencies = [ + "num-traits 0.2.19", +] + +[[package]] +name = "ffimage_yuv" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cf7ab943a8157f1f133a07ae728d5844b30d982e43f24c1098d6dc6cf38efb3" +dependencies = [ + "ffimage", + "num-traits 0.2.19", +] + [[package]] name = "fiat-crypto" version = "0.2.9" @@ -2972,19 +3048,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "749cff877dc1af878a0b31a41dd221a753634401ea0ef2f87b62d3171522485a" -[[package]] -name = "flume" -version = "0.10.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" -dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "pin-project", - "spin 0.9.8", -] - [[package]] name = "flume" version = "0.11.0" @@ -3561,6 +3624,7 @@ dependencies = [ "egui", "egui_extras", "env_logger 0.11.5", + "eye", "fs-mistrust", "futures 0.3.31", "gif", @@ -3577,9 +3641,9 @@ dependencies = [ "grin_wallet_impls", "grin_wallet_libwallet", "grin_wallet_util", - "hyper 0.14.30", + "hyper 0.14.31", "hyper-tls 0.5.0", - "image 0.25.2", + "image", "interprocess", "jni", "lazy_static", @@ -4390,9 +4454,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.30" +version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" dependencies = [ "bytes 1.7.2", "futures-channel", @@ -4478,7 +4542,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes 1.7.2", - "hyper 0.14.30", + "hyper 0.14.31", "native-tls", "tokio 1.40.0", "tokio-native-tls", @@ -4614,18 +4678,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "image" -version = "0.24.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "num-traits 0.2.19", -] - [[package]] name = "image" version = "0.25.2" @@ -5323,21 +5375,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "metal" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e198a0ee42bdbe9ef2c09d0b9426f3b2b47d90d93a4a9b0395c4cea605e92dc0" -dependencies = [ - "bitflags 1.3.2", - "block", - "cocoa", - "core-graphics 0.19.2", - "foreign-types 0.3.2", - "log", - "objc", -] - [[package]] name = "metal" version = "0.29.0" @@ -5532,15 +5569,6 @@ dependencies = [ "unicode-xid 0.2.6", ] -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom 0.2.15", -] - [[package]] name = "native-tls" version = "0.2.12" @@ -5666,14 +5694,12 @@ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" [[package]] name = "nokhwa" -version = "0.10.4" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4ae290027ab0d22e1405d304603e41edfaee597a81ce09cf751785b44c32a9" +checksum = "6b15e209a06308df0e9d0042a2ff0b190af22fa0a56535b4eb8a422a2332759c" dependencies = [ - "flume 0.10.14", - "image 0.24.9", + "image", "nokhwa-bindings-linux", - "nokhwa-bindings-macos", "nokhwa-bindings-windows", "nokhwa-core", "paste", @@ -5682,36 +5708,19 @@ dependencies = [ [[package]] name = "nokhwa-bindings-linux" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "448db09af68e12168b6311423409f679d2da6e75fb158b2d75de2f5d6dc460ca" +checksum = "9f1abe593709a177b1a6b87ebbae0bfe5ecc2f8d80d81e89e0a9b68487490a01" dependencies = [ "nokhwa-core", "v4l", - "v4l2-sys-mit", -] - -[[package]] -name = "nokhwa-bindings-macos" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739d58859fd2b958f01c25de9a0fbb686be7271e5ef3624150e2be85a627b38a" -dependencies = [ - "block", - "cocoa-foundation", - "core-media-sys", - "core-video-sys", - "flume 0.10.14", - "nokhwa-core", - "objc", - "once_cell", ] [[package]] name = "nokhwa-bindings-windows" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9b9bae36d0ce413568cefb94c43748e80f9ae97aa0a9e2d8e18f0275a909746" +checksum = "e6f82cd46134e24bbfe344280603fc9753b5a589ab6c62959e2b0cf2f906bef1" dependencies = [ "nokhwa-core", "once_cell", @@ -5720,12 +5729,12 @@ dependencies = [ [[package]] name = "nokhwa-core" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb9b0e58413cb1b6d041d802be0e921368f3c72525b7ea720089c8aa140d6d49" +checksum = "f13f7d3ea46f585ef235e705ade22633f0e15ba14a27d4672ab2b1d4434557fa" dependencies = [ "bytes 1.7.2", - "image 0.24.9", + "image", "thiserror", ] @@ -5979,7 +5988,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" dependencies = [ "malloc_buf", - "objc_exception", ] [[package]] @@ -6185,15 +6193,6 @@ dependencies = [ "objc2-foundation", ] -[[package]] -name = "objc_exception" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" -dependencies = [ - "cc", -] - [[package]] name = "object" version = "0.36.5" @@ -6230,6 +6229,26 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openpnp_capture" +version = "0.2.4" +source = "git+https://github.com/ardocrat/openpnp-capture-rs?rev=f9b06f627c5e5d42c672d117650af700846ca6cf#f9b06f627c5e5d42c672d117650af700846ca6cf" +dependencies = [ + "lazy_static", + "openpnp_capture_sys", +] + +[[package]] +name = "openpnp_capture_sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "210344540125153a623f5b0c8a3880a2aef08bb7c70e92a159574047d7319507" +dependencies = [ + "bindgen 0.60.1", + "cc", + "cmake", +] + [[package]] name = "openssl" version = "0.10.66" @@ -6327,6 +6346,12 @@ dependencies = [ "pin-project-lite 0.2.14", ] +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + [[package]] name = "overload" version = "0.1.1" @@ -6709,6 +6734,16 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" +[[package]] +name = "prettyplease" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" +dependencies = [ + "proc-macro2 1.0.87", + "syn 2.0.79", +] + [[package]] name = "prettytable-rs" version = "0.10.0" @@ -6856,7 +6891,7 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d68782463e408eb1e668cf6152704bd856c78c5b6417adaee3203d8f4c1fc9ec" dependencies = [ - "image 0.25.2", + "image", ] [[package]] @@ -7490,7 +7525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48eaf9c75f2a8f231b09036c115a45a9845313f7faa6a39fa45a2a2bd06a27c7" dependencies = [ "g2p", - "image 0.25.2", + "image", "lru", ] @@ -8639,6 +8674,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" + [[package]] name = "thiserror" version = "1.0.64" @@ -10411,10 +10452,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" [[package]] -name = "v4l" -version = "0.13.1" +name = "uvc" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9946a2fda19c7a729dc72e28b9fd9c653e9b7de954ffe3aecaf51977f88762" +checksum = "6b4126f130b1b469a8342f7c0001c4f4ac828613c977d6887972d60e0ddff1f9" +dependencies = [ + "uvc-sys", +] + +[[package]] +name = "uvc-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3675c448fbdc98cbdc4f755a541d41154d153eb3112686be533940ae925eb00" +dependencies = [ + "bindgen 0.56.0", +] + +[[package]] +name = "v4l" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8fbfea44a46799d62c55323f3c55d06df722fbe577851d848d328a1041c3403" dependencies = [ "bitflags 1.3.2", "libc", @@ -10423,11 +10482,11 @@ dependencies = [ [[package]] name = "v4l2-sys-mit" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c932c06df4af1dfb229f604214f2a87993784596ff33ffdadcba1b5519254e" +checksum = "6779878362b9bacadc7893eac76abe69612e8837ef746573c4a5239daf11990b" dependencies = [ - "bindgen", + "bindgen 0.65.1", ] [[package]] @@ -10861,7 +10920,7 @@ dependencies = [ "libc", "libloading", "log", - "metal 0.29.0", + "metal", "naga", "ndk-sys 0.5.0+25.2.9519653", "objc", @@ -10900,6 +10959,18 @@ dependencies = [ "libc", ] +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + [[package]] name = "widestring" version = "1.1.0" @@ -11277,7 +11348,7 @@ dependencies = [ "cfg_aliases 0.2.1", "concurrent-queue", "core-foundation 0.9.4", - "core-graphics 0.23.2", + "core-graphics", "cursor-icon", "dpi", "js-sys", diff --git a/Cargo.toml b/Cargo.toml index f431023..aa53f18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,7 +91,7 @@ tor-error = "0.23.0" sha2 = "0.10.8" ed25519-dalek = "2.1.1" curve25519-dalek = "4.1.3" -hyper = { version = "0.14.29", features = ["full"] } +hyper = { version = "0.14.30", features = ["full"] } hyper-tls = "0.5.0" tls-api = "0.9.0" tls-api-native-tls = "0.9.0" @@ -101,13 +101,13 @@ tokio-old = {version = "0.2", features = ["full"], package = "tokio" } tokio-util-old = { version = "0.2", features = ["codec"], package = "tokio-util" } [target.'cfg(target_os = "linux")'.dependencies] -nokhwa = { version = "0.10.4", default-features = false, features = ["input-v4l"] } +nokhwa = { version = "0.10.5", default-features = false, features = ["input-v4l"] } [target.'cfg(target_os = "windows")'.dependencies] -nokhwa = { version = "0.10.4", default-features = false, features = ["input-msmf"] } +nokhwa = { version = "0.10.5", default-features = false, features = ["input-msmf"] } [target.'cfg(target_os = "macos")'.dependencies] -nokhwa = { version = "0.10.4", default-features = false, features = ["flume", "input-avfoundation"] } +eye = { git = "https://github.com/raymanfx/eye-rs", rev = "5b7e3f7a1e79966091692896c568aab042e449ef", default-features = false } tls-api-openssl = "0.9.0" [target.'cfg(not(target_os = "android"))'.dependencies] @@ -127,8 +127,9 @@ winit = { version = "0.30.5", features = ["android-game-activity"] } eframe = { version = "0.29.1", features = ["wgpu", "android-game-activity"] } [patch.crates-io] -egui_extras = { git = "https://github.com/emilk/egui", rev = "23728e145ec52bd1193f6f0123973763de4dbb3d" } -egui = { git = "https://github.com/emilk/egui", rev = "23728e145ec52bd1193f6f0123973763de4dbb3d" } -eframe = { git = "https://github.com/emilk/egui", rev = "23728e145ec52bd1193f6f0123973763de4dbb3d" } +openpnp_capture = { git = "https://github.com/ardocrat/openpnp-capture-rs", rev = "f9b06f627c5e5d42c672d117650af700846ca6cf" } +egui_extras = { git = "https://github.com/emilk/egui", rev = "5b846b4554fe47269affb43efef2cad8710a8a47" } +egui = { git = "https://github.com/emilk/egui", rev = "5b846b4554fe47269affb43efef2cad8710a8a47" } +eframe = { git = "https://github.com/emilk/egui", rev = "5b846b4554fe47269affb43efef2cad8710a8a47" } ### patch grin store #grin_store = { path = "../grin-store" } diff --git a/src/gui/platform/desktop/mod.rs b/src/gui/platform/desktop/mod.rs index 11e51d1..ecbafb8 100644 --- a/src/gui/platform/desktop/mod.rs +++ b/src/gui/platform/desktop/mod.rs @@ -15,7 +15,7 @@ use std::fs::File; use std::io::Write; use std::thread; -use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::Arc; use parking_lot::RwLock; use lazy_static::lazy_static; @@ -30,6 +30,10 @@ pub struct Desktop { /// Context to repaint content and handle viewport commands. ctx: Arc>>, + /// Cameras amount. + cameras_amount: Arc, + /// Camera index. + camera_index: Arc, /// Flag to check if camera stop is needed. stop_camera: Arc, @@ -37,6 +41,127 @@ pub struct Desktop { attention_required: Arc, } +impl Desktop { + pub fn new() -> Self { + Self { + ctx: Arc::new(RwLock::new(None)), + cameras_amount: Arc::new(AtomicUsize::new(0)), + camera_index: Arc::new(AtomicUsize::new(0)), + stop_camera: Arc::new(AtomicBool::new(false)), + attention_required: Arc::new(AtomicBool::new(false)), + } + } + + #[allow(dead_code)] + #[cfg(not(target_os = "macos"))] + fn start_camera_capture(cameras_amount: Arc, + camera_index: Arc, + stop_camera: Arc) { + use nokhwa::Camera; + use nokhwa::pixel_format::RgbFormat; + use nokhwa::utils::{CameraIndex, RequestedFormat, RequestedFormatType}; + use nokhwa::utils::ApiBackend; + + let devices = nokhwa::query(ApiBackend::Auto).unwrap(); + cameras_amount.store(devices.len(), Ordering::Relaxed); + let index = camera_index.load(Ordering::Relaxed); + if devices.is_empty() || index >= devices.len() { + return; + } + + thread::spawn(move || { + let index = CameraIndex::Index(camera_index.load(Ordering::Relaxed) as u32); + let requested = RequestedFormat::new::( + RequestedFormatType::AbsoluteHighestFrameRate + ); + // Create and open camera. + if let Ok(mut camera) = Camera::new(index, requested) { + if let Ok(_) = camera.open_stream() { + loop { + // Stop if camera was stopped. + if stop_camera.load(Ordering::Relaxed) { + stop_camera.store(false, Ordering::Relaxed); + // Clear image. + let mut w_image = LAST_CAMERA_IMAGE.write(); + *w_image = None; + break; + } + // Get a frame. + if let Ok(frame) = camera.frame() { + // Save image. + let mut w_image = LAST_CAMERA_IMAGE.write(); + *w_image = Some((frame.buffer().to_vec(), 0)); + } else { + // Clear image. + let mut w_image = LAST_CAMERA_IMAGE.write(); + *w_image = None; + break; + } + } + camera.stop_stream().unwrap(); + }; + } + }); + } + + #[allow(dead_code)] + #[cfg(target_os = "macos")] + fn start_camera_capture(cameras_amount: Arc, + camera_index: Arc, + stop_camera: Arc) { + use image::{ExtendedColorType, ImageBuffer, ImageEncoder, Rgb}; + use eye::hal::{traits::{Context, Device, Stream}, PlatformContext}; + use image::codecs::jpeg::JpegEncoder; + + let index = camera_index.load(Ordering::Relaxed); + let devices = PlatformContext::default().devices().unwrap_or(vec![]); + cameras_amount.store(devices.len(), Ordering::Relaxed); + if devices.is_empty() || index >= devices.len() { + return; + } + + // Capture images at separate thread. + let uri = devices[camera_index.load(Ordering::Relaxed)].uri.clone(); + thread::spawn(move || { + if let Ok(dev) = PlatformContext::default().open_device(&uri) { + let streams = dev.streams().unwrap_or(vec![]); + if streams.is_empty() { + return; + } + let stream_desc = streams[0].clone(); + let w = stream_desc.width; + let h = stream_desc.height; + if let Ok(mut stream) = dev.start_stream(&stream_desc) { + loop { + // Stop if camera was stopped. + if stop_camera.load(Ordering::Relaxed) { + stop_camera.store(false, Ordering::Relaxed); + let mut w_image = LAST_CAMERA_IMAGE.write(); + *w_image = None; + break; + } + // Get a frame. + let frame = stream.next() + .expect("Stream is dead") + .expect("Failed to capture a frame"); + let mut out = vec![]; + if let Some(buf) = ImageBuffer::, &[u8]>::from_raw(w, h, &frame) { + JpegEncoder::new(&mut out) + .write_image(buf.as_raw(), w, h, ExtendedColorType::Rgb8) + .unwrap_or_default(); + } else { + out = frame.to_vec(); + } + // Save image. + let mut w_image = LAST_CAMERA_IMAGE.write(); + *w_image = Some((out, 0)); + } + } + } + }); + } +} + impl PlatformCallbacks for Desktop { fn set_context(&mut self, ctx: &egui::Context) { let mut w_ctx = self.ctx.write(); @@ -47,7 +172,7 @@ impl PlatformCallbacks for Desktop { let r_ctx = self.ctx.read(); if r_ctx.is_some() { let ctx = r_ctx.as_ref().unwrap(); - ctx.send_viewport_cmd(egui::ViewportCommand::Close); + ctx.send_viewport_cmd(ViewportCommand::Close); } } @@ -71,15 +196,13 @@ impl PlatformCallbacks for Desktop { let mut w_image = LAST_CAMERA_IMAGE.write(); *w_image = None; } - // Setup stop camera flag. let stop_camera = self.stop_camera.clone(); stop_camera.store(false, Ordering::Relaxed); - // Capture images at separate thread. - thread::spawn(move || { - Self::start_camera_capture(stop_camera); - }); + Self::start_camera_capture(self.cameras_amount.clone(), + self.camera_index.clone(), + stop_camera); } fn stop_camera(&self) { @@ -96,11 +219,20 @@ impl PlatformCallbacks for Desktop { } fn can_switch_camera(&self) -> bool { - false + let amount = self.cameras_amount.load(Ordering::Relaxed); + amount > 1 } fn switch_camera(&self) { - return; + self.stop_camera(); + let index = self.camera_index.load(Ordering::Relaxed); + let amount = self.cameras_amount.load(Ordering::Relaxed); + if index == amount - 1 { + self.camera_index.store(0, Ordering::Relaxed); + } else { + self.camera_index.store(index + 1, Ordering::Relaxed); + } + self.start_camera(); } fn share_data(&self, name: String, data: Vec) -> Result<(), std::io::Error> { @@ -171,53 +303,6 @@ impl PlatformCallbacks for Desktop { } } -impl Desktop { - pub fn new() -> Self { - Self { - stop_camera: Arc::new(AtomicBool::new(false)), - ctx: Arc::new(RwLock::new(None)), - attention_required: Arc::new(AtomicBool::new(false)), - } - } - - fn start_camera_capture(stop_camera: Arc) { - use nokhwa::Camera; - use nokhwa::pixel_format::RgbFormat; - use nokhwa::utils::{CameraIndex, RequestedFormat, RequestedFormatType}; - let index = CameraIndex::Index(0); - let requested = RequestedFormat::new::( - RequestedFormatType::AbsoluteHighestFrameRate - ); - // Create and open camera. - if let Ok(mut camera) = Camera::new(index, requested) { - if let Ok(_) = camera.open_stream() { - loop { - // Stop if camera was stopped. - if stop_camera.load(Ordering::Relaxed) { - stop_camera.store(false, Ordering::Relaxed); - // Clear image. - let mut w_image = LAST_CAMERA_IMAGE.write(); - *w_image = None; - break; - } - // Get a frame. - if let Ok(frame) = camera.frame() { - // Save image. - let mut w_image = LAST_CAMERA_IMAGE.write(); - *w_image = Some((frame.buffer().to_vec(), 0)); - } else { - // Clear image. - let mut w_image = LAST_CAMERA_IMAGE.write(); - *w_image = None; - break; - } - } - let _ = camera.stop_stream(); - }; - } - } -} - lazy_static! { /// Last captured image from started camera. static ref LAST_CAMERA_IMAGE: Arc, u32)>>> = Arc::new(RwLock::new(None)); diff --git a/src/gui/views/camera.rs b/src/gui/views/camera.rs index e4ed35a..24303e1 100644 --- a/src/gui/views/camera.rs +++ b/src/gui/views/camera.rs @@ -51,7 +51,7 @@ impl CameraContent { /// Draw camera content. pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) { ui.ctx().request_repaint(); - if let Some(img_data) = cb.camera_image() { + let rect = if let Some(img_data) = cb.camera_image() { if let Ok(img) = image::load_from_memory(&*img_data.0) { // Process image to find QR code. @@ -62,27 +62,28 @@ impl CameraContent { // Show UR scan progress. self.ur_progress_ui(ui); - - // Show button to switch cameras. - if cb.can_switch_camera() { - let r = { - let mut r = img_rect.clone(); - r.min.y = r.max.y - 52.0; - r.min.x = r.max.x - 52.0; - r - }; - ui.allocate_new_ui(UiBuilder::new().max_rect(r), |ui| { - let rotate_img = CAMERA_ROTATE.to_string(); - View::button(ui, rotate_img, Colors::white_or_black(false), || { - cb.switch_camera(); - }); - }); - } + img_rect } else { - self.loading_ui(ui); + self.loading_ui(ui) } } else { - self.loading_ui(ui); + self.loading_ui(ui) + }; + + // Show button to switch cameras. + if cb.can_switch_camera() { + let r = { + let mut r = rect.clone(); + r.min.y = r.max.y - 52.0; + r.min.x = r.max.x - 52.0; + r + }; + ui.allocate_new_ui(UiBuilder::new().max_rect(r), |ui| { + let rotate_img = CAMERA_ROTATE.to_string(); + View::button(ui, rotate_img, Colors::white_or_black(false), || { + cb.switch_camera(); + }); + }); } } @@ -148,13 +149,13 @@ impl CameraContent { } /// Draw camera loading progress content. - fn loading_ui(&self, ui: &mut egui::Ui) { + fn loading_ui(&self, ui: &mut egui::Ui) -> Rect { let space = (ui.available_width() - View::BIG_SPINNER_SIZE) / 2.0; ui.vertical_centered(|ui| { ui.add_space(space); View::big_loading_spinner(ui); ui.add_space(space); - }); + }).response.rect } /// Check if image is processing to find QR code.