Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/build-and-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,25 @@ jobs:
}
'linux-x64' {
Copy-Item -Force './CollimationCircles/Libraries/ASI_linux_mac_SDK_V1.41/lib/x64/libASICamera2.so*' $output
# Copy libuvc for UVC camera control and streaming via libuvc on Linux
Copy-Item -Force './CollimationCircles/Libraries/libuvc/linux/x64/libuvc.so' $output

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bundle libusb with Linux libuvc artifacts

For the Linux release artifacts this copies only libuvc.so, but the checked-in Linux libuvc.so has a dynamic NEEDED dependency on libusb-1.0.so.0 (I verified with readelf -d, and ldd reports it as not found in this environment). On systems without a system libusb package, the first DllImport("libuvc") will fail before any UVC camera can open, so the self-contained Linux builds won't actually provide the new UVC path unless libusb is packaged or libuvc is linked statically.

Useful? React with 👍 / 👎.

}
'linux-arm64' {
Copy-Item -Force './CollimationCircles/Libraries/ASI_linux_mac_SDK_V1.41/lib/armv8/libASICamera2.so*' $output
# Copy libuvc for UVC camera control and streaming via libuvc on Linux
Copy-Item -Force './CollimationCircles/Libraries/libuvc/linux/arm64/libuvc.so' $output
}
'win-x64' {
Copy-Item -Force './CollimationCircles/Libraries/ASI_Windows_SDK_V1.41/lib/x64/ASICamera2.dll' $output
# Copy libusb + libuvc for UVC camera control and streaming on Windows
Copy-Item -Force './CollimationCircles/Libraries/libusb/win/x64/libusb-1.0.dll' $output
Copy-Item -Force './CollimationCircles/Libraries/libuvc/win/x64/libuvc.dll' $output
}
'win-arm64' {
Write-Warning 'No ZWO ASI Windows arm64 binary is shipped in the SDK; skipping native library copy.'
# Copy libusb + libuvc for UVC camera control and streaming on Windows
Copy-Item -Force './CollimationCircles/Libraries/libusb/win/arm64/libusb-1.0.dll' $output
Copy-Item -Force './CollimationCircles/Libraries/libuvc/win/arm64/libuvc.dll' $output
}
}

Expand Down
48 changes: 48 additions & 0 deletions CollimationCircles/CollimationCircles.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,54 @@
<Message Text="Ad-hoc signed libusb and libuvc dylibs" Importance="high" />
</Target>

<!-- Linux: Copy libuvc shared library for UVC camera control + streaming via libuvc -->
<Target Name="CopyLibUvcLinuxX64" AfterTargets="Build" Condition="'$(RuntimeIdentifier)' == 'linux-x64'">
<ItemGroup>
<LibUvcFiles Include="Libraries\libuvc\linux\x64\libuvc.so" />
</ItemGroup>
<Copy SourceFiles="@(LibUvcFiles)" DestinationFolder="$(OutputPath)" />
<Message Text="Copied libuvc.so (linux-x64) to $(OutputPath)" Importance="high" />
</Target>
<Target Name="CopyLibUvcLinuxArm64" AfterTargets="Build" Condition="'$(RuntimeIdentifier)' == 'linux-arm64'">
<ItemGroup>
<LibUvcFiles Include="Libraries\libuvc\linux\arm64\libuvc.so" />
</ItemGroup>
<Copy SourceFiles="@(LibUvcFiles)" DestinationFolder="$(OutputPath)" />
<Message Text="Copied libuvc.so (linux-arm64) to $(OutputPath)" Importance="high" />
</Target>

<!-- Windows: Copy libusb-1.0.dll for UVC camera control via libuvc -->
<Target Name="CopyLibUsbWinX64" AfterTargets="Build" Condition="'$(RuntimeIdentifier)' == 'win-x64'">
<ItemGroup>
<LibUsbFiles Include="Libraries\libusb\win\x64\libusb-1.0.dll" />
</ItemGroup>
<Copy SourceFiles="@(LibUsbFiles)" DestinationFolder="$(OutputPath)" />
<Message Text="Copied libusb-1.0.dll (win-x64) to $(OutputPath)" Importance="high" />
</Target>
<Target Name="CopyLibUsbWinArm64" AfterTargets="Build" Condition="'$(RuntimeIdentifier)' == 'win-arm64'">
<ItemGroup>
<LibUsbFiles Include="Libraries\libusb\win\arm64\libusb-1.0.dll" />
</ItemGroup>
<Copy SourceFiles="@(LibUsbFiles)" DestinationFolder="$(OutputPath)" />
<Message Text="Copied libusb-1.0.dll (win-arm64) to $(OutputPath)" Importance="high" />
</Target>

