Skip to content

Commit e1b9f46

Browse files
committed
feat(windows): add CCAP_WIN_NO_DEVICE_VERIFY option to skip device verification
- Add CMake option to skip device verification during enumeration on Windows - Prevents crashes from buggy camera drivers (e.g., Oculus Quest 3 when unplugged) - Modifies findDeviceNames() to conditionally skip BindToObject() call - Device properties are still verified via enumerateDevices() - Affects issue #26 Files changed: - CMakeLists.txt: Add CCAP_WIN_NO_DEVICE_VERIFY option with PRIVATE scope - ccap_config.h: Add documentation for the new option - ccap_imp_windows.cpp: Conditional compilation to skip filter instantiation - docs/CMAKE_OPTIONS.md: Comprehensive documentation of all CMake options
1 parent 1d4e51f commit e1b9f46

3 files changed

Lines changed: 151 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ endif()
88

99
option(CCAP_NO_LOG "Disable logging" OFF)
1010
option(CCAP_BUILD_SHARED "Build ccap as shared library" OFF)
11+
option(CCAP_WIN_NO_DEVICE_VERIFY "Skip device verification on Windows (for buggy camera drivers)" OFF)
1112

1213
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
1314
set(CCAP_IS_ROOT_PROJECT ON)
@@ -171,6 +172,11 @@ if(CCAP_NO_LOG)
171172
message(STATUS "ccap: Disable logging")
172173
endif()
173174

175+
if(CCAP_WIN_NO_DEVICE_VERIFY)
176+
target_compile_definitions(ccap PRIVATE CCAP_WIN_NO_DEVICE_VERIFY=1)
177+
message(STATUS "ccap: Skip device verification on Windows (for buggy camera drivers)")
178+
endif()
179+
174180
# Configure shared library export definitions
175181
if(CCAP_BUILD_SHARED)
176182
target_compile_definitions(ccap PUBLIC CCAP_SHARED=1)

