175 Commits

Author SHA1 Message Date
Frank Barchard
205022c08c [libyuv] Add AVX-512 VNNI row functions for ARGB to YUV and Gray
Add AVX-512 VNNI (VPDPBUSD / _mm512_dpbusd_epi32) row kernels for 64-bit
x86 targets alongside existing AVX-512BW implementations in both
row_gcc.cc (inline assembly) and row_win.cc (C++ intrinsics):

- ARGBToYMatrixRow_AVX512VNNI and ARGBToYMatrixRow_Any_AVX512VNNI:
  Pre-computes the 32-bit signed-pixel bias once per row and replaces
  vpmaddubsw + vpmaddwd + vpaddw with a single vpdpbusd per 16 pixels.
- ARGBToUV444MatrixRow_AVX512VNNI and
  ARGBToUV444MatrixRow_Any_AVX512VNNI: Loads 64 ARGB pixels once instead
  of twice and computes 32-bit U and V dot products directly via
  vpdpbusd with signed UV matrix coefficients.
- ARGBToUVMatrixRow_AVX512VNNI: Computes 2x2 box-filtered ARGB to U and
  V conversion using vpdpbusd with k-masked tail handling for arbitrary
  widths.
- ARGBGrayRow_AVX512VNNI: Computes BT.601 grayscale luminance using a
  single vpdpbusd per 16 pixels, broadcasts Y to RGB via vpshufb, and
  preserves alpha via vpternlogd with k-masked tail handling.
- Wire runtime dispatch via TestCpuFlag(kCpuHasAVX512VNNI) across
  convert.cc, convert_from_argb.cc, and planar_functions.cc.

Add AVX512VNNIVBMI variants of the Y, UV444 and UV kernels. These use
both AVX-512 VNNI (vpdpbusd) and AVX-512 VBMI (vpermt2b) and are only
selected when the CPU has both features; there are no VBMI versions
without VNNI. The AVX512VNNI kernels remain for CPUs with VNNI but no
VBMI (Cascade Lake, Cooper Lake).

- The 32-bit sums are always in [0, 65535], so Y, U and V are byte 1 of
  each int32. Two vpermt2b gather 64 results from 4 accumulators,
  replacing vpackusdw/vpackssdw + vpsrlw + vpackuswb + vpermd.
- U and V accumulators start at ~kAddUV so they hold ~(kAddUV - dot).
  The inverse is folded into the vpternlogd that merges the two
  256-bit halves. kAddUV is loaded from ArgbConstants rather than
  hard coded as 0x8000.
- Y folds the source loads into vpxorq.
- row_win.cc hides the vpermt2b indices from clang, which otherwise
  constant folds them into a longer vpshufb + vpor + vpermd sequence.

Performance (1280x720, 5000 iterations, AVX512BW -> AVX512VNNI):
uArch / Benchmark            AVX512BW  AVX512VNNI  Speedup
---------------------------  --------  ----------  -------
Intel Ice Lake ARGBToI420      941 ms      862 ms   +9.2%
Intel Ice Lake ARGBToI422     1059 ms      947 ms  +11.8%
Intel Ice Lake ARGBToI444     1140 ms     1038 ms   +9.8%
Intel Ice Lake ARGBGray        357 ms      273 ms  +30.8%
Intel Sapphire Rapids GrayTo   317 ms      218 ms  +45.4%
Intel Emerald Rapids GrayTo    310 ms      213 ms  +45.5%
Intel Granite Rapids GrayTo    349 ms      241 ms  +44.8%
AMD Zen 4 ARGBToI420           648 ms      517 ms  +25.3%
AMD Zen 4 ARGBToI444           695 ms      526 ms  +32.1%
AMD Zen 4 ARGBGray             403 ms      227 ms  +77.5%
AMD Zen 5 ARGBToI422           460 ms      403 ms  +14.1%
AMD Zen 5 ARGBToI444           382 ms      321 ms  +19.0%

Performance (row_gcc, AVX512VNNI -> AVX512VNNIVBMI):
uArch / Benchmark             AVX512VNNI  VNNIVBMI  Speedup
----------------------------  ----------  --------  -------
AMD Zen 6 ARGBToI420 1280x720     327 ms    284 ms   +15.1%
AMD Zen 6 ARGBToI422 1280x720     372 ms    330 ms   +12.7%
AMD Zen 6 ARGBToI444 1280x720     357 ms    334 ms    +6.9%
AMD Zen 6 ARGBToI400 256x24        94 ms     76 ms   +23.7%
AMD Zen 5 ARGBToI422 1280x720     406 ms    350 ms   +16.0%
AMD Zen 5 ARGBToI444 1280x720     330 ms    301 ms    +9.6%
AMD Zen 5 ARGBToI400 256x24       100 ms     90 ms   +11.1%
AMD Zen 4 ARGBToI420 1280x720     631 ms    540 ms   +16.9%
AMD Zen 4 ARGBToI422 1280x720     993 ms    825 ms   +20.4%
AMD Zen 4 ARGBToI400 256x24       245 ms    218 ms   +12.4%
Intel GNR ARGBToI422 256x24       654 ms    616 ms    +6.2%
Intel SPR ARGBToI422 256x24       653 ms    613 ms    +6.5%
Intel GNR, EMR, SPR and Ice Lake are within +/-3% at 1280x720.

R=rrwinterton@gmail.com

Bug: none
Test: out/Release/libyuv_unittest --gtest_filter=*ARGBToI4*:*ARGBGray*
Test: LIBYUV_DISABLE_AVX512VBMI=1 out/Release/libyuv_unittest
Test: sde64 -gnr / -clx with is_msan=true (row_win.cc)
Change-Id: Ia7a37b39dd2948fe4055a8a7694dd1ff8ac3e55c
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8647811
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-10-26 14:07:50 -07:00
Frank Barchard
f249eaa72f [libyuv] Fix top 20 bugs and performance issues
1. Fix multi-bit TestCpuFlag(A | B) checks in AYUVToNV12, AYUVToNV21,
   RAWToRGBA, NV12ToRGB24Matrix, NV21ToRGB24Matrix, MergeRGBPlane, and
   MergeXR30Plane to compare == (A | B) so AVX-512 VBMI/BW kernels are
   not dispatched when AVX512VBMI or AVX512VL is absent.
2. Fix 2-byte SVE2 heap buffer overflow on odd widths in
   I422ToARGB1555Row_SVE_SC and I422ToARGB4444Row_SVE_SC using
   trn1/trn2 + st2b under .b predicates.
3. Fix ARGBPolynomialRow_SSE2 to use packssdw before packuswb, and add
   missing vzeroupper to SplitRGBRow_AVX2.
