letmaik / pyvirtualcam

🎥 Send frames to a virtual camera from Python
GNU General Public License v2.0
452 stars 49 forks source link

Add AkVCam backend #88

Closed ratuspro closed 9 months ago

ratuspro commented 1 year ago

Follows the discussion on https://github.com/letmaik/pyvirtualcam/discussions/87

This PR still needs to handle:

ratuspro commented 1 year ago

@letmaik I've solved all the issues you mentioned.

Still, I'm not entirely confident that AkVCam backend's performance is good enough to be comparable to the other backends. E.g. it cannot stream more than Full HD @ 30FPS

letmaik commented 1 year ago

Interesting, I think it's worth checking how Webcamoid uses akvcam internally. Maybe there's some way to get better performance. This seems to be the place: https://github.dev/webcamoid/webcamoid/blob/9d399b7d04668ad642dd8cb62c9609f612cf396b/libAvKys/Plugins/VirtualCamera/src/dshow/src/vcamdshow.cpp#L1146 On first it seems to be doing what you had originally, so line by line writing. Can you compare the performance to the OBS cam for example?

ratuspro commented 1 year ago

I conducted a couple of tests to see how obs and the akvcam backends affected the streaming performance:

backend width height Target FPS Actual FPS
obs 1280 720 120 120.0 (100.0%)
akvcam 1280 720 120 123.9 (103.2%)
obs 1920 1080 120 69.3 (57.7%)
akvcam 1920 1080 120 93.2 (77.6%)
obs 1280 720 60 59.9 (99.9%)
akvcam 1280 720 60 60.2 (100.4%)
obs 1920 1080 60 60.0 (100.0%)
akvcam 1920 1080 60 60.2 (100.4%)
obs 1280 720 30 29.9 (99.8%)
akvcam 1280 720 30 30.0 (100.0%)
obs 1920 1080 30 29.9 (99.8%)
akvcam 1920 1080 30 29.7 (99.3%)
obs 2560 1440 30 29.9 (99.7%)
akvcam 2560 1440 30 -
obs 3840 2160 30 17.7 (59.1%)
akvcam 3840 2160 30 -
obs 1280 720 15 14.9 (99.7%)
akvcam 1280 720 15 14.9 (99.7%)
obs 1920 1080 15 14.9 (99.4%)
akvcam 1920 1080 15 14.9 (99.4%)
obs 2560 1440 15 14.8 (99.1%)
akvcam 2560 1440 15 -
obs 3840 2160 15 14.7 (98.4%)
akvcam 3840 2160 15 -

TL;DR; akvcam cannot handle 2560x1400 or higher resolutions. Also, I also tested writing line by line and it did not affect the performance.

ratuspro commented 1 year ago

I'm pretty sure that there might be an overflow or a memory problem when handling larger resolutions but I was not able to figure it out.

letmaik commented 1 year ago

I'm pretty sure that there might be an overflow or a memory problem when handling larger resolutions but I was not able to figure it out.

Did you try to use akvcam directly from the command line? https://github.com/webcamoid/akvirtualcamera/wiki/Usage-and-examples#streaming-with-ffmpeg has an example using ffmpeg. If it doesn't work there as well, then I guess it's an upstream bug.

ratuspro commented 1 year ago

I've tried directly from the command line and the results seem to be inconsistent (independent of the resolution the stream does have irregular FPS).

letmaik commented 1 year ago

I've tried directly from the command line and the results seem to be inconsistent (independent of the resolution the stream does have irregular FPS).

From the command line, do the higher resolutions work?

letmaik commented 1 year ago

CI is still failing, can you have a look?

D:\a\pyvirtualcam\pyvirtualcam\pyvirtualcam\native_windows_akvcam\virtual_output.h(150): error C2065: 'cout': undeclared identifier

letmaik commented 1 year ago

@ratuspro Are you going to continue working on this? I tried your branch and noticed that Python hangs at WriteFile() indefinitely if an app is showing the virtual camera and you press Ctrl-C in the console. I'm not sure how to fix this issue, unfortunately. I see in the task manager that the avkcammanager process is terminated and that probably causes the stdin pipe to become unusable. See also https://learn.microsoft.com/en-us/windows/console/ctrl-c-and-ctrl-break-signals.