docs/CMAKE_OPTIONS.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# CMake Build Options
2+
3+
This document describes all available CMake options for building the ccap (Camera Capture) library.
4+
5+
## General Options
6+
7+
### CCAP_NO_LOG
8+
- **Description**: Disable logging throughout the library
9+
- **Type**: Boolean (ON/OFF)
10+
- **Default**: OFF
11+
- **Example**: `-DCCAP_NO_LOG=ON`
12+
- **Notes**: When enabled, all logging macros (CCAP_LOG_*) are disabled, reducing binary size and improving performance
13+
14+
### CCAP_BUILD_SHARED
15+
- **Description**: Build ccap as a shared library instead of static
16+
- **Type**: Boolean (ON/OFF)
17+
- **Default**: OFF
18+
- **Example**: `-DCCAP_BUILD_SHARED=ON`
19+
- **Notes**: When enabled, the library is built as a shared library (.dll on Windows, .so on Linux, .dylib on macOS)
20+
21+
### CCAP_INSTALL
22+
- **Description**: Generate installation target for the library
23+
- **Type**: Boolean (ON/OFF)
24+
- **Default**: ON (if ccap is the root project), OFF (if used as a subdirectory)
25+
- **Example**: `-DCCAP_INSTALL=ON`
26+
- **Notes**: When enabled, allows installation of headers, library, and CMake config files via `cmake --install`
27+
28+
## Windows-Specific Options
29+
30+
### CCAP_WIN_NO_DEVICE_VERIFY
31+
- **Description**: Skip device verification during enumeration on Windows
32+
- **Type**: Boolean (ON/OFF)
33+
- **Default**: OFF
34+
- **Example**: `-DCCAP_WIN_NO_DEVICE_VERIFY=ON`
35+
- **Purpose**: Prevents crashes caused by buggy camera drivers (e.g., Oculus Quest 3 VR headset when unplugged) that fail during `IMoniker::BindToObject()` or `filter->Release()` calls
36+
- **Notes**:
37+
- Only affects Windows platform
38+
- When enabled, device names are added without instantiating filters
39+
- Device properties are still verified via `enumerateDevices()`
40+
- Safe to enable for compatibility with problematic drivers
41+
- Related to issue #26
42+
43+
## Build Configuration Options
44+
45+
### CCAP_BUILD_EXAMPLES
46+
- **Description**: Build example programs
47+
- **Type**: Boolean (ON/OFF)
48+
- **Default**: ON (if ccap is the root project), OFF (if used as a subdirectory)
49+
- **Example**: `-DCCAP_BUILD_EXAMPLES=ON`
50+
- **Notes**: Includes desktop examples with GLFW for visualization
51+
52+
### CCAP_BUILD_TESTS
53+
- **Description**: Build unit tests
54+
- **Type**: Boolean (ON/OFF)
55+
- **Default**: OFF
56+
- **Example**: `-DCCAP_BUILD_TESTS=ON`
57+
- **Notes**: Requires GoogleTest framework; enables `enable_testing()` and CTest integration
58+
59+
## Architecture Options
60+
61+
### CCAP_FORCE_ARM64
62+
- **Description**: Force ARM64 architecture compilation
63+
- **Type**: Boolean (ON/OFF)
64+
- **Default**: OFF
65+
- **Example**: `-DCCAP_FORCE_ARM64=ON`
66+
- **Platforms**: macOS, Windows
67+
- **Notes**:
68+
- On macOS: Sets `CMAKE_OSX_ARCHITECTURES` to "arm64"
69+
- On Windows: Sets `CMAKE_GENERATOR_PLATFORM` to "ARM64"
70+
- Enables NEON support on ARM64
71+
- Useful for cross-compilation or universal binary generation
72+
73+
## Usage Examples
74+
75+
### Build with default settings (static library)
76+
```bash
77+
cmake -B build
78+
cmake --build build
79+
```
80+
81+
### Build as shared library
82+
```bash
83+
cmake -B build -DCCAP_BUILD_SHARED=ON
84+
cmake --build build
85+
```
86+
87+
### Build with examples and tests
88+
```bash
89+
cmake -B build -DCCAP_BUILD_EXAMPLES=ON -DCCAP_BUILD_TESTS=ON
90+
cmake --build build
91+
```
92+
93+
### Build with Windows device verification disabled
94+
```bash
95+
cmake -B build -DCCAP_WIN_NO_DEVICE_VERIFY=ON
96+
cmake --build build
97+
```
98+
99+
### Build for ARM64 with all features disabled
100+
```bash
101+
cmake -B build -DCCAP_FORCE_ARM64=ON -DCCAP_NO_LOG=ON
102+
cmake --build build
103+
```
104+
105+
### Install the library
106+
```bash
107+
cmake -B build -DCCAP_INSTALL=ON
108+
cmake --build build
109+
cmake --install build --prefix /usr/local
110+
```
111+
112+
## Related CMake Variables
113+
114+
The following CMake variables can also be used to customize the build:
115+
116+
- `CMAKE_BUILD_TYPE`: Set to Debug, Release, RelWithDebInfo, or MinSizeRel
117+
- `CMAKE_OSX_DEPLOYMENT_TARGET`: Minimum macOS version (default: 10.13)
118+
- `CMAKE_CXX_STANDARD`: C++ standard version (fixed to 17 by ccap)
119+
120+
## Platform-Specific Notes
121+
122+
### Windows
123+
- When `CCAP_WIN_NO_DEVICE_VERIFY` is enabled, the library skips filter instantiation during device enumeration
124+
- MSVC is the primary compiler; MinGW and Clang are also supported
125+
126+
### macOS
127+
- Requires framework linking for AVFoundation, CoreVideo, CoreMedia, and Accelerate
128+
- ARM64 support is fully integrated
129+
130+
### Linux
131+
- Requires pthread library for thread support
132+
- Standard V4L2 device access
133+
134+
## Related Files
135+
136+
- `CMakeLists.txt` - Main build configuration
137+
- `src/ccap_imp_windows.cpp` - Windows implementation (affected by CCAP_WIN_NO_DEVICE_VERIFY)
138+
- `include/ccap_config.h` - Configuration macros

src/ccap_imp_windows.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,12 @@ std::vector<std::string> ProviderDirectShow::findDeviceNames() {
399399
}
400400

401401
enumerateDevices([&](IMoniker* moniker, std::string_view name) {
402+
#ifdef CCAP_WIN_NO_DEVICE_VERIFY
403+
// Skip device verification to avoid crashes from buggy camera drivers
404+
// Device properties are already verified in enumerateDevices()
405+
m_allDeviceNames.emplace_back(name.data(), name.size());
406+
CCAP_LOG_I("ccap: \"%s\" added without verification (CCAP_WIN_NO_DEVICE_VERIFY enabled)\n", name.data());
407+
#else
402408
// Try to bind device, check if available
403409
IBaseFilter* filter = nullptr;
404410
HRESULT hr = moniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&filter);
@@ -408,6 +414,7 @@ std::vector<std::string> ProviderDirectShow::findDeviceNames() {
408414
} else {
409415
CCAP_LOG_I("ccap: \"%s\" is not a valid video capture device, removed\n", name.data());
410416
}
417+
#endif
411418
// Unavailable devices are not added to the list
412419
return false; // Continue enumeration
413420
});

0 commit comments

Comments
 (0)