4. Fix CalcFrameSsim to return 0.0 instead of 0.0 / 0 (NaN) when
   width <= 8 || height <= 8 so I420Ssim stays finite on small frames.
5. Fix negative-height vertical inversion in ConvertFromI420,
   SplitARGBPlane (when dst_a is NULL), I422Rotate, I010Rotate, and
   I210Rotate.
6. Fix horizontal flip (negative x/dx) in ScaleFilterCols_NEON (signed
   sbfx #16, #16 offset extraction) and ScaleAddCols1_16_C (shift
   x >>= 16 before indexing src_ptr).
7. Fix ConvertToARGB odd crop_x chroma alignment in NV12/NV21, src_u
   offset in I420/YV12/J420/H420/U420, and FOURCC_U422 calling
   U422ToARGB instead of H422ToARGB.
8. Remove dead 14-instruction block in ScaleRowUp2_Bilinear_16_SSE2.
9. Fix UVScale_16 for src_width == 1 (P010ToP410/P210ToP410), enable
   and fix column order in TransposeWx4_32_SVE2, fix ByteToFloatRow
   NEON Any BPP (3 -> 4), fix AB64ToARGBRow_Any_*, ScaleColsUp2_SSE2,
   ScaleUVRowDown2Box_SME, and UYVYToARGBRow_SME macro guards, fix SVE2
   loop tail branches (b.lt/b.ge), and remove duplicate HAS_* macros.
10. Fix ConvertFP16ToFP32Column_NEON loop condition and unsigned b.lo
    underflow on widths < 8 or not multiples of 8.
11. Fix UYVYToNV12 IS_ALIGNED(awidth, ...) checks and WASM SIMD
    IS_ALIGNED(width, 16) checks in I420ToRGB24Matrix /
    I422ToRGB24Matrix.
12. Wire SplitUVRow_SVE2, SplitUVRow_LSX, and SplitUVRow_LASX in
    NV24ToARGB.
13. Fix MJpegDecoder heap buffer overflows in LoadFrame (reallocate
    databuf_[i] when scanlines_size changes), DecodeToBuffers, and
    DecodeToCallback (clamp scanlines_to_copy to lines_left and align
    skip to max_v_samp_factor).
14. Replace width & (vl - 1) tail calculations with post-loop remainder
    across 18 SVE2 functions in row_sve.h for non-power-of-2 SVE VL,
    and remove duplicate label 2: in UYVYToARGBRow_SVE_SC.
15. Handle width & 15 tail pixels in DetileToYUY2_C and validate
    IS_POWEROFTWO(tile_height) in DetileSplitUVPlane and DetileToYUY2.
16. Avoid signed 32-bit overflow in DivideRow_16_C and C16TO8, fix
    ClampFloatToZero_SSE2 pointer increment (lea 0x4) and loop counter
    (sub $0x1), and initialize xmm3 in ARGBCopyYToAlphaRow_SSE2.
17. Check max leaf 7 subleaf and max extended CPUID leaf in GetCpuFlags
    before querying subleaf 7:1 and extended leaf 0x80000021.
18. Free plane_u on error in I422ToNV21, and fix 4x/2x scratch row
    over-allocation in ScaleARGBBilinearDown and ScaleUVBilinearDown.
19. Add ARGBSetRow_RVV and ARGBShuffleRow_RVV in row_rvv.cc.
20. Fix NEON mask (15 -> 7) in ScaleUVRowUp2_Linear_Any_NEON /
    _16_Any_NEON, use SIMD InterpolateRow + SplitUVRow in NV16ToI420,
    wire SSSE3/SSE2 in ARGBToI400Matrix / ARGBToYUY2Matrix /
    ARGBToUYVYMatrix and RGB24Mirror, and split HalfFloatRow multiply
    into (src * scale) * 2^-112 to avoid 50x Intel denormal stalls.

Bug: b/574714081
Test: libyuv_unittest
Change-Id: Iec3ae5c58d52bee3ef13cf9b765ac84b733aa576
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8601931
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-10-19 16:46:40 -07:00
Frank Barchard
700f153cb8 [libyuv] Add Qualcomm Hexagon HVX SIMD support
Implement Qualcomm Hexagon Vector Extensions (HVX) 128-byte SIMD
optimizations and runtime CPU detection for Hexagon DSP targets:
- CPU detection: Add kCpuHasHexagon and kCpuHasHVX flags,
  LIBYUV_DISABLE_HVX environment variable support, and Hexagon
  unit_test mmap/munmap shims.
- Rotate/Transpose (rotate_hvx.cc): Implement TransposeWxH_HVX,
  TransposeUVWxH_HVX, TransposeWxH_16_HVX, and TransposeWxH_32_HVX
  using power-of-2 vdeal/vshuff butterfly networks.
- Compare (compare_hvx.cc): Implement HammingDistance_HVX,
  SumSquareError_HVX, HashDjb2_HVX, and Ssim4x4Row_HVX.
- Scale (scale_hvx.cc): Implement 16 scale row kernels including
  ScaleAddRow_HVX, ScaleRowDown2*_HVX (8-bit and 16-bit),
  ScaleRowDown4*_HVX, ScaleARGBRowDown2*_HVX, and
  ScaleUVRowDown2*_HVX.
- Row functions (row_hvx.cc): Implement 58 row kernels covering
  copy/set/mirror, split/merge, 8/16-bit conversions, YUV-to-ARGB,
  ARGB-to-YUV, ARGB channel swizzles, blend, attenuate, and
  interpolate using hardware-predicated partial loads/stores.

R=rrwinterton@gmail.com

Bug: None
Test: libyuv_unittest on Hexagon v81 simulator and Snapdragon 8 Elite
Change-Id: Ib6713de51f6246d95e58c95e629ff03f18e3b91e
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8604586
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-10-19 14:16:18 -07:00
Frank Barchard
2404f9730e [libyuv] Rewrite LoongArch LSX/LASX kernels in compact inline asm
Reduce loop unrolling across LoongArch LSX (128-bit) and LASX (256-bit)
compare, row, rotate, and scale kernels to match SSE2/SSSE3 and AVX2
(1-2 vectors per iteration), rewrite intrinsics/macro implementations
into GCC/Clang inline assembly, update all _Any wrapper masks and
IS_ALIGNED dispatch checks, and port all remaining LSX Convert (+19) and
Rotate (+2) kernels to LASX for full parity:

ISA              | Compare | Convert | Rotate  | Scale
-----------------|---------|---------|---------|--------
MIPS/Loong (Any) |    1    |    68   |    4    |   20
  LSX            |    1    |    68   |    4    |   20
  LASX           |    1    |    68   |    4    |    0

