Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows + MinGW64 + 2 Elgato CamLinks in November 2022 #245

Closed
FrostKiwi opened this issue Nov 26, 2022 · 3 comments
Closed

Windows + MinGW64 + 2 Elgato CamLinks in November 2022 #245

FrostKiwi opened this issue Nov 26, 2022 · 3 comments

Comments

@FrostKiwi
Copy link

FrostKiwi commented Nov 26, 2022

Used libUVC with great success out of the box on Linux, moved to Windows and it was a painful 6 hours long debug session. Want to quickly sumarize how it ended up and what the result looks like. Since this is not an issue, I'll just close it in a week, just want to document how I got things running in a MinGW64 environment.

I just need one demonstration with 2 cameras hooked up to two Elgato CamLinks up and running within 24h, so I ended up doing a lot of hacky things.

@mcuee Has been doing god's work, linking to vital resources pupil-labs#10 (comment) and distributing prepuilt libraries #12 (comment). Directly linking his MSVC built dlls from MinGW64's GCC results in segfaults on every function that prints to the console (Which I guess is expected with such an ungodly cross-compiler adventure). Ignoring those functions, there is a deal breaker for me: https://github.com/pupil-labs/libuvc did not support NV12 as I found out, the only mode, that support 4k streaming on the Cam Link. (Also a super nice to work with format, match made in heaven for Shader access). Same goes for https://github.com/rageworx/libuvc. It's a repo made for MinGW64, but grepping through it did not match for NV12, therefore I just skiped trying that one. So I had to make the upstream https://github.com/libuvc/libuvc work. (There is also I420, but neither repo supports this one, as reported recently by @damijans in #240)

A big help was this french blog I came across, who built libUVC on MinGW64: https://anthony.lepors.fr/raspi-thermo-cam/compilation-libusb-libuvc-msys2/ (didn't even need deepl.com , really well put together blog with images and file previews ), though I ended up doing this a bit differently.

This repo has misconfigured CMake build instructions if used in combination with MSYS2 for linking libUSB. There have been multiple solutions proposed and multiple repos have provided patches, but nothing made it to upstream.
I just commented out the libUSB part in CMakeLists.txt.

  # target_link_libraries(${target_name}
    # libusb-1.0 used internally so we link to it privately.
   # PRIVATE LibUSB::LibUSB
  #)

If you use MinGW64, then you don't need to compile libUSB, because MSYS2's package manager has it already in store: pacman -S mingw-w64-x86_64-libusb
I generated Ninja build files, hand copied both libUSB header and library cp /mingw64/lib/libusb-1.0.dll.a libuvc/build/CMakeFiles/uvc.dir/src cp /mingw64/include/libusb-1.0/libusb.h libuvc/build/include/libusb.h and edited the link step of the auto generated Ninja build.ninja file to append the lib file:

#############################################
# Link the shared library libuvc.dll

build libuvc.dll libuvc.dll.a: C_SHARED_LIBRARY_LINKER__uvc_Release CMakeFiles/uvc.dir/src/ctrl.c.obj CMakeFiles/uvc.dir/src/ctrl-gen.c.obj CMakeFiles/uvc.dir/src/device.c.obj CMakeFiles/uvc.dir/src/diag.c.obj CMakeFiles/uvc.dir/src/frame.c.obj CMakeFiles/uvc.dir/src/init.c.obj CMakeFiles/uvc.dir/src/stream.c.obj CMakeFiles/uvc.dir/src/misc.c.obj CMakeFiles/uvc.dir/src/libusb-1.0.dll.a
  LANGUAGE_COMPILE_FLAGS = -O3 -DNDEBUG
[...]

(Couple hours in libuvc and libusb started blending together in my eyes and I confused files a couple of times^^) Linking just the resulting libuvc.dll.a to my final program was not enough, because the build file was configured for Shared build mode. It had to be both libuvc.dll.a and libuvc.dll. Normally a deal breaker, but it's just a one of demo, I'm sure it can be reconfigured for proper static only linkage.

Next, the default Camera driver won't work. Following https://github.com/pupil-labs/pyuvc/blob/master/WINDOWS_USER.md steps 1-6, I replaced both the CamLink's drivers with libusbK. This makes libUVC play along, but as a side effect, OBS does not recognize those CamLinks anymore. What a pain, have to switch back the drivers. (Which makes me wonder, whether each driver switch fills up the C: drive with System Restore points...)

The result:

Device Config of a CamLink with a Panasonic GH6 in 4K mode
DEVICE CONFIGURATION (0fd9:0066/0005AC85A6000) ---
Status: idle
VideoControl:
        bcdUVC: 0x0110
