基于MingGW64 GCC編譯Windows平臺上的 libuvc

安裝cmake

打開cmake官網 https://cmake.org/download/,下載安裝包:

安裝時選擇將cmake加到系統環境變量里。安裝完成后在新的CMD命令窗口執行cmake --version可看到輸出:

D:\>cmake --version
cmake version 3.29.3
CMake suite maintained and supported by Kitware (kitware.com/cmake).

安裝Mingw64 GCC

Mingw目標是為支持Windows平臺上的GCC編譯,它主要提供頭文件和支持庫,Mingw自身不包括GCC和binutils,所以官網提供了集成這些組件的各種安裝包。列表里有Linux平臺的安裝包,那些是用來在Linux平臺生成Widows程序的。

https://www.mingw-w64.org/

這里我選擇了w64devkit,點擊后安裝鏈接指向了github:https://github.com/skeeto/w64devkit/releases ,下載w64devkit-1.23.0.zip。

解壓后放在C盤,將目錄 C:\w64devkit\bin\ 加入系統PATH環境變量。

然后新打開的CMD命令窗口輸入gcc –v 可以看到輸出:

D:\>gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=C:/w64devkit/bin/../libexec/gcc/x86_64-w64-mingw32/14.1.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: /gcc-14.1.0/configure --prefix=/w64devkit --with-sysroot=/w64devkit/x86_64-w64-mingw32 --with-native-system-header-dir=/include --target=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-static --disable-shared --with-pic --with-gmp-include=/deps/include --with-gmp-lib=/deps/lib --with-mpc-include=/deps/include --with-mpc-lib=/deps/lib --with-mpfr-include=/deps/include --with-mpfr-lib=/deps/lib --enable-languages=c,c++ --enable-libgomp --enable-threads=posix --enable-version-specific-runtime-libs --disable-dependency-tracking --disable-lto --disable-multilib --disable-nls --disable-win32-registry --enable-mingw-wildcard CFLAGS_FOR_TARGET=-Os CXXFLAGS_FOR_TARGET=-Os LDFLAGS_FOR_TARGET=-s CFLAGS=-Os CXXFLAGS=-Os LDFLAGS=-s
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 14.1.0 (GCC)

下載libusb

Libuvc依賴libusb,libusb是一個低級的通用訪問USB設備的用戶空間庫。我們直接下載官網已經編譯好的二進制庫。

https://libusb.info/

點擊圖中Latest Windows Binaries下載 https://github.com/libusb/libusb/releases/download/v1.0.27/libusb-1.0.27.7z 解壓后將 include\libusb.h, MinGW64下面的 .a 及 .dll 庫提取到一個目錄,如D:\libusb:

下載編譯libuvc

https://github.com/libuvc/libuvc

從官網以git clone下載源碼,源碼所放位置為D:\libuvc

由于cmake最小版本過低會產生如下告警:

CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required):Compatibility with CMake < 3.5 will be removed from a future version ofCMake.Update the VERSION argument <min> value or use a ...<max> suffix to tellCMake that the project does not need compatibility with older versions.

所以我們把libuvc/CmakeList.txt開頭的cmake最低版本改為3.10

如果直接執行cmake .. 會提示找不到libusb,打開D:\libuvc\CmakeLists.txt,刪除find_package(LibUSB)一行,替換為下面內容(目錄分隔符這里用的是 /, 如果用 \ 分隔,轉義的原因還要改為 \\):

# Locate the libusb-1.0 package manually if not found
#find_path(LIBUSB_INCLUDE_DIR NAMES libusb.h PATH_SUFFIXES libusb-1.0)
#find_library(LIBUSB_LIBRARY NAMES usb-1.0 libusb-1.0)
set(LIBUSB_INCLUDE_DIR D:/libusb)
set(LIBUSB_LIBRARY?? D:/libusb/libusb-1.0.dll? D:/libusb/libusb-1.0.dll.a)
#set(LIBUSB_LIBRARY? D:/libusb/libusb-1.0.a)?? # for static linkif(LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARY)set(LIBUSB_FOUND TRUE)
else()set(LIBUSB_FOUND FALSE)message(WARNING "LibUSB not found. Please install it.")
endif()

靜態鏈接用lbusb-1.0.a就注釋掉46行,打開47行, 這樣會更方便一點,不會產生找不到dll的問題。

然后在130行左右添加libusb.h頭文件目錄和鏈接庫,

打開CMD窗口,執行下面命令:

cd D:\libuvc
mkdir build install
cd build
rm –fr *;? #如果cmake有錯,重新執行時建議把目錄清空。
cmake -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=D:\libuvc\install -DBUILD_SHARED_LIBS=ON ?..

第一次執行cmake報錯, 系統會報病毒攔截,再執行一次上面的cmake ?命令即可。 不確定是誤報還是真有病毒。

CMake Error at C:/Program Files/CMake/share/cmake-3.29/Modules/CMakeDetermineCompilerId.cmake:922 (file):file STRINGS file "D:/libuvc/build/CMakeFiles/3.29.3/CompilerIdC/a.exe"cannot be read.

執行cmake成功后生成Makefie,接下來執行make命令進行編譯。編譯過程中會提示ARRAYSIZE重復定義的警告:

D:/libuvc/include/libuvc/libuvc_internal.h:75:9: warning: "ARRAYSIZE" redefined75 | #define ARRAYSIZE(arr) (sizeof(arr) / (IS_ARRAY(arr) ? sizeof(arr[0]) : 0))|???????? ^~~~~~~~~
In file included from C:/w64devkit/x86_64-w64-mingw32/include/minwindef.h:163,from C:/w64devkit/x86_64-w64-mingw32/include/windef.h:9,from C:/w64devkit/x86_64-w64-mingw32/include/windows.h:69,from D:/libusb/libusb.h:64,from D:/libuvc/include/libuvc/libuvc_internal.h:14:
C:/w64devkit/x86_64-w64-mingw32/include/winnt.h:681:
note: this is the location of the previous definition681 | #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

如果不想看到太多輸出警告信息,可以編輯D:\libuvc\include\libuvc\libuvc_internal.h, 在ARRAYSIZE外面加上#ifndef ARRAYSIZE 進行防御。

編譯成功:

D:\libuvc\build>make
[? 5%] Building C object CMakeFiles/uvc.dir/src/ctrl.c.obj
[ 10%] Building C object CMakeFiles/uvc.dir/src/ctrl-gen.c.obj
[ 15%] Building C object CMakeFiles/uvc.dir/src/device.c.obj
[ 20%] Building C object CMakeFiles/uvc.dir/src/diag.c.obj
[ 25%] Building C object CMakeFiles/uvc.dir/src/frame.c.obj
[ 30%] Building C object CMakeFiles/uvc.dir/src/init.c.obj
[ 35%] Building C object CMakeFiles/uvc.dir/src/stream.c.obj
[ 40%] Building C object CMakeFiles/uvc.dir/src/misc.c.obj
[ 45%] Linking C shared library libuvc.dll
[ 45%] Built target uvc
[ 50%] Building C object CMakeFiles/uvc_static.dir/src/ctrl.c.obj
[ 55%] Building C object CMakeFiles/uvc_static.dir/src/ctrl-gen.c.obj
[ 60%] Building C object CMakeFiles/uvc_static.dir/src/device.c.obj
[ 65%] Building C object CMakeFiles/uvc_static.dir/src/diag.c.obj
[ 70%] Building C object CMakeFiles/uvc_static.dir/src/frame.c.obj
[ 75%] Building C object CMakeFiles/uvc_static.dir/src/init.c.obj
[ 80%] Building C object CMakeFiles/uvc_static.dir/src/stream.c.obj
[ 85%] Building C object CMakeFiles/uvc_static.dir/src/misc.c.obj
[ 90%] Linking C static library libuvc.a
[ 90%] Built target uvc_static
[ 95%] Building C object CMakeFiles/example.dir/src/example.c.obj
[100%] Linking C executable example.exe
[100%] Built target example

然后安裝到install目錄,

D:\libuvc\build>make install
[ 45%] Built target uvc
[ 90%] Built target uvc_static
[100%] Built target example
Install the project...
-- Install configuration: "Release"
-- Installing: D:/libuvc/install/lib/libuvc.dll.a
-- Installing: D:/libuvc/install/bin/libuvc.dll
-- Installing: D:/libuvc/install/include/libuvc/libuvc.h
-- Installing: D:/libuvc/install/include/libuvc/libuvc_config.h
-- Installing: D:/libuvc/install/lib/libuvc.a
-- Up-to-date: D:/libuvc/install/include/libuvc/libuvc.h
-- Up-to-date: D:/libuvc/install/include/libuvc/libuvc_config.h
-- Installing: D:/libuvc/install/lib/cmake/libuvc/libuvcTargets.cmake
-- Installing: D:/libuvc/install/lib/cmake/libuvc/libuvcTargets-release.cmake
-- Installing: D:/libuvc/install/lib/cmake/libuvc/FindLibUSB.cmake
-- Installing: D:/libuvc/install/lib/cmake/libuvc/FindJpegPkg.cmake
-- Installing: D:/libuvc/install/lib/cmake/libuvc/libuvcConfigVersion.cmake
-- Installing: D:/libuvc/install/lib/pkgconfig/libuvc.pc
-- Installing: D:/libuvc/install/lib/cmake/libuvc/libuvcConfig.cmake