Removes 1,935 macro/helper lines from loongson_intrinsics.h (-99.3%) and
reduces total LoongArch compiled .text size by 9,799 bytes (-25.1%
overall, -37.4% row_lsx.cc, -52.3% scale_lsx.cc, -31.2% rotate_lsx.cc,
-4.9% row_lasx.cc while adding +25 LASX functions):

File               | Before   | After    | Change
-------------------|----------|----------|--------
scale_lsx.cc.o     | 6,055 B  | 2,888 B  | -52.3%
row_lsx.cc.o       | 17,252 B | 10,792 B | -37.4%
rotate_lsx.cc.o    | 1,488 B  | 1,024 B  | -31.2%
row_lasx.cc.o      | 13,740 B | 13,072 B |  -4.9%
rotate_lasx.cc.o   |   544 B  | 1,504 B  | +176.5%
TOTAL .text        | 39,079 B | 29,280 B | -25.1%

R=wtc@google.com, yuanhecai@loongson.cn

Test: qemu-loongarch64 -cpu la464 libyuv_unittest (LASX and LIBYUV_DISABLE_LASX=1)
Change-Id: I11c1143ad2aad0399f10b2c3fc9bc4c02c740c59
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8564659
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-10-16 17:25:23 -07:00
Frank Barchard
b9d572cc63 Add 25 native k-masked AVX-512 row kernels
R=rrwinterton@gmail.com

Bug: None
Change-Id: I2ee9b2c2d939f63f49d2f951f2d552ca6863d78b
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8564927
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-10-12 18:14:41 -07:00
Frank Barchard
63b56324de [libyuv] Replace AVX-512 _Any wrappers with k-mask tail handling
Replace stack-buffer memcpy _Any wrappers with native AVX-512 k-mask
tail handling across 8 AVX-512 row kernels (unlocking composite
RGBToUVMatrixRow_AVX512BW as well) and remove IS_ALIGNED dispatch
constraints:
- MirrorSplitUVRow_AVX512BW: Masked 16-bit load (vmovdqu16 %{k1%}%{z%}),
  dynamic reverse index (vpsubw + vpermw via kMirrorUVPermute_AVX512),
  and vpmovwb %{k1%} U/V stores; unlocks unaligned SplitRotateUV180.
- ARGBToUVMatrixRow_AVX512BW: Fix MASK=63 vs 32-pixel loop bug;
  zero-load tail dwords per row, duplicate odd final pixel via knotw +
  vpshufd, and store masked U/V bytes.
- I422ToARGBRow_AVX512BW & I422ToAR30Row_AVX512BW: Add masked Y/U/V
  loads (READYUV422_MASK_AVX512BW) and masked ARGB/AR30 stores.
- CopyRow_AVX512BW: Add 64-byte full vector step + bzhi masked tail.
- BlendPlaneRow_AVX512BW, ARGBShuffleRow_AVX512BW, RGBToARGBRow_AVX512BW
  (RAWToARGBRow_AVX512BW / RGB24ToARGBRow_AVX512BW): Masked loads and
  stores in both row_gcc.cc inline assembly and row_win.cc intrinsics.

Reduces x86-64 binary .text size by 2,592 bytes with 0 bytes added to
.rodata.

Performance on Intel Sapphire Rapids (1275x1650, 1000 iterations):
Function (Test)          | Before  | After   | Speedup
-------------------------|---------|---------|--------
NV12Rotate180_Opt        | 429 ms  | 260 ms  | 1.65x
RGB24ToI420_Opt          | 615 ms  | 531 ms  | 1.16x
I420ToAR30_Opt           | 425 ms  | 383 ms  | 1.11x
ARGBToI420_Opt           | 427 ms  | 411 ms  | 1.04x
I420ToARGB_Opt           | 423 ms  | 411 ms  | 1.03x
RGB24ToARGB_Opt          | 493 ms  | 490 ms  | 1.01x
ARGBToBGRA_Opt           | 544 ms  | 542 ms  | 1.00x
CopyPlane_Opt            | 246 ms  | 245 ms  | 1.00x
BlendPlane_Opt           | 259 ms  | 258 ms  | 1.00x
RAWToARGB_Opt            | 486 ms  | 486 ms  | 1.00x

R=rrwinterton@gmail.com

Test: LIBYUV_WIDTH=1275 LIBYUV_HEIGHT=1650 LIBYUV_REPEAT=1000 out/Release/libyuv_unittest
Change-Id: Ib5e5ae52076352649108b20f8df2b12d81860fb1
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8563977
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-10-12 15:33:19 -07:00
Frank Barchard
98697ab033 [libyuv] Add WASM SIMD128 compare, rotate, scale and row functions
d8 geomean speedup vs C compiled with -O2 -msimd128:
File            AMD Zen 3  ARM Neoverse-V2
row_wasm.cc         5.67x            3.24x
scale_wasm.cc       5.47x            3.17x
compare_wasm.cc     4.58x            5.77x
rotate_wasm.cc      6.83x            6.03x

Bug: None
Change-Id: Ia06c805dc4029f94842c40e7301b2933beb8c1e5
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8524106
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-10-06 19:05:05 -07:00
Frank Barchard
18835bfb35 ARGBToRGB24 AVX512 with tail masking
Bug: None
Change-Id: I7590c66940b5354ca0fdd8ff120392434d2785d7
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8490011
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-09-29 16:15:44 -07:00
Frank Barchard
f1c9b58986 clang format and bump version
Bug: None
Change-Id: I6a482d5c538b113549b88e820473af644d6d3704
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8467772
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-09-28 10:42:45 -07:00
Sida Zhu
eae15e5fdd convert_from_argb: Add ARGB to P010, P210, and P410
Add matrix and BT.601 wrappers that convert ARGB to 16-bit biplanar
YUV in P010 (4:2:0), P210 (4:2:2), and P410 (4:4:4) layouts.

Reuse optimized ARGB matrix row functions for 8-bit Y and chroma,
merge UV with MergeUVRow, then expand with Convert8To16Row (bits=10)
and MultiplyRow_16 (scale=64) so 10-bit samples are stored in the
high bits of each uint16.

Reject width > INT_MAX / 2 so UV width (halfwidth * 2 or width * 2)
does not overflow Convert8To16Row.

Bug: 537818862
Change-Id: I7a776fb3d6f52ce46a0f6825903bfdb9c6dcfbe2
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8314189
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-09-23 20:42:55 -07:00
Frank Barchard
f51ad56a3e Multiply_16 port to avx512, rvv, neon 32 bit, and windows
- Also remove redundant neon check for I8MM kernels

======================================================================
CPU                                 Before      After          Speedup
----------------------------------------------------------------------
Intel Granite Rapids (AVX10.1)      251 ms     141 ms   1.78x (+43.8%)
Intel Emerald Rapids (AVX512)       199 ms     108 ms   1.84x (+45.7%)
Intel Sapphire Rapids (AVX512)      230 ms     112 ms   2.05x (+51.3%)
AMD Turin Zen 5 (AVX512)            156 ms      99 ms   1.58x (+36.5%)
AMD Venice Zen 6 (AVX512)           204 ms     106 ms   1.92x (+48.0%)
Intel Skylake-X (AVX512)            320 ms     156 ms   2.05x (+51.2%)
AMD Genoa Zen 4 (AVX512)            236 ms     346 ms   0.68x (-46.6%)
Intel Ice Lake (AVX512)             242 ms     316 ms   0.77x (-30.6%)
AMD Milan Zen 3 (AVX2)              252 ms     230 ms    1.10x (+8.7%)
Intel Haswell (AVX2)                369 ms     456 ms   0.81x (-23.6%)
NVIDIA Grace (SVE2)                 336 ms     337 ms    1.00x (-0.3%)
ARM Neoverse-N1 (NEON)             1081 ms    1105 ms    0.98x (-2.2%)
======================================================================


Bug: 537818862
Change-Id: I3ddeddb040fc52a30dabe7ae2c71d16dda021568
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8343467
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-09-01 19:08:52 -07:00
Sida Zhu
bcb6b76283 convert_from_argb: Add ARGB to NV16 and NV24
Add matrix and BT.601 wrapper APIs for converting ARGB to NV16 and
NV24. Reuse the optimized ARGB Y and UV row functions, then merge
the planar chroma rows into the interleaved destination plane.

NV16 performs horizontal 2:1 chroma subsampling on every source row.
NV24 preserves full-resolution 4:4:4 chroma. Both paths support odd
widths, negative heights, and the existing matrix constants.

Add tests that compare scalar and optimized paths at an odd width and
height through the matrix API and its BT.601 wrapper.

Bug: 537818862
Change-Id: Iddefc714a800cdec4dd1394ac7a52bf7b51fd350
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8314188
Reviewed-by: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-09-01 12:56:28 -07:00
yuanhecai
60102bd795 loongarch: Fix RGBToY SIMD
Add missing RGBToYMatrixRow_Any_{LSX,LASX} and kAddY offset fix so
RAW/RGB24 to YUV works on LoongArch.

Change-Id: I4c990a3705d7f521fa6d0c9e7e01f1e36f81c379
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8292090
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-31 20:57:34 -07:00
Wan-Teh Chang
8585efd4bd Fix clang-tidy warnings
1. source/convert_from_argb.cc should include libyuv/convert.h because
   it calls ARGBToI420Matrix().
2. Include <string.h> for memset().

Change-Id: I3f4841fe604639c7357148ef4788fe0415f0b81b
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8255654
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-08-28 08:59:01 -07:00
Frank Barchard
0c781f87b8 [libyuv] Keep LIBYUV_API in basic_types.h and remove legacy types and bool macros
Reduces include/libyuv/basic_types.h to only define LIBYUV_API.
Directly includes <stdint.h> and <stddef.h> where needed in public
headers.
Replaces LIBYUV_BOOL, LIBYUV_FALSE, and LIBYUV_TRUE with C++ bool,
true, and false in C++ code (MJpegDecoder, unit tests) and int (0, 1)
for C API functions.
Updates documentation and unit tests.

Test: ninja -C out/Release libyuv_unittest && ./out/Release/libyuv_unittest --gtest_filter=*
Change-Id: I2d58e872f0f976263bcda546dcc3b1b5f7e53d58
TAG=agy
CONV=2730bc56-93ff-48ed-b615-dcde1b834394
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8280662
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-28 08:32:19 -07:00
Wan-Teh Chang
d67b51303d Revert "Add the ARGBToRGB565Row_SSE2() function back"
This reverts commit 87c797b3c29cc6fb233fc329a93aace2942ba2d9.

Reason for revert: Only commit 8aeb3a9 needs the workaround

Original change's description:
> Add the ARGBToRGB565Row_SSE2() function back
>
> Add the ARGBToRGB565Row_SSE2() and ARGBToRGB565Row_Any_SSE2() functions
> back because they hide the unaligned access in ARGBToRGB565Row_C().
>
> To reproduce the unalgined access error, run the following command in
> Google's internal repository:
>   blaze test --config=asan third_party/libyuv:libyuv_test \
>   --test_filter=LibYUVConvertTest.I420ToARGBToRGB565_Unaligned
>
> Bug: b:547803993
> Change-Id: I9cc6b643bc007c100dfc092ef3ec814428789219
> Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8265046
> Commit-Queue: Wan-Teh Chang <wtc@google.com>
> Reviewed-by: Frank Barchard <fbarchard@google.com>

Bug: b:547803993
Change-Id: I904126f032f4ed37c470d8972152a137ca315168
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8258919
Reviewed-by: Frank Barchard <fbarchard@google.com>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-17 14:43:10 -07:00
Wan-Teh Chang
87c797b3c2 Add the ARGBToRGB565Row_SSE2() function back
Add the ARGBToRGB565Row_SSE2() and ARGBToRGB565Row_Any_SSE2() functions
back because they hide the unaligned access in ARGBToRGB565Row_C().

To reproduce the unalgined access error, run the following command in
Google's internal repository:
  blaze test --config=asan third_party/libyuv:libyuv_test \
  --test_filter=LibYUVConvertTest.I420ToARGBToRGB565_Unaligned

Bug: b:547803993
Change-Id: I9cc6b643bc007c100dfc092ef3ec814428789219
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8265046
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-08-17 13:09:01 -07:00
Frank Barchard
6fa5264292 ARGBToRGB565Dither fix for unaligned dither matrix
Copy dither4x4 (16 bytes) into an aligned local uint32_t dither4[4] array
using memcpy and index using dither4[y & 3] to avoid unaligned 32-bit
pointer dereference traps in fastbuild / UB sanitizers.

Bug: None
Test: LibYUVConvertTest.TestNoDither, LibYUVConvertTest.TestDither
Change-Id: I4447cd2924b16739a9bce2792d57a550dedeb345
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8262354
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-14 17:27:08 -07:00
Frank Barchard
149568401f SVE2 row functions needed for multipass image functions
- MergeUVRow_SVE2: Interleaves U and V
 - SplitUVRow_SVE2: De-interleaves UV
 - InterpolateRow_SVE2: Bilinear row interpolation
 - YUY2ToYRow_SVE2, YUY2ToUVRow_SVE2, UYVYToYRow_SVE2, UYVYToUVRow_SVE2
 - HalfMergeUVRow_SVE2: 2:1 vertical averaging of U and V

