duvc-ctl 2.0.0
USB Video Class Camera Control Library
Loading...
Searching...
No Matches
capability.cpp
Go to the documentation of this file.
1
10
13
14namespace duvc {
15
16// Static empty capability for unsupported properties
17const PropertyCapability DeviceCapabilities::empty_capability_ = {};
18
20 : device_(device), device_accessible_(false) {
21 device_accessible_ = is_device_connected(device_);
22 if (device_accessible_) {
23 scan_capabilities();
24 }
25}
26
27void DeviceCapabilities::scan_capabilities() {
28 camera_capabilities_.clear();
29 video_capabilities_.clear();
30
31 // Create camera instance for property access
32 Camera camera(device_);
33 if (!camera.is_valid()) {
34 DUVC_LOG_WARNING("Device not accessible during capability scan");
35 device_accessible_ = false;
36 return;
37 }
38
39 // Scan all camera properties
40 for (int i = 0; i <= static_cast<int>(CamProp::Lamp); ++i) {
41 CamProp prop = static_cast<CamProp>(i);
42 PropertyCapability capability;
43
44 // Try to get range - if successful, property is supported
45 auto range_result = camera.get_range(prop);
46 if (range_result.is_ok()) {
47 capability.supported = true;
48 capability.range = range_result.value();
49
50 // Try to get current value
51 auto current_result = camera.get(prop);
52 if (current_result.is_ok()) {
53 capability.current = current_result.value();
54 } else {
55 DUVC_LOG_WARNING("Failed to get current camera property value for " +
56 std::string(to_string(prop)));
57 }
58
59 camera_capabilities_[prop] = capability;
60 }
61 }
62
63 // Scan all video properties
64 for (int i = 0; i <= static_cast<int>(VidProp::Gain); ++i) {
65 VidProp prop = static_cast<VidProp>(i);
66 PropertyCapability capability;
67
68 // Try to get range - if successful, property is supported
69 auto range_result = camera.get_range(prop);
70 if (range_result.is_ok()) {
71 capability.supported = true;
72 capability.range = range_result.value();
73
74 // Try to get current value
75 auto current_result = camera.get(prop);
76 if (current_result.is_ok()) {
77 capability.current = current_result.value();
78 } else {
79 DUVC_LOG_WARNING("Failed to get current video property value for " +
80 std::string(to_string(prop)));
81 }
82
83 video_capabilities_[prop] = capability;
84 }
85 }
86}
87
88const PropertyCapability &
90 auto it = camera_capabilities_.find(prop);
91 return it != camera_capabilities_.end() ? it->second : empty_capability_;
92}
93
96 auto it = video_capabilities_.find(prop);
97 return it != video_capabilities_.end() ? it->second : empty_capability_;
98}
99
103
107
109 std::vector<CamProp> props;
110 for (const auto &pair : camera_capabilities_) {
111 if (pair.second.supported) {
112 props.push_back(pair.first);
113 }
114 }
115 return props;
116}
117
119 std::vector<VidProp> props;
120 for (const auto &pair : video_capabilities_) {
121 if (pair.second.supported) {
122 props.push_back(pair.first);
123 }
124 }
125 return props;
126}
127
129 device_accessible_ = is_device_connected(device_);
130 if (!device_accessible_) {
131 return Err<void>(ErrorCode::DeviceNotFound, "Device not connected");
132 }
133
134 camera_capabilities_.clear();
135 video_capabilities_.clear();
136 scan_capabilities();
137 return Ok();
138}
139
141 // Defensive validation: check if device strings are accessible
142 // This prevents crashes from corrupted Device objects passed from Python
143 try {
144 // Validate device before use
145 if (!device.is_valid()) {
146 return Err<DeviceCapabilities>(ErrorCode::InvalidArgument, "Invalid device");
147 }
148
149 // Force access to string internals to catch corruption early
150 // If strings are corrupted (e.g., from bad pybind11 copy), this will throw
151 const auto* name_ptr = device.name.data();
152 const auto* path_ptr = device.path.data();
153 size_t name_len = device.name.size();
154 size_t path_len = device.path.size();
155
156 // Validate pointers are not null if strings are non-empty
157 if ((name_len > 0 && !name_ptr) || (path_len > 0 && !path_ptr)) {
159 "Device has corrupted string data (null pointer with non-zero size)");
160 }
161
162 // Validate we can actually read the strings without crashing
163 // This will fault if the internal string buffer pointer is invalid
164 if (!device.name.empty()) {
165 [[maybe_unused]] volatile wchar_t first_char = device.name[0];
166 }
167 if (!device.path.empty()) {
168 [[maybe_unused]] volatile wchar_t first_char = device.path[0];
169 }
170
171 } catch (const std::exception& e) {
173 std::string("Device object has corrupted memory: ") + e.what());
174 } catch (...) {
176 "Device object has corrupted memory (unknown exception)");
177 }
178
179 // Device validation passed - safe to proceed
180 DeviceCapabilities capabilities(device);
181 if (!capabilities.is_device_accessible()) {
182 return Err<DeviceCapabilities>(ErrorCode::DeviceNotFound, "Device not accessible");
183 }
184
185 return Ok(std::move(capabilities));
186}
187
196
197} // namespace duvc
#define DUVC_LOG_WARNING(msg)
Definition api.h:1076
RAII camera handle for simplified device management.
Device capability detection and snapshots using Camera API.
RAII camera handle for simplified device management.
Definition camera.h:23
Complete device capability snapshot.
Definition capability.h:35
const PropertyCapability & get_video_capability(VidProp prop) const
Get video property capability.
DeviceCapabilities(const Device &device)
Create capabilities snapshot for device.
std::vector< CamProp > supported_camera_properties() const
Get list of supported camera properties.
bool supports_video_property(VidProp prop) const
Check if video property is supported.
Result< void > refresh()
Refresh capability snapshot.
bool supports_camera_property(CamProp prop) const
Check if camera property is supported.
std::vector< VidProp > supported_video_properties() const
Get list of supported video properties.
const PropertyCapability & get_camera_capability(CamProp prop) const
Get camera property capability.
bool is_device_accessible() const
Check if device is connected and accessible.
Definition capability.h:93
Result type that can contain either a value or an error.
Definition result.h:75
const T & value() const &
Get the value (assumes success)
Definition result.h:114
Device enumeration and management functions.
Structured logging interface for duvc-ctl.
Definition core.h:13
VidProp
Video processing properties (IAMVideoProcAmp interface)
Definition types.h:50
@ Gain
Sensor gain level.
@ InvalidArgument
Invalid function argument.
@ DeviceNotFound
Device not found or disconnected.
Result< DeviceCapabilities > get_device_capabilities(const Device &device)
Create device capability snapshot.
std::vector< Device > list_devices()
Enumerate all available video input devices.
Definition core.cpp:626
const char * to_string(CamProp)
Convert camera property enum to string.
Definition core.cpp:678
CamProp
Camera control properties (IAMCameraControl interface)
Definition types.h:18
@ Lamp
Camera lamp/flash control.
bool is_device_connected(const Device &dev)
Check if a device is currently connected and accessible.
Definition core.cpp:549
Result< void > Ok()
Helper to create successful void Result.
Definition result.h:222
Result/Error type system for duvc-ctl.
String conversion utilities for enums and types.
Represents a camera device.
Definition types.h:131
std::wstring path
Unique device path/identifier.
Definition types.h:133
std::wstring name
Human-readable device name.
Definition types.h:132
bool is_valid() const
Check if device has valid identifying information.
Definition types.h:186
Property capability information.
Definition capability.h:20