letmaik / pyvirtualcam

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

Use libyuv for pixel format conversions #40

Closed letmaik closed 3 years ago

letmaik commented 3 years ago

Previously the repo contained some hand-rolled conversion functions from RGB to UYVY and NV12. This PR uses libyuv instead which contains a large collection of those and which are highly efficient (though there was no bottleneck before).

A minor inconvenience is that it is largely based around two core formats (ARGB and I420) and there are typically no direct conversions available from RGB to other formats. In the case of OBS on macOS, this means RGB -> ARGB -> UYVY, and for Windows RGB -> I420 -> NV12. On Linux, I420 is used directly (via RGB -> I420). The first step on macOS and the second step in Windows is a copy (re-ordering of bytes), which is very fast. The net effect is that the end-to-end performance is the same as before but an additional buffer for ARGB and I420, respectively, has to be kept in memory. For 720p this would be ~3.5 MB on macOS, and ~1.3 MB on Windows.

Adding libyuv to the mix will also open doors for potentially supporting more input formats in the future, next to RGB. See also https://github.com/letmaik/pyvirtualcam/discussions/12#discussioncomment-475709 for a related discussion. @FredericDlugi fyi