OnePlus 15 with Qualcomm Snapdragon 8 Elite Gen 5 Oryon V3

Benchmark (1280x720 1000x)     | SVE2   | NEON   | Result
-------------------------------+--------+--------+------------------
TestInterpolatePlane           | 119 ms | 164 ms | SVE2 is 1.38x win
TestInterpolatePlane_16        | 138 ms | 172 ms | SVE2 is 1.25x win
SplitUVPlane_Opt               |  68 ms |  69 ms | SVE2 is 1.01x win
MergeUVPlane_Opt               |  40 ms |  40 ms | Tied
SwapUVPlane_Opt                |  72 ms |  72 ms | Tied
HalfMergeUVPlane_Opt           |  50 ms |  50 ms | Tied
I420ToNV12_Opt                 |  25 ms |  26 ms | SVE2 is faster
I420ToNV21_Opt                 |  26 ms |  26 ms | Tied
YUY2ToNV12_Opt                 |  79 ms |  81 ms | SVE2 is faster
NV21ToNV12_Opt                 |  36 ms |  35 ms | Tied
Android420ToI420ToNV12_Opt     |  53 ms |  53 ms | Tied
Android420ToI420ToNV21_Opt     |  35 ms |  33 ms | NEON is faster
YUY2ToI420_Opt                 |  87 ms |  84 ms | NEON is faster
UYVYToI420_Opt                 |  87 ms |  83 ms | NEON is faster
YUY2ToI422_Opt                 | 101 ms |  97 ms | NEON is faster
UYVYToI422_Opt                 | 101 ms |  97 ms | NEON is faster
UYVYToNV12_Opt                 | 111 ms | 108 ms | NEON is faster
ARGBToNV21_Opt                 | 279 ms | 279 ms | Tied
ABGRToNV21_Opt                 | 279 ms | 280 ms | SVE2 is faster
ARGBToNV12_Opt                 | 285 ms | 280 ms | NEON is faster
ABGRToNV12_Opt                 | 284 ms | 281 ms | NEON is faster

Bug: 42280902
Change-Id: I53f633fe453f2853f7bc9fe17280e938912c4e8f
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8196068
Reviewed-by: Justin Green <greenjustin@google.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-08-06 12:40:26 -07:00
Wan-Teh Chang
a86d27122a Export the ARGBToNV21Matrix() function
Change-Id: If6edc42e8491bfc0973fe6134b6d6923e9d3befd
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8198925
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-05 19:19:46 -07:00
Wan-Teh Chang
019de35678 Rename the dst_stride_uv param of ARGBToNV21Matrix
It should be named dst_stride_vu to match the dst_vu parameter.

Change-Id: I3a4835eafa358787a858b896060e6c715813bbec
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8135083
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-05 14:48:57 -07:00
Frank Barchard
7138e0a2a7 Make RGBToY a 1 pass avx512bw
- RGBToARGB use vpermi2q+vpshufb
- direct RGBToY for avx512 and rvv

+----------+----------+-------------+----------+---------+-----------+
| ARGBToY  | ARGBToUV | ARGBToUV444 | RGBToY   | RGBToUV | RGBToUV444|
+----------+----------+-------------+----------+---------+-----------+
| avx512bw | avx512bw | avx512bw    | avx512bw | 2 step  | 2 step    |
| avx2     | avx2     | avx2        | 2 step   | 2 step  | 2 step    |
| ssse3    | ssse3    | ssse3       | 2 step   | 2 step  | 2 step    |
| dot      | i8mm     | i8mm        | dot      | neon    | neon      |
| sve2     | sve2     | -           | -        | -       | -         |
| sme      | sme      | -           | -        | -       | -         |
| rvv      | rvv      | rvv         | rvv      | rvv     | rvv       |
+----------+----------+-------------+----------+---------+-----------+


Bug: 42280902
Change-Id: I9f83bf3039431f9fb5391bd7d9eb393e186d6bcf
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8175442
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-08-03 17:53:19 -07:00
Frank Barchard
0148582bb8 Change all 1 use wrappers to matrix calls
Bug: 42280902
Change-Id: Ieccb1e8eeaec3064fc5d36d2f1233fd38eb2a128
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8177647
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-07-31 17:29:30 -07:00
Frank Barchard
1a746db4ce Remove unused wrappers for 'matrix' functions
Bug: 42280902
Change-Id: Idbc757e10d1bcf276ce00dbdd07a39f4ad01a5af
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8177664
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-07-30 19:03:49 -07:00
Frank Barchard
805babf995 [libyuv] Fix NV21 chroma plane ordering in ARGBToNV21Matrix
Fix the chroma plane order passed to MergeUVRow in ARGBToNV21Matrix.
MergeUVRow(a, b, dst, ...) writes a into byte 0 and b into byte 1.
Passing (row_u, row_v) produced NV12 format (UV interleaved) instead
of NV21 format (VU interleaved). Swapping to (row_v, row_u) ensures
the chroma channels are correctly ordered for NV21 output.

Test: libyuv_unittest --gtest_filter=*NV21*
Bug: None
Change-Id: I3b78246c635ce515923739298013a61203cabb72
TAG=agy
CONV=5daf08a8-11bd-4d47-8c71-c5b7a882a788
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8133203
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-07-21 18:49:32 -07:00
Frank Barchard
4be798d7c5 BGRAToI420 use BgraConstants for a direct conversion using AVX512BW
row win (msvc)
Was C/SSSE3
BGRAToARGB_Opt (594 ms)
BGRAToARGB_Endswap_Opt (609 ms)
BGRAToI420_Opt (122 ms)

Now AVX2
BGRAToARGB_Opt (100 ms)
BGRAToARGB_Endswap_Opt (99 ms)
BGRAToI420_Opt (115 ms)

Clang/GCC AVX512BW
BGRAToARGB_Opt (86 ms)
BGRAToARGB_Endswap_Opt (91 ms)
BGRAToI420_Opt (110 ms)


Bug: 42280902
Change-Id: I52cb2b0cacea8f2f0b138ec3cc521185dbef8595
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7905821
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-06-08 12:21:47 -07:00
Wan-Teh Chang
62fffa9eeb Fix integer overflow when flipping negative height
Treat height == INT_MIN as invalid. Omit explicit height == INT_MIN
check if we disallow height < 32768.

Perform multiplications of stride in the ptrdiff_t type.

Add checks for invalid width and height to some functions.

