基于MingGW64 GCC编译Windows平台上的 libuvc

2024-06-02 11:28

本文主要是介绍基于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。

 

这篇关于基于MingGW64 GCC编译Windows平台上的 libuvc的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1023836

相关文章

在Windows上使用qemu安装ubuntu24.04服务器的详细指南

《在Windows上使用qemu安装ubuntu24.04服务器的详细指南》本文介绍了在Windows上使用QEMU安装Ubuntu24.04的全流程:安装QEMU、准备ISO镜像、创建虚拟磁盘、配置... 目录1. 安装QEMU环境2. 准备Ubuntu 24.04镜像3. 启动QEMU安装Ubuntu4

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1

Windows的CMD窗口如何查看并杀死nginx进程

《Windows的CMD窗口如何查看并杀死nginx进程》:本文主要介绍Windows的CMD窗口如何查看并杀死nginx进程问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows的CMD窗口查看并杀死nginx进程开启nginx查看nginx进程停止nginx服务

Windows 系统下 Nginx 的配置步骤详解

《Windows系统下Nginx的配置步骤详解》Nginx是一款功能强大的软件,在互联网领域有广泛应用,简单来说,它就像一个聪明的交通指挥员,能让网站运行得更高效、更稳定,:本文主要介绍W... 目录一、为什么要用 Nginx二、Windows 系统下 Nginx 的配置步骤1. 下载 Nginx2. 解压

windows系统上如何进行maven安装和配置方式

《windows系统上如何进行maven安装和配置方式》:本文主要介绍windows系统上如何进行maven安装和配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录1. Maven 简介2. maven的下载与安装2.1 下载 Maven2.2 Maven安装2.

使用Python实现Windows系统垃圾清理

《使用Python实现Windows系统垃圾清理》Windows自带的磁盘清理工具功能有限,无法深度清理各类垃圾文件,所以本文为大家介绍了如何使用Python+PyQt5开发一个Windows系统垃圾... 目录一、开发背景与工具概述1.1 为什么需要专业清理工具1.2 工具设计理念二、工具核心功能解析2.

Windows Server 2025 搭建NPS-Radius服务器的步骤

《WindowsServer2025搭建NPS-Radius服务器的步骤》本文主要介绍了通过微软的NPS角色实现一个Radius服务器,身份验证和证书使用微软ADCS、ADDS,具有一定的参考价... 目录简介示意图什么是 802.1X?核心作用802.1X的组成角色工作流程简述802.1X常见应用802.

windows和Linux安装Jmeter与简单使用方式

《windows和Linux安装Jmeter与简单使用方式》:本文主要介绍windows和Linux安装Jmeter与简单使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows和linux安装Jmeter与简单使用一、下载安装包二、JDK安装1.windows设

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四