VideoStreaming(1):
        bEndpointAddress: 131
        Formats:
        UncompressedFormat(1)
                  bits per pixel: 12
                  GUID: 4e56313200001000800000aa00389b71 (NV12)
                  default frame: 1
                  aspect ratio: 0x0
                  interlace flags: 00
                  copy protect: 00
                        FrameDescriptor(1)
                          capabilities: 01
                          size: 3840x2160
                          bit rate: -1308983296--1308983296
                          max frame size: 12441600
                          default interval: 1/29
                          interval[0]: 1/29
        UncompressedFormat(2)
                  bits per pixel: 12
                  GUID: 4e56313200001000800000aa00389b71 (NV12)
                  default frame: 1
                  aspect ratio: 0x0
                  interlace flags: 00
                  copy protect: 00
                        FrameDescriptor(1)
                          capabilities: 01
                          size: 3840x2160
                          bit rate: -1308983296--1308983296
                          max frame size: 12441600
                          default interval: 1/29
                          interval[0]: 1/29
        UncompressedFormat(3)
                  bits per pixel: 12
                  GUID: 4934323000001000800000aa00389b71 (I420)
                  default frame: 1
                  aspect ratio: 0x0
                  interlace flags: 00
                  copy protect: 00
                        FrameDescriptor(1)
                          capabilities: 01
                          size: 3840x2160
                          bit rate: -1308983296--1308983296
                          max frame size: 12441600
                          default interval: 1/29
                          interval[0]: 1/29
END DEVICE CONFIGURATION
Device Config Listing of a CamLink with a Panasonic HDC-SD909 in PAL 1080p
DEVICE CONFIGURATION (0fd9:0067/0003D9565D000) ---
Status: idle
VideoControl:
        bcdUVC: 0x0110
VideoStreaming(1):
        bEndpointAddress: 131
        Formats:
        UncompressedFormat(1)
                  bits per pixel: 16
                  GUID: 5955593200001000800000aa00389b71 (YUY2)
                  default frame: 1
                  aspect ratio: 0x0
                  interlace flags: 00
                  copy protect: 00
                        FrameDescriptor(1)
                          capabilities: 01
                          size: 1920x1080
                          bit rate: 1658880000-1658880000
                          max frame size: 4147200
                          default interval: 1/50
                          interval[0]: 1/50
        UncompressedFormat(2)
                  bits per pixel: 12
                  GUID: 4e56313200001000800000aa00389b71 (NV12)
                  default frame: 1
                  aspect ratio: 0x0
                  interlace flags: 00
                  copy protect: 00
                        FrameDescriptor(1)
                          capabilities: 01
                          size: 1920x1080
                          bit rate: 1244160000-1244160000
                          max frame size: 3110400
                          default interval: 1/50
                          interval[0]: 1/50
        UncompressedFormat(3)
                  bits per pixel: 12
                  GUID: 4934323000001000800000aa00389b71 (I420)
                  default frame: 1
                  aspect ratio: 0x0
                  interlace flags: 00
                  copy protect: 00
                        FrameDescriptor(1)
                          capabilities: 01
                          size: 1920x1080
                          bit rate: 1244160000-1244160000
                          max frame size: 3110400
                          default interval: 1/50
                          interval[0]: 1/50
END DEVICE CONFIGURATION
Both cameras work, but their behaviour is strange, as compared to Linux. The 4k camera in NV12 mode should stream at 30fps, but libUVC only updates at 24fps, regardless of circumstances. (I confirmed the camera streaming at 30 fps in OBS before switching drivers)

Then the second 1080p Camera does not enter NV12 mode, but fails with get_mode: Invalid mode (-51). This one I don't understand at all. It's fine in Linux. It's fine in YUV2 mode though on Windows. Even though it has way less data to stream, it only streams at 4.8fps. Again the strange FPS shift. So I ended up with the YUV2 mode, uvc_yuyv2rgb() conversion and a 4.8 fps framerate on the 2nd Cam. Mind you, the results are the same whether or not both cameras stream at the same time or not.

The main camera streams at 24 fps and the secondary overlayed one is not that important for my demo, I'm happy with what I got. But man is all of this unrelaible as compared to Linux. Across two Windows machines, same result. Propably libusbK acting up.

@FrostKiwi FrostKiwi changed the title Windows + MinGW64 in November 2022 Windows + MinGW64 + 2 Elgato CamLinks in November 2022 Nov 26, 2022
@FrostKiwi
Copy link
Author

Ohh... And just in case any of you were wonder on how reliable the drivers are...

reliable.mp4

(Finger pointed at Loose HDMI connector)

@FrostKiwi
Copy link
Author

FrostKiwi commented Dec 6, 2022

Again the strange FPS shift. So I ended up with the YUV2 mode, uvc_yuyv2rgb() conversion and a 4.8 fps framerate on the 2nd Cam.

I don't know why, but I replaced the HDMI cable for my on stage demo and my streamed FPS shot up to the full 50fps on the second cam, that was 5 fps before. O.O
Maybe a coincidence. Either way everything worked perfectly in the end.
That was my experience with libUVC on Windows.

Sry for the long blog like mess, thought I bundle all this information, maybe useful to someone.

PS: If you want to revert to the original driver, after changing it with Zadig, you have to plugin the CamLink, find the libusbk composite parent in the device manager, right click, properties, uninstall device and be sure to tick the uninstall the device driver option. After rescanning for new devices and replugging the CamLink, it received the original driver and VLC and OBS could playback the HDMI signal again.

@mcuee
Copy link

mcuee commented Dec 30, 2022

@FrostKiwi
Thanks a lot for the detailed instructions. I am able to follow your instructions and build libuvc git HEAD under MSYS2/mingw64.

Result binary seems to work fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants