4. Platform Abstraction Layer¶
4.1 Platform Interfaces¶
Header: <duvc-ctl/platform/interface.h>
The platform abstraction layer decouples high-level camera APIs from platform-specific implementations. This allows supporting multiple camera APIs (DirectShow, V4L2, AVFoundation) through a common interface.
IPlatformInterface¶
class IPlatformInterface {
public:
virtual ~IPlatformInterface() = default;
virtual Result<std::vector<Device>> list_devices() = 0;
virtual Result<bool> is_device_connected(const Device& device) = 0;
virtual Result<std::unique_ptr<IDeviceConnection>> create_connection(const Device& device) = 0;
};
Abstract interface for platform-specific device enumeration and connection management.
Methods:
list_devices(): Enumerates all video input devices available on the system. Returns a vector of Device objects or an error if enumeration fails.
auto platform = duvc::create_platform_interface();
auto result = platform->list_devices();
if (result.is_ok()) {
for (const auto& dev : result.value()) {
std::wcout << dev.name << L"\n";
}
}
is_device_connected(const Device&): Checks if a specific device is currently connected and accessible. Returns boolean status or error.
Device my_camera = /* saved device */;
auto result = platform->is_device_connected(my_camera);
if (result.is_ok() && result.value()) {
// Device available
}
create_connection(const Device&): Creates a connection handle for interacting with a specific device. Returns an IDeviceConnection instance or error if connection fails.
auto conn_result = platform->create_connection(device);
if (conn_result.is_ok()) {
auto connection = std::move(conn_result.value());
// Use connection
}
IDeviceConnection¶
class IDeviceConnection {
public:
virtual ~IDeviceConnection() = default;
virtual bool is_valid() const = 0;
virtual Result<PropSetting> get_camera_property(CamProp prop) = 0;
virtual Result<void> set_camera_property(CamProp prop, const PropSetting& setting) = 0;
virtual Result<PropRange> get_camera_property_range(CamProp prop) = 0;
virtual Result<PropSetting> get_video_property(VidProp prop) = 0;
virtual Result<void> set_video_property(VidProp prop, const PropSetting& setting) = 0;
virtual Result<PropRange> get_video_property_range(VidProp prop) = 0;
};
Abstract interface for device-specific operations on an active connection.
Methods:
is_valid(): Returns true if the connection is active and usable. Check before performing operations.
if (connection->is_valid()) {
// Safe to use
}
Camera property operations:
get_camera_property(CamProp): Reads current value and mode for a camera control property (Pan, Tilt, Zoom, etc.).
set_camera_property(CamProp, PropSetting): Sets a new value and mode for a camera control property.
get_camera_property_range(CamProp): Queries the valid range, step, and defaults for a camera control property.
Video property operations:
get_video_property(VidProp): Reads current value and mode for a video processing property (Brightness, Contrast, etc.).
set_video_property(VidProp, PropSetting): Sets a new value and mode for a video processing property.
get_video_property_range(VidProp): Queries the valid range, step, and defaults for a video processing property.
Example usage:
auto conn = platform->create_connection(device).value();
// Get brightness
auto brightness = conn->get_video_property(VidProp::Brightness);
if (brightness.is_ok()) {
std::cout << "Brightness: " << brightness.value().value << "\n";
}
// Set zoom
PropSetting zoom_setting{100, CamMode::Manual};
conn->set_camera_property(CamProp::Zoom, zoom_setting);
// Query pan range
auto range = conn->get_camera_property_range(CamProp::Pan);
if (range.is_ok()) {
std::cout << "Pan: " << range.value().min << " to " << range.value().max << "\n";
}
Factory function¶
std::unique_ptr<IPlatformInterface> create_platform_interface();
Creates a platform-specific implementation of the interface. Returns appropriate backend based on compile-time platform detection.
Platform selection:
Windows: Returns
WindowsPlatformInterface(DirectShow-based implementation)Other platforms: Returns
nullptr(unsupported)
auto platform = duvc::create_platform_interface();
if (!platform) {
std::cerr << "Platform not supported\n";
return;
}
// Use platform interface
auto devices = platform->list_devices();
Implementation note: On Windows, the factory creates a WindowsPlatformInterface instance that internally uses DirectShow via DirectShowEnumerator and DirectShowDeviceConnection classes.
Windows DirectShow implementation¶
The Windows backend implementation wraps DirectShow COM interfaces:
WindowsPlatformInterface:
list_devices(): UsesDirectShowEnumerator::enumerate_devices()to queryCLSID_VideoInputDeviceCategoryis_device_connected(): UsesDirectShowEnumerator::is_device_available()to check device presencecreate_connection(): CreatesDirectShowDeviceConnectioninstance wrapping DirectShow filter
DirectShowDeviceConnection:
Manages
DirectShowFilterinstance holdingIBaseFilterCOM interfaceProperty operations query
IAMCameraControlandIAMVideoProcAmpinterfacesMaps
CamProp/VidPropenums to DirectShow constants viaDirectShowMapperConverts between
PropSetting/PropRangeand DirectShow values/flags
Error mapping:
COM failures →
ErrorCode::SystemErrorUnsupported properties →
ErrorCode::PropertyNotSupportedMissing interfaces →
ErrorCode::PropertyNotSupportedDevice not found →
ErrorCode::DeviceNotFound
Design rationale¶
Abstraction benefits:
High-level APIs (
Camera,list_devices()) remain platform-agnosticPlatform-specific code isolated to implementation classes
Future backends (V4L2, AVFoundation) implement same interfaces
Testing via mock implementations
Usage in library:
The Camera class internally uses IPlatformInterface via a global singleton. Direct use of platform interfaces is only needed for:
Custom platform backends
Low-level testing
Performance-critical batch operations
Normal applications use Camera class instead:
// Typical usage (recommended)
Camera cam(0);
cam.get(CamProp::Zoom);
// Platform interface usage (advanced)
auto platform = create_platform_interface();
auto conn = platform->create_connection(device).value();
conn->get_camera_property(CamProp::Zoom);