YUV conversion in Rust now faster than libyuv

141 points Honest-Emphasis-4841

After some reworking of RGB<->YUV conversion it is now faster than libyuv, written almost in assembly, even with significantly higher precision.

Source repository: https://github.com/awxkee/yuvutils-rs

Test image sized 5763x3842

Results in 8-bit encoding:

Note: on x86 I wasn't able to hit a SIMD accelerated path in libyuv, I tried aligned memory, image dimensions dividable by 16/8 but luck so far.

Conversion time(NEON) Time(AVX)
utils RGB->YUV 4:2:0 3.16ms 3.53ms
libyuv RGB->YUV 4:2:0 3.58ms 33.87ms
utils RGBA->YUV 4:2:0 4.04ms 5.47ms
libyuv RGBA->YUV 4:2:0 4.87ms 23.48ms
utils RGBA->YUV 4:2:2 4.34ms 7.08ms
libyuv RGBA->YUV 4:2:2 5.90ms 35.23ms
utils RGBA->YUV 4:4:4 4.49ms 7.97ms

Results in 8-bit decoding:

Here is also libyuv have issues on some paths

Conversion time(NEON) Time(AVX)
utils YUV NV12->RGB 3.86ms 6.24ms
libyuv YUV NV12->RGB 5.20ms 45.28ms
utils YUV 4:2:0->RGB 3.26ms 5.25ms
libyuv YUV 4:2:0->RGB 5.70ms 44.95ms
utils YUV 4:2:0->RGBA 3.77ms 5.98ms
libyuv YUV 4:2:0->RGBA 6.13ms 6.88ms
utils YUV 4:2:2->RGBA 4.88ms 6.91ms
libyuv YUV 4:2:2->RGBA 5.91ms 6.91ms
utils YUV 4:4:4->RGBA 4.79ms 7.20ms
libyuv YUV 4:4:4->RGBA 4.82ms 7.30ms