測試

以example.exe來進行測試。

首先利用USBDeview (https://usbdeview.me)工具找到電腦上外置UVC攝像頭的VID和PID。

然后打開D:\libuvc\src\example.c, 修改其中的VID和PID:

重新在build目錄執行make,然后執行example.exe, 會提示找不到libusb-1.0.dll,可以將D:\libusb-1.0.dll復制一份放在example.exe同一個目錄。 或者一勞永逸的復制到C:\Windows\System32下。 如果給別人發編譯好的程序,需要帶上libusb-1.0.dll。若前面Cmake配置靜態鏈接libusb則沒有此麻煩。

解決完dll問題后,example跑起來會報錯,找不到設備:

D:\libuvc\build>example.exe
UVC initialized
Device found
uvc_open: Not found (-5)
UVC exited

先用USBDeview查看驅動,此UVC設備使用了usbvideo驅動,需要安裝WinUSB驅動。

https://learn.microsoft.com/zh-cn/windows-hardware/drivers/usbcon/winusb-installation 面向開發人員的 WinUSB (Winusb.sys) 安裝 文檔中描述到:

對于某些通用串行總線 (USB) 設備(例如僅由單個應用程序訪問的設備),可以在設備的內核模式堆棧中安裝 WinUSB (Winusb.sys) 作為 USB 設備的功能驅動程序,而不是實現驅動程序。libusb正是此種場景。可以認為WinUSB.sys驅動是一種低層次的驅動,libusb要跟低層的驅動打交道,usbvideo.sys驅動是高層次的驅動。可以31按鏈接中微軟官方的指導安裝WinUSB驅動,也可以用Zadig來安裝此驅動。

從 https://zadig.akeo.ie下載Zadig。由于在此電腦上,USB Camera(Interface 0)是Video類型,USB Camera(Interface 2)是Audio類型, 所以在從Options菜單中選擇List All Devices后選擇USB Camera(Interface 0),換用WinUSB驅動。

安裝WinUSB驅動后用USBDeview查看:

example跑成功的日志:

D:\libuvc\build>example.exeUVC initialized
Device found
Device openedDEVICE CONFIGURATION (b349:b182/[none]) ---
Status: idle
VideoControl:bcdUVC: 0x0100VideoStreaming(1):bEndpointAddress: 129Formats:UncompressedFormat(1)bits per pixel: 16GUID: 5955593200001000800000aa00389b71 (YUY2)default frame: 1aspect ratio: 0x0interlace flags: 00copy protect: 00FrameDescriptor(1)capabilities: 01size: 1600x1200bit rate: 153600000-153600000max frame size: 3840000default interval: 1/5interval[0]: 1/5FrameDescriptor(2)capabilities: 01size: 1280x720bit rate: 110592000-110592000max frame size: 1843200default interval: 1/7interval[0]: 1/7FrameDescriptor(3)capabilities: 01size: 640x480bit rate: 147456000-147456000max frame size: 614400default interval: 1/30interval[0]: 1/30MJPEGFormat(2)bits per pixel: 0GUID: 4d4a5047000000000000000000000000 (MJPG)default frame: 1aspect ratio: 0x0interlace flags: 00copy protect: 00FrameDescriptor(1)capabilities: 01size: 1600x1200bit rate: 921600000-921600000max frame size: 3840000default interval: 1/30interval[0]: 1/30FrameDescriptor(2)capabilities: 01size: 1280x720bit rate: 442368000-442368000max frame size: 1843200default interval: 1/30interval[0]: 1/30FrameDescriptor(3)capabilities: 01size: 640x480bit rate: 147456000-147456000max frame size: 614400default interval: 1/30interval[0]: 1/30
END DEVICE CONFIGURATION
First format: (YUY2) 1600x1200 5fps
bmHint: 0001
bFormatIndex: 1
bFrameIndex: 1
dwFrameInterval: 2000000
wKeyFrameRate: 0
wPFrameRate: 0
wCompQuality: 61
wCompWindowSize: 0
wDelay: 0
dwMaxVideoFrameSize: 3840000
dwMaxPayloadTransferSize: 3060
bInterfaceNumber: 1
Streaming...
Enabling auto exposure ...... full AE not supported, trying aperture priority mode... enabled aperture priority auto exposure mode
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
callback! frame_format = 3, width = 1600, height = 1200, length = 3840000, ptr = 0000000000003039
Done streaming.
Device closed
UVC exited

恢復驅動

安裝過WinUSB驅動的UVC設備,不會出現在設備管理器的照像機下面。 如果要恢復正常的UVC Camera功能,可以在設備管理器中卸載此設備的驅動。

??

卸載驅動后在設備管理器中右擊鼠標,掃描檢測硬件改動,USB Camera可以自動識別出來。驅動也恢復為原來的usbvideo.sys。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/20869.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/20869.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/20869.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

牛客網刷題 | BC108 反斜線形圖案

目前主要分為三個專欄&#xff0c;后續還會添加&#xff1a; 專欄如下&#xff1a; C語言刷題解析 C語言系列文章 我的成長經歷 感謝閱讀&#xff01; 初來乍到&#xff0c;如有錯誤請指出&#xff0c;感謝&#xff01; 描述 KiKi學習了循環&am…

社交媒體數據恢復:Voxer

一、Voxer數據恢復教程 了解Voxer應用 Voxer是一款專門為iPhone和Android智能手機設計的免費對講機應用&#xff0c;為用戶提供即時的語音、文本、照片等信息發送和接收服務。該應用有點類似短信服務&#xff0c;但用聲音代替文本。當你下載之后&#xff0c;如果不邀請朋友&a…

Github查詢語法

轉載自link 基礎查詢結構 一個關鍵詞會匹配文件內容或文件路徑。 多個關鍵詞會匹配文件內容&#xff0c;只要包含關鍵詞&#xff0c;就會出現在搜索結果中&#xff0c;不論前后順序&#xff0c;是否是一個單詞&#xff08;多個關鍵詞之間沒有空格&#xff09;。 還可以使用…

Java中的JVM是什么?簡要說明其工作原理

Java虛擬機&#xff08;JVM&#xff09;概述 Java虛擬機&#xff08;Java Virtual Machine&#xff0c;JVM&#xff09;是Java技術的核心部分。它是一個抽象的計算機&#xff0c;可以解釋和執行Java字節碼。JVM提供了一個運行Java程序的環境&#xff0c;使得Java程序可以在各種…

【面試】字節碼文件是跨平臺的嗎?

目錄 1. 說明 1. 說明 1.字節碼文件&#xff08;.class文件&#xff09;是跨平臺的。2.字節碼文件是Java源代碼經過Java編譯器&#xff08;javac&#xff09;編譯后生成的中間代碼文件&#xff0c;這些包含了Java虛擬機&#xff08;JVM&#xff09;指令&#xff0c;而不是特定…

重復文件怎么查找并清理?電腦重復文件清理工具分享:4個

在日常使用電腦的過程中&#xff0c;我們不可避免地會遇到各種重復文件的問題。這些重復文件不僅占據了寶貴的存儲空間&#xff0c;還可能導致系統性能下降&#xff0c;甚至引發一些不必要的問題。因此&#xff0c;如何有效地查找并清理這些重復文件成為了許多用戶關注的焦點。…

計算 x 的二進制表示中 1 的個數

計算 x 的二進制表示中 1 的個數 代碼如下&#xff1a; int func(int x){int countx 0;while (x>0){countx;x x & (x - 1);}return countx;} 完整代碼&#xff1a; using System; using System.Collections.Generic; using System.ComponentModel; using System.Dat…

STM32基于HAL庫的HC-SR04模塊超聲波測距

文章目錄 一、HC-SR04模塊介紹二、創建工程1.選擇芯片2.配置RCC、SY![在這里插入圖片描述](https://img-blog.csdnimg.cn/direct/9d2a5b883f0e409eabb804e6da861277.png)3.配置串口14.配置定時器5.配置GPIO 三、Keil代碼1.勾選Use MicroLIB2.創建SR04.c和SR04.h文件3.其他代碼 …

html three.js 引入.stl模型示例

1.新建一個模塊用于放置模型 <div id"chart_map" style"width:800px;height:500px"></div> 2. 引入代碼根據需求更改 <!-- 在head或body標簽內加入以下鏈接 --> <script src"https://cdn.jsdelivr.net/npm/three0.137/build/t…

算法題-字符串排序

題目描述 給定n個字符串&#xff0c;請對n個字符串按照字典序排列。 輸入描述: 輸入第一行為一個正整數n(1≤n≤1000),下面n行為n個字符串(字符串長度≤100),字符串中只含有大小寫字母。 輸出描述: 數據輸出n行&#xff0c;輸出結果為按照字典序排列的字符串。 輸入 #輸…

2.7HDR與LDR

一、基本概念 1.基本概念 動態范圍&#xff08;Dynamic Range&#xff09; 最高亮度 / 最低亮度 HDR High Dynamic RangeLDR Low Dynamic Range HDR與LDR和Tonemapping的對應關系&#xff1a; 我們常用的各種顯示器屏幕&#xff0c;由于不同的廠家不同的工藝導致它們的…

HALCON-從入門到入門-軟件界面介紹

1.廢話 從halcon12到halcon23&#xff0c;開發的IDE界面大差不差&#xff0c;簡單說下界面上不同功能按鍵的分布&#xff0c;以及一些快捷鍵啥的&#xff0c;要是還有我沒有總結到的&#xff0c;又比較好用的&#xff0c;歡迎大家補充一下。 1.菜單欄 從上看到下&#xff0c;…

如何從0到設計一個CRM系統

什么是CRM 設計開始之前&#xff0c;先來了解一下什么是CRM。CRM&#xff08;Customer Relationship Management&#xff09;是指通過建立和維護與客戶的良好關系&#xff0c;達到滿足客戶需求、提高客戶滿意度、增加業務收入的一種管理方法和策略。CRM涉及到跟蹤和管理客戶的所…

python深度學習入門-從零構建CNN和RNN

文章目錄 第1章 基本概念1.1. 導數1.2. 鏈式法則1.3. 多輸入函數的導數1.4. 多輸入向量函數的導數1.5. 向量函數及其導數&#xff1a; 再進一步1.6. 包含兩個二維矩陣數據的計算圖 第2章 基本原理2.1. 監督學習概述2.2. 監督學習模型2.3. 線性回歸2.3.1. 線性回歸&#xff1a; …

[激光原理與應用-94]:電控 - 低噪聲運放的原理

目錄 一、什么是低噪聲運放 1.1 什么是低噪聲水平 1.2 什么是高增益 在電子工程中的應用 在通信領域的應用 在音頻和視頻處理中的應用 注意事項 1.3 什么是寬帶寬 1.4 什么是低偏置電流 重要性 特點 解決方法 應用 二、低噪聲運放的原理圖 1. 基本構成 2. 設計…

HTML5新元素探索:重塑網頁結構與功能的革新

隨著互聯網技術的飛速發展&#xff0c;HTML5作為新一代超文本標記語言標準&#xff0c;不僅增強了對多媒體內容的支持&#xff0c;還引入了一系列新元素&#xff0c;旨在使網頁結構更加語義化、可訪問性更強。本文將深入探討幾個核心的新元素&#xff0c;通過代碼示例展示它們如…

22data 腳本語言基礎——Python

橫線為沒講到的。 1. 基礎語法 變量&#xff1a;變量的聲明和使用。 數據類型&#xff1a;整數&#xff08;int&#xff09;、浮點數&#xff08;float&#xff09;、字符串&#xff08;str&#xff09;、布爾值&#xff08;bool&#xff09;等。 運算符&#xff1a;算術運算符…

第五維度【百度之星】/二分

第五維度 二分 思路&#xff1a;看到題目是盡可能晚的情況下最早就應該想到貪心。 #include<bits/stdc.h> using namespace std; typedef long long ll; ll a[100005],b[100005]; ll n,m; bool check(ll t) {ll res0,big0;for(ll i0;i<n;i) {if(a[i]>t) continue…

JMeter工具介紹

Jmeter功能概要 JDK常用文件目錄介紹 Bin目錄&#xff1a;存放可執行文件和配置文件 Docs目錄&#xff1a;是Jmeter的API文檔&#xff0c;用于開發擴展組件 printable_docs目錄&#xff1a;用戶幫助手冊 lib目錄&#xff1a;存放JMeter依賴的jar包和用戶擴展所依賴的Jar包 修…

HALCON-從入門到入門-讀取圖片保存圖片

1.廢話 視覺算法庫的第一步。 讀取圖片&#xff1a; 看你是從哪里讀取&#xff0c;從相機讀取還是從本地硬盤中讀取。 保存圖片&#xff1a;就只有保存到本地了。 上面的截圖顯示我讀取了一張圖片 從相機中讀取另開一篇來說&#xff0c;先說從本地磁盤讀取哈。 怎么讀取的…