Bug: 518806561
Change-Id: I5e39fffed7f806852a8758d4b59df919839c0a3b
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7891415
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-06-03 16:17:37 -07:00
Frank Barchard
e14b0e2c60 RGB565ToARGB use AVX2 instead of SSE2
Now AVX2/AVX512
ARGB4444ToI420_Opt (204 ms)
RGB565ToI420_Opt (211 ms)
ARGB1555ToI420_Opt (231 ms)
RAWToI420_Opt (197 ms)
RGB24ToI420_Opt (197 ms)

Was SSE2/AVX2
ARGB4444ToI420_Opt (276 ms)
RGB565ToI420_Opt (292 ms)
ARGB1555ToI420_Opt (332 ms)
RAWToI420_Opt (237 ms)
RGB24ToI420_Opt (232 ms)

Bug: libyuv:508639302
Change-Id: I2005189d1b6af15cb5ebef1f6d66b426fa9df8eb
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7891416
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-06-02 18:28:02 -07:00
Wan-Teh Chang
c98edcc8dc Don't coalesce rows if width*height would overflow
Audit all occurrences of "width *= height;" in the libyuv source code.
Make sure height > 0 and (ptrdiff_t)width * height <= INT_MAX before
executing width *= height.

Bug: chromium:517339758
Change-Id: I143a41c66492a6e4c48b6aa2a1c4a2ae974ceeb1
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7883816
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-05-29 11:57:47 -07:00
Frank Barchard
c6c8689c74 Fix I444 and J444 parameter names/order
Bug: libyuv:42280902
Change-Id: Ia2c45f2d996d071534b08381f61adf8cb8ef35b9
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7841767
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-05-12 15:30:35 -07:00
Frank Barchard
4b4e68b372 ABGRToJ420 call ARGBToI420Matrix
- Standardize libyuv ARGB-family (ARGB, ABGR, RGBA, BGRA) to YUV conversion by utilizing the generic MatrixRow architecture and explicit ArgbConstants.
- Consolidated ARGBToI420, ABGRToI420, BGRAToI420, and RGBAToI420 as wrappers for ARGBToI420Matrix.
- Refactored ABGRToJ420, ABGRToJ422, and ABGRToI422 to use generic matrix functions.
- Added matrix-based versions for NV21, I400, YUY2, and UYVY.
- Updated RAW and RGB24 to I420/I422/I444 dispatchers to use MatrixRow logic and explicit constants.
- Fixed parameter swap bugs in ARGBToI422, ARGBToJ422, and ABGRToJ422.
- Fixed a bug in the generic C implementation of matrix row functions ensuring all 4 channels are processed correctly for all ARGB-family formats.
- Moved kShuffleAARRGGBB in row_gcc.cc to the top of the libyuv namespace for visibility.
- Cleaned up redundant format-specific row implementations.

Bug: libyuv:42280902
Change-Id: I67ffa4c476abc0d2dcc4650510d7bda91b65988e
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7830291
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-05-08 15:23:30 -07:00
Frank Barchard
4aacbbdfb4 Refactored RGB/RAW to YUV color conversion functions to use generic Matrix-based functions parameterized by ArgbConstants.
This consolidation standardizes conversion logic, improves code
maintainability, and provides flexible support for various color spaces
(e.g., BT.601, JPEG full
  range).

Key Modifications:
 - Function Consolidation: Refactored several high-level conversion functions into lightweight wrappers around generic Matrix variants:
     - ARGBToI420 → ARGBToI420Matrix
     - ARGBToI444 → ARGBToI444Matrix
     - ARGBToI422 → ARGBToI422Matrix
     - ARGBToNV12 → ARGBToNV12Matrix
     - RAWToJ400, RGB24ToJ400 → RGBToI400Matrix
     - RAWToI444, RAWToJ444 → RGBToI444Matrix
 - 2-Pass Conversions: Updated RGB565ToI420, ARGB1555ToI420, and ARGB4444ToI420 to utilize 2-pass conversions via RGBToI420Matrix.
 - Standardization: Refactored ARGBToNV21, ARGBToYUY2, and ARGBToUYVY to use parameterized matrix row functions (ARGBToYMatrixRow,
   ARGBToUVMatrixRow).
 - Legacy Cleanup: Replaced legacy calls to ARGBToYJRow with the parameterized ARGBToYMatrixRow in the ARGBSobelize helper.
 - Internal Integration: Included libyuv/convert_from_argb.h in planar_functions.cc and ensured all new matrix symbols are properly
   declared/exported (LIBYUV_API).

Bug: libyuv:42280902
Change-Id: Ied5fd9899767427e3a03cdcfbeaff3e9d502374a
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7822033
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-05-06 20:02:47 -07:00
Frank Barchard
125f151316 ARGBToNV12 use Matrix
Refactored Matrix functions (ARGBToI420Matrix, ARGBToI422Matrix, ARGBToI444Matrix and ARGBToNV12Matrix)
  and updated their CPU dispatch logic.

ARGBToNV12 clang
 68.05% ARGBToUVMatrixRow_AVX512BW
 21.04% ARGBToYMatrixRow_AVX512BW
  2.88% MergeUVRow_AVX512BW

ARGBToNV12 rowwin
 61.26% ARGBToUVMatrixRow_AVX2
 25.43% ARGBToYMatrixRow_AVX2
  3.09% MergeUVRow_AVX2

ARM on One Plus 15
 42.98% libyuv::ARGBToUVMatrixRow_SVE_SC()
 38.95% ARGBToYMatrixRow_NEON_DotProd
  2.96% MergeUVRow_NEON
  0.18% ARGBToUVMatrixRow_SVE2

ARGBToI420
 72.28% ARGBToUVMatrixRow_AVX512BW
 19.04% ARGBToYMatrixRow_AVX512BW

ARGBToI422
 77.46% ARGBToUVMatrixRow_AVX512BW
 15.55% ARGBToYMatrixRow_AVX512BW

ARGBToI444
 67.03% ARGBToYMatrixRow_AVX512BW
 24.80% ARGBToUV444MatrixRow_AVX512BW

Bug: libyuv:42280902
Change-Id: I463ebcdb70cb669a1ce1a81102b8fd2fb3943bd3
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7819051
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-05-05 18:17:19 -07:00
Frank Barchard
2143edfa7a ARGBToUVMatrixRow_NEON arm32 reimplemented for GCC
Bug: libyuv:508639302
Change-Id: Ib120373d799c66926a64c980873034be262d8848
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7810481
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Justin Green <greenjustin@google.com>
2026-05-04 11:38:45 -07:00
Frank Barchard
f2ac6db694 RAWToNV21 using SME, SVE, I8MM or Neon
Pixel 9 Now SVE2 2 pass LibYUVConvertTest.RAWToNV21_Opt (364 ms)
 31.76% libyuv::ARGBToUVMatrixRow_SVE_SC()
 30.38% RAWToARGBRow_SVE2
 26.81% ARGBToYMatrixRow_NEON_DotProd
  3.26% MergeUVRow_NEON