<!-- Windows: Copy libuvc.dll for UVC camera control + streaming via libuvc -->
<Target Name="CopyLibUvcWinX64" AfterTargets="Build" Condition="'$(RuntimeIdentifier)' == 'win-x64'">
<ItemGroup>
<LibUvcFiles Include="Libraries\libuvc\win\x64\libuvc.dll" />
</ItemGroup>
<Copy SourceFiles="@(LibUvcFiles)" DestinationFolder="$(OutputPath)" />
<Message Text="Copied libuvc.dll (win-x64) to $(OutputPath)" Importance="high" />
</Target>
<Target Name="CopyLibUvcWinArm64" AfterTargets="Build" Condition="'$(RuntimeIdentifier)' == 'win-arm64'">
<ItemGroup>
<LibUvcFiles Include="Libraries\libuvc\win\arm64\libuvc.dll" />
</ItemGroup>
<Copy SourceFiles="@(LibUvcFiles)" DestinationFolder="$(OutputPath)" />
<Message Text="Copied libuvc.dll (win-arm64) to $(OutputPath)" Importance="high" />
</Target>

<ItemGroup Condition="$([MSBuild]::IsOSPlatform('Windows'))">
<Content Include="Libraries\libvlc\**\*.*">
<Link>libvlc\%(RecursiveDir)%(Filename)%(Extension)</Link>
Expand Down
48 changes: 48 additions & 0 deletions CollimationCircles/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace CollimationCircles
{
Expand Down Expand Up @@ -48,6 +49,12 @@ public static void Main(string[] args)

try
{
if (StartupOptions.DebugUvc)
{
RunUvcDebug().Wait();
return;
}

if (StartupOptions.RecoverUvcVidPid is { } recoverVidPid)
{
bool recovered = UvcFrameSource.TryRecoverUvcDevice(recoverVidPid.VendorId, recoverVidPid.ProductId);
Expand Down Expand Up @@ -101,6 +108,47 @@ private static void InstallLinuxCrashHandler()
}
}

private static async Task RunUvcDebug()
{
logger.Info("=== UVC Camera Detection Debug Mode ===");
logger.Info($"Operating System: Windows");

try
{
logger.Info("Initiating UVC camera detection...");
var detector = new UvcCameraDetectWindows();
var cameras = await detector.GetCameras();

logger.Info($"\n========================================");
logger.Info($"DETECTION COMPLETE");
logger.Info($"Total UVC cameras found: {cameras.Count}");
logger.Info($"========================================");

if (cameras.Count > 0)
{
logger.Info("Cameras detected:");
foreach (var camera in cameras)
{
logger.Info($"\n Camera {camera.Index}:");
logger.Info($" Name: {camera.Name}");
logger.Info($" VendorID: 0x{camera.VendorId:X4}");
logger.Info($" ProductID: 0x{camera.ProductId:X4}");
logger.Info($" Path: {camera.Path}");
logger.Info($" APIType: {camera.APIType}");
}
}
else
{
logger.Warn("No UVC cameras were detected.");
logger.Info("Check the debug output above for details on why devices were filtered.");
}
}
catch (Exception ex)
{
logger.Fatal(ex, "Error during UVC camera detection");
}
}

private static void BootstrapMacArm64VlcEnvironment(string[] args)
{
if (!IsMacArm64)
Expand Down
24 changes: 24 additions & 0 deletions CollimationCircles/Services/CameraControlService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ public void Set(ControlType controlName, double value, Camera camera)
{
new UvcCameraDetectMac().SetControl(camera, controlName, value);
}
else if (OperatingSystem.IsLinux())
{
new UvcCameraDetectLinux().SetControl(camera, controlName, value);
}
else if (OperatingSystem.IsWindows())
{
new UvcCameraDetectWindows().SetControl(camera, controlName, value);
}
}

// ZWO camera controls (Linux/Windows/macOS)
Expand Down Expand Up @@ -72,6 +80,14 @@ public void SetAuto(ControlType controlName, bool isAuto, Camera camera)
{
new UvcCameraDetectMac().SetControlAuto(camera, controlName, isAuto);
}
else if (OperatingSystem.IsLinux())
{
new UvcCameraDetectLinux().SetControlAuto(camera, controlName, isAuto);
}
else if (OperatingSystem.IsWindows())
{
new UvcCameraDetectWindows().SetControlAuto(camera, controlName, isAuto);
}
}

// ZWO camera auto-controls (Linux/Windows/macOS)
Expand All @@ -89,6 +105,10 @@ public async Task<List<Camera>> GetCameraList()
{
var dshowCameras = await new DShowCameraDetect().GetCameras();
cameras.AddRange(dshowCameras);

// Also detect UVC cameras via libuvc on Windows
var windowsUvcCameras = await new UvcCameraDetectWindows().GetCameras();
cameras.AddRange(windowsUvcCameras);
}
else if (OperatingSystem.IsMacOS())
{
Expand All @@ -112,6 +132,10 @@ public async Task<List<Camera>> GetCameraList()

var v4l2Cameras = await new V4L2CameraDetect().GetCameras();
cameras.AddRange(v4l2Cameras);

// Also detect UVC cameras via libuvc on Linux
var linuxUvcCameras = await new UvcCameraDetectLinux().GetCameras();
cameras.AddRange(linuxUvcCameras);
}

var zwoCameras = await new ZWOCameraDetect().GetCameras();
Expand Down
Loading
Loading