Was NEON 1 pass LibYUVConvertTest.RAWToJNV21_Opt (295 ms)
 44.14% RAWToYJRow_NEON
 41.91% RAWToUVJRow_NEON
  5.11% MergeUVRow_NEON

Clang on Intel Skylake clang [ OK ] LibYUVConvertTest.RAWToJNV21_Opt
(301 ms) visual c (row_win) [ OK ] LibYUVConvertTest.RAWToJNV21_Opt
(2056 ms)

clang [ OK ] LibYUVConvertTest.RAWToJNV21_Opt (275 ms) visual c [ OK ]
LibYUVConvertTest.RAWToJNV21_Opt (365 ms)

Bug: libyuv:42280902
Change-Id: Iaba558ebe96ce6b9881ee9335ba72b8aac390cde
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7802432
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
2026-04-29 13:11:04 -07:00
Frank Barchard
4afb965416 RAWToARGB use AVX512BW
Bug: libyuv:42280902
Change-Id: I7a80fd64d97b6d411316819df0fd917d609a173b
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7787163
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-04-22 16:56:46 -07:00
Frank Barchard
bd2c4c76ec RAWToARGB AVX512VBMI
Bug: libyuv:42280902
Change-Id: I1c7f432f004079357a00515785bc524c459ed4b9
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7787160
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-04-22 14:48:29 -07:00
Frank Barchard
d445250d8b Replace RAWToY/RGB24ToY with RGBToYMatrix
Bug: libyuv:42280902
Change-Id: I6ddebd492036c416550fc045eb39493dea73246b
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7784094
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-04-21 17:11:14 -07:00
Frank Barchard
81f698829b Add RGBToNV21Matrix function
- implement wrappers with RAW, RGB24, NV21 and JNV21 to call it.

Zen5
Was [       OK ] LibYUVConvertTest.RAWToJNV21_Opt (1146 ms)
Now [       OK ] LibYUVConvertTest.RAWToJNV21_Opt (1446 ms)
reason - the new code uses 1 pass for RAWToY but 2 pass for RAWToARGB,ARGBToUV.  needs 1 RGBToUV

Bug: libyuv:42280902
Change-Id: Ife6fbed0829484045409e6d42b85cec1d1fd6052
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7780026
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-04-20 18:03:34 -07:00
Frank Barchard
9f13b2814d add RGBToYMatrixRow_AVX2
Adds RGBToYMatrixRow_AVX2 which reads 24 bit RGB values by reading 3 vectors instead of 4 and permutes them into 4 ARGB vectors before conversion.
Also adds RGBToYMatrixRow_Opt and RGBToYMatrixRow_2Step_Opt to convert_argb_test.cc to benchmark and compare the direct AVX2 conversion vs a 2-step approach.

./libyuv_test '--gunit_filter=*RAWToJ400_Opt' --libyuv_width=1280 --libyuv_height=720 --libyuv_repeat=10000 --libyuv_flags=-1 --libyuv_cpu_info=-1

AMD Zen 5
Was LibYUVConvertTest.RAWToJ400_Opt (757 ms)
Now LibYUVConvertTest.RAWToJ400_Opt (699 ms)

Intel Skylake
Was LibYUVConvertTest.RAWToJ400_Opt (1705 ms)
Now LibYUVConvertTest.RAWToJ400_Opt (1426 ms)

Bug: 477295731
Change-Id: I29866baf4ad5fe7a3725e4a01f2fe24649510a7d
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7777325
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
Reviewed-by: Justin Green <greenjustin@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
2026-04-20 12:52:44 -07:00
Frank Barchard
ace7c4573c Add ARGBToUV444MatrixRow_RVV, ARGBToUVMatrixRow_RVV, and wrappers
This change implements ARGBToUV444MatrixRow_RVV, ARGBToUVMatrixRow_RVV,
and their wrappers (ARGBToUVRow_RVV, ARGBToUVJRow_RVV, etc.) using RVV
intrinsics, mirroring the NEON/AVX2 designs. It wires them into the
build and dispatch systems.

LIBYUV_RVV_HAS_TUPLE_TYPE is always true on new compilers. This macro
has been removed, assuming it is true everywhere, reducing the amount of
code in row_rvv.cc, scale_rvv.cc, and row.h.

Tested via: ~/bin/doyuv3v && ~/bin/runyuv3v TestARGBToI444Matrix
~/bin/doyuv3av

Bug: libyuv:42280902
Change-Id: I36d305386b297d69023c068aa9c62ab6b2ad039c
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7769956
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
2026-04-16 20:52:43 -07:00
Frank Barchard
e034c41661 Port ARGBToUVMatrixRow from AVX2 to AVX512BW
Benchmark on Icelake Xeon
Now AVX512BW:
[       OK ] LibYUVConvertTest.ARGBToNV12_Opt (1723 ms)
Was AVX2:
[       OK ] LibYUVConvertTest.ARGBToNV12_Opt (2144 ms)

- Added `ARGBToUVMatrixRow_AVX512BW` implementation in `source/row_gcc.cc`.
- Added corresponding `ARGBToUVRow_AVX512BW` and `ABGRToUVRow_AVX512BW` functions.
- Added unaligned wrappers `ARGBToUVRow_Any_AVX512BW` and `ABGRToUVRow_Any_AVX512BW` in `source/row_any.cc`.
- Updated `source/row_any.cc` to correctly size `vin` and `vout` buffers for AVX512BW width and adjusted the `ANY12MS` and `ANY12S` macros to handle `MASK=63`.
- Updated `include/libyuv/row.h` with the required AVX512BW headers and definitions, scoped appropriately.
- Wired all callers of `ARGBToUVRow_AVX2` and related functions in `source/convert.cc` and `source/convert_from_argb.cc` to dynamically use the `AVX512BW` implementations if the CPU flag indicates AVX-512BW support.
- Optimized AVX-512 code to generate the `-1` multiplier in a single instruction (`vpternlogd`) and reused it across word (`vpmaddwd`) dot products. Handled the resulting negation by replacing a subtraction with `vpaddw` offset adjustment.

Bug: 477295731
R=dalecurtis@chromium.org, rrwinterton@gmail.com

Change-Id: Ida5fb27e59ae4c1c3824737f009b80549cd20a06
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7763257
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
2026-04-14 16:15:31 -07:00
Frank Barchard
cbc64c353c Port ARGBToYRow_AVX2 usages to dynamically use ARGBToYRow_AVX512BW
I have successfully ported the usage of ARGBToYRow_AVX2 to dynamically detect and utilize ARGBToYRow_AVX512BW when available.

  Here's a summary of the changes:
   1. Source Modifications: In both source/convert.cc and source/convert_from_argb.cc, I searched for all references where ARGBToYRow_AVX2 was
      being conditionally used (which operates on 32 pixels).
   2. AVX512BW Detection: Immediately following those blocks, I injected a new check for kCpuHasAVX512BW. If the CPU flag is present, the logic
      now utilizes ARGBToYRow_Any_AVX512BW by default, falling back to the fully aligned ARGBToYRow_AVX512BW when the width is aligned to 64
      bytes.
   3. Profiling: After building and compiling the tests (doyuv3x), I validated the change using perfyuv3 ARGBToNV12_Opt | cat. The test
      successfully executed and the performance profile indicated that ARGBToYRow_AVX512BW successfully executed (taking up ~18% of CPU cycles,
      replacing the previous AVX2 specific instruction overhead for the Y row extraction).

  The HAS_ARGBTOYROW_AVX512BW macro implementation now fully supports all AVX2 conversion paths to utilize AVX512BW when the system processor
  flags allow it!

R=richard, rrwinterton@gmail.com

Change-Id: Iad811e12d301f5621e6f6d039105420861ade43e
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7760779
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-04-14 11:42:59 -07:00
Frank Barchard
893eacf9b4 ARGBToY for AVX512
- add ARGBToYMatrixRow_AVX512BW
- refactor SSE and AVX to use Matrix functions, making old functions
  call the new ones.

Zen5 1280x720
Was AVX2   LibYUVConvertTest.ARGBToI444_Opt (1125 ms)
Now AVX512 LibYUVConvertTest.ARGBToI444_Opt (641 ms)

Details by Gemini:
  1. Created 3 new Matrix functions:
    Added ARGBToYMatrixRow_SSSE3, ARGBToYMatrixRow_AVX2, and
    ARGBToYMatrixRow_AVX512BW to source/row_gcc.cc. These take the
    const struct ArgbConstants* c parameter similarly to
    ARGBToUV444MatrixRow_*. The x86 vector instructions dynamically
    calculate the needed values using the properties of the constants
    struct, including using vpmaddwd inside the AVX512 code to offset
    the lack of a native vphaddw.

  2. Replaced Old Functions with Wrappers:
    Modified the existing implementations of ARGBToYRow_SSSE3,
    ARGBToYJRow_SSSE3, ABGRToYRow_SSSE3, ABGRToYJRow_SSSE3,
    RGBAToYRow_SSSE3, RGBAToYJRow_SSSE3, BGRAToYRow_SSSE3 (and their
    _AVX2 equivalents) in source/row_gcc.cc to act as inline wrappers
    calling the new ARGBToYMatrixRow_* functions, passing the right
    matrix parameters (e.g. &kArgbI601Constants, &kArgbJPEGConstants,
    &kAbgrI601Constants).

  3. Added row_any.cc Handlers:
    Added ANY11MC definitions to source/row_any.cc to autogenerate
    ARGBToYMatrixRow_Any_SSSE3, ARGBToYMatrixRow_Any_AVX2, and
    ARGBToYMatrixRow_Any_AVX512BW which safely handles non-aligned
    tails.

  4. Updated include/libyuv/row.h:
    Updated the headers with the proper void declarations for all newly
    generated Matrix and Any_ variants. Also defined
    HAS_ARGBTOYROW_AVX512BW in the CPU macros.

  5. Tested the Implementations:
    Compiled and tested on Linux x86, which resulted in all tests passing
    cleanly. Also successfully completed all Windows 32-bit build checks
    ensuring 32-bit regression prevention without issues.

Bug: 477295731
Change-Id: I4f5eec9a961e24a9d760d0a1c0810fb5e29a0bd1
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7759494
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-04-13 17:26:07 -07:00
Frank Barchard
4c3d7d517a ARGBToUV444 for AVX512
1.27x faster on AMD Zen5 (turin)

Now AVX512
perf record ./libyuv_test '--gunit_filter=*ARGBToI444_Opt' --libyuv_width=1280 --libyuv_height=720 --libyuv_repeat=10000 --libyuv_flags=-1 --libyuv_cpu_info=-1

[       OK ] LibYUVConvertTest.ARGBToI444_Opt (1071 ms)
Overhead  Symbol
  53.49%  ARGBToYRow_AVX2
  44.70%  ARGBToUV444Row_AVX512BW

Was AVX2
[       OK ] LibYUVConvertTest.ARGBToI444_Opt (1369 ms)
  61.06%  ARGBToUV444Row_AVX2
  37.67%  ARGBToYRow_AVX2

Bug:  libyuv:42280902
Change-Id: I306fbac656d6f7834ce1559e86d01eb34931ec3c
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7738362
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
2026-04-08 19:25:41 -07:00
Dale Curtis
1170363ce5 Add Gemini implementation for NEON32 RGB to YUV matrix operations
These are about 25% faster than the C versions.

Bug: libyuv:42280902

Change-Id: I8b298670ee5f3ed5db35527fc41d6d9a51b020a1
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7573682
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
2026-03-23 16:30:44 -07:00
Frank Barchard
4183733af5 Rename MergeUVRow_ variable to MergeUVRow
Bug:  libyuv:42280902
Change-Id: I9935bf958b901ddf84cf91b2097c8cd5d6efadde
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7683070
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
2026-03-18 17:18:25 -07:00
Dale Curtis
b1cacfb38f Unify X86/X64 versions of ARGBToI4xxMatrix functions
Change-Id: Iead13414414543e5f10ba9ba47a6ceaeb3113dee
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7562443
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-03-18 16:27:07 -07:00
Dale Curtis
f69a479f04 Add ARGBToNV12Matrix implementation
This one reuses the SIMD implementations for MergeUVRow_ from the
existing ARGBToNV12 functions.

Bug: libyuv:42280902
Change-Id: If0a4be133d657ed0262f29fdd568dac90b49636c
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7564317
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
2026-03-18 16:26:59 -07:00
Dale Curtis
2c21d57319 Add ABGR versions of the ArgbConstants structures
This allows for ABGR conversion using the same methods

Bug: libyuv:42280902
Change-Id: I5566e3150b30573a2326a900ce31ab095f8935f9
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7564316
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-03-17 17:28:51 -07:00