3041 Commits

Author SHA1 Message Date
Frank Barchard
a0fa632939 Add AVX2 row functions for RGB565, ARGB1555, and ARGB4444
On Icelake:
Was C
I420ToARGB1555_Opt (1230 ms)
I420ToARGB4444_Opt (1195 ms)
I420ToRGB565_Opt (1141 ms)

Now AVX2
I420ToARGB1555_Opt (372 ms)
I420ToARGB4444_Opt (397 ms)
I420ToRGB565_Opt (347 ms)
I420ToRGB24Filter_Opt (567 ms)
I420ToRGB565Dither_Opt (418 ms)
I420ToARGBFilter_Opt (381 ms)
I420ToRGBA_Opt (304 ms)
I420ToBGRA_Opt (296 ms)
I420ToARGB_Opt (257 ms)
I420ToABGR_Opt (254 ms)
I420ToAR30_Opt (215 ms)
I420ToRGB24_Opt (205 ms)
I420ToRAW_Opt (193 ms)

Bug: None
Change-Id: I36cf95d29ba85ae63c549fef7f55cb1fe0f95d8e
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8282746
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-08-24 19:41:39 -07:00
Sida Zhu
ae48f8dd61 Fix same-width vertical point upsampling
ScalePlane's same-width vertical fast path used the endpoint-oriented
FixedDiv1 step for all upsampling. That stepping is appropriate for
bilinear interpolation, but not for point sampling, where source rows
should cover equally sized destination cells.

Use the same centered FixedDiv stepping as the generic point sampler.
Allow the point path to select the final source row while passing a
zero interpolation stride so row kernels cannot form a pointer beyond
it. Add 8-bit and 16-bit point regression coverage and verify that
bilinear upsampling remains unchanged.

Bug: 537818862
Change-Id: I7bee21b85913b31c146ecf7fe9f5f08608a8a17d
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8264449
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-08-24 19:28:50 -07:00
Wan-Teh Chang
196d9aa2f1 Remove four unused macros in row_win.cc
The READYUV444, READYUVA444, READYUVA422, and STOREARGB macros are
defined but not used.

Change-Id: Ic1174b5b9c7dc8554f362871de73080c32a58537
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8279223
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-24 19:27:06 -07:00
Frank Barchard
5689f16923 Refactor multi-stage SSSE3 scalers into single asm blocks
Consolidate split asm volatile blocks into single blocks across SSSE3
scaling functions in scale_gcc.cc. This prevents potential register
corruption or clobbering by compiler optimizations between disjoint
asm blocks, and uses named operand constraints for clarity and safety.

List of affected functions in scale_gcc.cc:
- ScaleRowDown34_SSSE3: merge 2 asm blocks into 1
- ScaleRowDown34_1_Box_SSSE3: merge 3 asm blocks into 1
- ScaleRowDown34_0_Box_SSSE3: merge 3 asm blocks into 1
- ScaleRowDown38_2_Box_SSSE3: merge 2 asm blocks into 1
- ScaleRowDown38_3_Box_SSSE3: merge 2 asm blocks into 1
- ScaleARGBFilterCols_SSSE3: merge 2 asm blocks into 1

Test: ninja -C out/Release libyuv_unittest && ./out/Release/libyuv_unittest
Test: ninja -C out/Release_x86 libyuv_unittest && ./out/Release_x86/libyuv_unittest
Bug: 489489002
Change-Id: I900a590db2ef21b9f019a115699d3a270877ed28
TAG=agy
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8280666
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-08-24 18:05:48 -07:00
Frank Barchard
ba68378488 Fix off by 32 rounding for I420ToAR30
- x86 SSSE3 / AVX2 / AVX-512: subtract 24 in YUVTORGB_SETUP_AR30
- ARM NEON64: adjust BB (+24), BG (-24), BR (+24) in YUVTORGB_SETUP_AR30
- Windows MSVC AVX2 / AVX-512BW: subtract 24 from kYBiasToRgb
- C reference: adjust Yb in LOAD_YUV_CONSTANTS_AR30
- Unit tests: add +0.5 rounding to expected 10-bit Y reference

Bug: 551985141
Change-Id: I2bc418edb2d6efb76b4fb1c6bc01205525f4a49c
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8280769
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-08-24 13:52:04 -07:00
Wan-Teh Chang
553f01170b Check rotate_any.cc and scale_any.cc for overflows
Inspect all the ANY macros.

Change-Id: Icdf382181572b34490e0830d1a0a14286b84faaf
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8266561
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-24 11:40:53 -07:00
Wan-Teh Chang
72e5a16aee Remove magjed from OWNERS
Change-Id: Ie4c1c5e25c68653d3d918584938c1ea0f94c84ac
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8269401
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-08-24 10:43:21 -07:00
Frank Barchard
44d9bc68f2 STOREAR30 remove initial shift by 4
- reduced shifts to isolate 10 bits
- permi2w instead of packlwd to combine words (ARG) (GB) into ARGB
- vpternlogd to combine A,R,G into 1 register

Saphhire Rapids 10000 iterations of 1280x720P:
Conversion Kernel     │   Was     │    Now     │  Speedup
──────────────────────┼────────────────────────┼────────────────
I420ToAR30_Opt        │  1675 ms  │   1568 ms  │    +7.1%
H420ToAR30_Opt        │  1632 ms  │   1555 ms  │    +5.2%
I210ToAR30_Opt        │  2459 ms  │   2167 ms  │   +13.5%
P010ToAR30_Opt        │  2054 ms  │   1926 ms  │    +6.6%
P016ToAR30_Opt        │  2043 ms  │   1938 ms  │    +5.4%
Total Test Suite Time │ 9,866 ms  │  9,155 ms  │    +7.8% overall

Bug: None
Change-Id: I7972f98408a65a2bb51c506145e4c0c63824c424
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8259796
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-08-21 11:57:41 -07:00
Frank Barchard
8d7ed8af35 Fix undeclared register clobbers in x86 and NEON assembly
List of affected functions:
- ARGBToAB64Row_SSSE3 (row_gcc.cc): add xmm3 clobber
- ARGBToAB64Row_AVX2 (row_gcc.cc): add xmm3 clobber
- ARGBToAB64Row_NEON (row_neon64.cc): add v5, v6, v7 clobbers
- ARGBToUV444MatrixRow_NEON (row_neon.cc): add q13 clobber
- ARGBSepiaRow_NEON_DotProd (row_neon64.cc): add v23 clobber
- I422ToRGB24Row_NEON (row_neon.cc): remove dead d6 mutation
- I422ToRGB565Row_NEON (row_neon.cc): remove dead d6 mutation
- MergeAR64Row_NEON (row_neon.cc, row_neon64.cc): add q14, v30 clobbers
- MergeXR30Row_AVX2 (row_gcc.cc): add xmm6 clobber
- MergeXR64Row_NEON (row_neon.cc, row_neon64.cc): add q14, v30 clobbers
- NV12ToRGB24Row_NEON (row_neon.cc): remove dead d6 mutation
- NV12ToRGB565Row_NEON (row_neon.cc): remove dead d6 mutation
- NV21ToRGB24Row_NEON (row_neon.cc): remove dead d6 mutation
- RGBToUV444MatrixRow_NEON (row_neon.cc): add q13 clobber
- ScaleRowDown2Box_SSSE3 (scale_gcc.cc): add xmm4 clobber
- ScaleRowDown2Box_AVX2 (scale_gcc.cc): add xmm4 clobber
- SobelToPlaneRow_SSE2 (row_gcc.cc): remove dead xmm5 mutation
- UYVYToARGBRow_SSSE3 (row_gcc.cc): add xmm6, xmm7 clobbers

Test: ninja -C out/Release libyuv_unittest && ./out/Release/libyuv_unittest
Bug: 489489002
Change-Id: I0a8794be0423ef36d679a45e276738c2e42d2fb8
TAG=agy
CONV=16035e35-dcc9-4b8f-90f7-f17b299bc523
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8258080
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-08-20 20:31:22 -07:00
Alex Ovsienko
28ce69c274 [DEPS] Add CPython CIPD package for hermetic Python toolchain
Add src/third_party/cpython3 CIPD packages for Linux and host platforms
('\''infra/3pp/tools/cpython3/${platform}'\'' at '\''version:3@3.11.9.chromium.38'\'').

This enables hermetic Python execution in Siso builds where Siso configs
inherited from build/ require the hermetic Python binary at
src/third_party/cpython3/linux-amd64/bin/python3 on remote workers.

Bug: chromium:537680330
Change-Id: I439b2af56dcc5f325ec6f3dbe2837cf550e5c0d2
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8266781
Reviewed-by: Mirko Bonadei <mbonadei@chromium.org>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Commit-Queue: Alex Ovsienko <ovsienko@google.com>
2026-08-19 20:31:30 -07:00
Frank Barchard
e808cf543e STOREAR30 macro improvement for I420ToAR30 etc
Bug: None
Change-Id: I163e8da5b223a928df9341f3f8819c56f76ea5e8
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8268434
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-08-19 15:52:36 -07:00
Wan-Teh Chang
fdaa609a4f OWNERS: List mbonadei after fbarchard and wtc
Change-Id: I05d68f8d9c033595db23c3e20a9f64300ab3048b
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8269632
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-08-19 14:02:35 -07:00
Frank Barchard
fd64b1b5ab Fix unit test buffer sizes and skip large allocation on MSan
In P010ToARGBMatrixFilterOverflow, P210ToARGBMatrixFilterOverflow,
P010ToAR30MatrixFilterOverflow, and P210ToAR30MatrixFilterOverflow,
the tests set src_stride_uv to width (1039) and allocated
width * src_uv_height elements. For odd widths, the interleaved UV
row requires (width + 1) & ~1 elements (1040). Using width for the
stride and buffer size caused the second row to read past the allocated
buffer and access uninitialized memory under MSan.
Fix this by computing src_stride_uv = (width + 1) & ~1 and sizing the
allocated buffer to src_stride_uv * src_uv_height.

In TestI400LargeSize, the test attempts large allocations totaling
over 10 GB (~2 GB for source and ~8.5 GB for destination). Under
MemorySanitizer (MSan), large allocations can exceed shadow memory
virtual address limits or assert. Skip this test under MSan by checking
__SANITIZE_MEMORY__ and __has_feature(memory_sanitizer).

Test: libyuv_unittest --gtest_filter=*FilterOverflow*:*I400Large*
Bug: 549112862
Change-Id: I679b7c67d93822e83f066b1895924589fc7242e7
TAG=agy
CONV=dd635180-175b-4e35-b7f0-2e38105d3506
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8269585
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-19 12:52:21 -07:00
George Steed
50bfd8fc08 AArch64: Avoid INCP in {YUY2,UYVY}ToUVRow_SVE2
The INCP instructions are particularly slow on some CPUs and in this
case can be replaced by a simple ADD instruction, so use that instead.

Reduction in time taken relative to the existing SVE2 code for
{YUY2,UYVY}ToUVRow_SVE2:

       Cortex-A510: −12.1%
     Lumex C1-Nano:   0.0%
       Cortex-A720:   0.0%
      Lumex C1-Pro:   0.0%
         Cortex-X4: −20.9%
    Lumex C1-Ultra: −20.3%

Bug: 546962730
Change-Id: Iea3d75f7b70fe8a29f12afdd877ac02d43e49f04
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8252282
Reviewed-by: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-19 11:25:07 -07:00
Frank Barchard
210d11f747 READI422 macro improved for avx512 vpermw
- speeds up I420ToARGB etc

Granite Rapids
Now
I420ToARGB_Opt (100 ms)
I420ToAR30_Opt (135 ms)
Was
I420ToARGB_Opt (109 ms)
I420ToAR30_Opt (147 ms)

Bug: None
Change-Id: I70b9356dfbd98f28f07bfe9d8a44f0107435a26f
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8265437
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-08-18 15:31:51 -07:00
Frank Barchard
0f36c7f808 STORERGB24 macros for avx512
- improves I420ToRAW performance

I420ToRAW on Skylake
  Was AVX2
    I420ToRAW_Opt (262 ms)
  Now AVX512
    I420ToRAW_Opt (212 ms)

I420ToRAW on Icelake with avx512vbmi
  Was I420ToRAW_Opt (200 ms)
  Now I420ToRAW_Opt (187 ms)

Bug: None
Change-Id: If5b171801ba931557d379696fc128d9b155f7c44
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8267746
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-08-18 14:18:47 -07:00
George Steed
26e56be0f9 GEMINI.md: Update Arm wording and guidance
Update trademarks, document `arm_sve.h` and add guidance to prefer fully
predicated loop iterations for SVE/SME implementations.

Change-Id: I4039b982ba816193019df62a523fd29f474c3d10
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8256407
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-08-18 11:21:14 -07:00
George Steed
f61a589bb3 AArch64: Fix {YUY2,UYVY}ToUVRow_SVE2 tail predication
The tail LD2B predicate previously used the raw remaining width, however
for odd widths this is incorrect. We already calculate the correct
halved predicate for the UV store part so just compute the load
predicate from that directly.

Bug: 546962730
Change-Id: I59654208ea48eb5bcc6261a63cb90abae58c1668
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8252280
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-18 10:50:05 -07:00
Wan-Teh Chang
c8e8b70460 Remove Disabled comment: HAS_ARGBTOYMATRIXROW_SME
The "Disabled:" comment for HAS_ARGBTOYMATRIXROW_SME was left behind
when we re-enabled HAS_ARGBTOYMATRIXROW_SME.

Bug: 546962730
Change-Id: Id21fb368a5233bed9f9733d8a54bce3ed0751f47
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8263125
Reviewed-by: George Steed <george.steed@arm.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-17 17:44:57 -07:00
Frank Barchard
1b7af2e5a9 HalfWidthRow_16To8_SSSE3 fix 32 bit build pmaddwd constant 2
Test: compile for android_x86 (32 bit)

Was
source/row_gcc.cc:5524:7: error: inline assembly requires more registers than available
 5524 |       "movd        %4,%%xmm2                     \n"
      |       ^

Bug: b/547388714
Change-Id: I5aa01516c2fd7e8c37fad72fa044a7e51d7410b8
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8265047
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-17 15:14:53 -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
Wan-Teh Chang
fc8c2359fe SAROW() should memset src_temp for msan
It is the temporary input buffer, not the temporary output buffer, that
needs to be zero-initialized for msan.

This mistake may have been introduced because dst_temp was declared
before src_temp. So swap their declarations.

Change-Id: I74691afe51a7d84187fc0decbc83f2c970cf52b7
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8261587
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-17 13:05:33 -07:00
Frank Barchard
7badb217b9 HalfWidthRow_16To8_SSSE3 fix 32 bit build using width on stack
Test: compile for android_x86 (32 bit)
Was
source/row_gcc.cc:5524:7: error: inline assembly requires more registers than available
 5524 |       "movd        %4,%%xmm2                     \n"
      |       ^

Bug: b/547388714
Change-Id: Ie2b847dff15a9c6ba190a934ca303906fc53d127
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8253314
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-08-17 11:20:28 -07:00
Frank Barchard
0da8e419df ARGBToYMatrixRow_SVE2 fix for ARGBToI400
- set full accumulators to 0
 - uzp1 to convert uint16 to uint8

Bug: 546962730
Change-Id: I19334c3d0da479348f0c1df0a892ca76eb7acc23
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8263170
Commit-Queue: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-16 16:31:32 -07:00
Wan-Teh Chang
5bbceb1bb2 Disable SVE2 functions that caused test failures
The following macros are disabled because they caused test failures:
    HAS_ARGBTOYMATRIXROW_SVE2
    HAS_HALFMERGEUVROW_SVE2
    HAS_UYVYTOUVROW_SVE2
    HAS_YUY2TOUVROW_SVE2

HAS_ARGBTOYMATRIXROW_SME is also disabled because ARGBToYMatrixRow_SME()
has the same code as ARGBToYMatrixRow_SVE2().

Bug: 546962730
Change-Id: Ic590e809443585ee66c609ff8ba6b6f0e40300c9
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8261763
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-08-16 14:06:11 -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
1dac06e8c0 Fix ARM NEON and SVE2 register constraints for ARGBToRGB565DitherRow
- Add register z2 to the inline assembly clobber list in ARGBToRGB565DitherRow_SVE2.
    - Fix operand constraints and register indexes for src_argb, dst_rgb, and width in ARGBToRGB565DitherRow_NEON to properly use '+r' for modified
  operands.

Bug: None
Change-Id: I521c5b37dc37e2bcbe910f72c389144b1491e9dc
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8261579
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-14 12:49:04 -07:00
Frank Barchard
9f05e62032 Fix HalfWidthRow_16To8 test buffer allocations and stride
HalfWidthRow_16To8 downsamples 2x2 16-bit pixels to 8-bit.
For width output pixels, row 0 and row 1 each require width * 2 uint16_t
elements (4 * width bytes).
With two rows separated by src_uv_stride, total source buffer requirement
is 8 * width bytes (4 * width uint16_t elements).

The previous buffer allocation only allocated kPixels * 4 bytes
(2 * kPixels uint16_t elements).
Because align_buffer_page_end places the buffer at the end of a page,
reading the second row caused an out-of-bounds access past the page
boundary, failing the test:

[ RUN      ] LibYUVPlanarTest.HalfWidthRow_16To8_Opt
[  FAILED  ] LibYUVPlanarTest.HalfWidthRow_16To8_Opt
[----------] Global test environment tear-down
[==========] 3603 tests from 8 test suites ran.
[  PASSED  ] 3602 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] LibYUVPlanarTest.HalfWidthRow_16To8_Opt

 1 FAILED TEST.

Use align_buffer_page_end_16 to allocate 4 * width uint16_t elements
(8 * width bytes) and set src_uv_stride to 2 * width elements
in HalfWidthRow_16To8_Opt and HalfWidthRow_16To8_Any.

Bug: None
Test: LibYUVPlanarTest.HalfWidthRow_16To8_*
Change-Id: Ieba81ec211a34cc315e60fc26aad64fb41a88641
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8252627
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-14 12:16:02 -07:00
Frank Barchard
c20b35a7bc I420ToAR30 add avx512bw support
Benchmark for 720p 1000 images
CPU Architecture          AVX2 (us)   AVX512 (us)   Speedup    Change
---------------------------------------------------------------------
Intel Skylake                325          229        1.42x     -29.5%
Intel Cascade Lake           289          213        1.36x     -26.3%
Intel Granite Rapids         209          168        1.24x     -19.6%
AMD Zen 4                    168          165        1.02x      -1.8%
AMD Zen 5 (Turin)            180          112        1.61x     -37.8%

Bug: None
Change-Id: I3d07c9b36196305ba7ff63973246c080ff872367
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8251940
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
2026-08-13 15:40:19 -07:00
Dale Curtis
3f42e3840b Scale*BilinearUp: Add invariants assertions and simplify loop
In ScaleARGBBilinearUp, ScalePlaneBilinearUp, ScalePlaneBilinearUp_16,
and ScaleUVBilinearUp, dy is strictly < 65536 (dy < 1.0 in 16.16 fixed
point), so yi (y >> 16) advances strictly in unit increments (0 -> 1 ->
2 -> ... -> H - 1).

Because yi transitions across each integer row in sequence:
- src is primed at row 2 and incrementally advanced by 1 row on each
  integer transition while (y + 65536) < max_y.
- When y >= max_y - 65536, src increments stop, leaving src pointing to
  the final row (H - 1).
- Therefore, src is always pointing to row yi + 1 before each buffer
  swap, making the inner 'src = src_ptr + yi * src_stride' recomputation
  and nested 'if (yi != lasty)' checks redundant.

Bug: 540206290, 539110937
Test: LibYUVScaleTest.*
Change-Id: Ic5cc5c601d4771e9df8b9a882df2f7f3e6777b23
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8252878
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-13 14:20:11 -07:00
Dale Curtis
2e58f4b971 ARGBScale: Fix signed integer overflow when scaling large heights
In ScaleARGBBilinearDown and ScaleARGBBilinearUp, adding dy to y can
overflow signed 32-bit int when scaling down large height images (e.g.,
src_height = 32768 down to 2). Check if max_y - dy < y before adding dy
to y to prevent signed integer overflow.

R=wtc

Fixed: 540206290, 539110937
Test: LibYUVScaleTest.ARGBScale_LargeHeightOverflow
Change-Id: If353d002714481ce0018653798047066663f1fb9
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8175358
Reviewed-by: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
2026-08-12 15:49:52 -07:00
Wan-Teh Chang
79d22698bc Add static_assert to source/row_any.cc
Bug: chromium:543078936
Change-Id: Idd25a8cd987e5295788173dce3cc2ec8c55e9bff
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8230873
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-11 18:28:15 -07:00
Frank Barchard
eac1ea9744 I410ToI420 use 1 step HalfWidthRow function for UV
On Icelake
Was C+AVX512
I410ToI420_Opt (593 ms)
I412ToI420_Opt (581 ms)
Now AVX512
I410ToI420_Opt (241 ms)
I412ToI420_Opt (227 ms)
 60.28% HalfWidthRow_16To8_AVX512BW
 32.34% Convert16To8Row_AVX512BW

Samsung S25 Oryon
Was C+NEON
I410ToI420_Opt (141 ms)
I412ToI420_Opt (127 ms)
Now NEON
I410ToI420_Opt (89 ms)
I412ToI420_Opt (88 ms)

Vivo X300 lunix c1
Was C+NEON
I410ToI420_Opt (682 ms)
I412ToI420_Opt (679 ms)
With SVE2 (slow)
I410ToI420_Opt (622 ms)
I412ToI420_Opt (584 ms)
 65.59% HalfWidthRow_16To8_SVE2
 26.74% Convert16To8Row_SVE2
Now NEON
I410ToI420_Opt (412 ms)
I412ToI420_Opt (406 ms)

Bug: chromium:531172025
Change-Id: I1732157f6be660d2a01086f21daf85fe7f7d166f
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8230200
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-10 18:19:25 -07:00
Wan-Teh Chang
c409140ff6 Correct vin/vout buffer sizes in ANY21S and ANY13
Tested:
libyuv_unittest --gtest_filter=LibYUVConvertTest.YUY2ToNV12Overflow
libyuv_unittest --gtest_filter=LibYUVPlanarTest.SplitRGBPlaneOverflow
libyuv_unittest --gtest_filter=LibYUVPlanarTest.SplitARGBPlaneOverflow

Bug: chromium:543078936
Change-Id: I45cc5ec912612b09ac720e3bdefa11c8ad503098
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8219514
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-10 14:20:54 -07:00
Wan-Teh Chang
e2a1744681 Correct vin/vout buffer sizes in ANY21CT
Tested:
libyuv_unittest --gtest_filter=LibYUVConvertTest.P010ToARGBMatrixFilterOverflow
libyuv_unittest --gtest_filter=LibYUVConvertTest.P210ToARGBMatrixFilterOverflow
libyuv_unittest --gtest_filter=LibYUVConvertTest.P010ToAR30MatrixFilterOverflow
libyuv_unittest --gtest_filter=LibYUVConvertTest.P210ToAR30MatrixFilterOverflow

Bug: chromium:543078936
Change-Id: I7001c21d3ef9f7a01bf884332ea6ccbdfd7a69d0
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8229574
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-08-10 13:47:24 -07:00
Wan-Teh Chang
60c4b08950 Use standard way of applying ptrdiff_t casts to n
Remove unnecessary ptrdiff_t casts on r.

Change-Id: I36cf40ea1891a9b0e1c3b1ec2f73559040f243b6
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8229575
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-10 10:32:01 -07:00
Frank Barchard
9c5d5c1e55 InterpolateRow_NEON/SVE2 and InterpolateRow_16_NEON/SVE2 use 2 registers
Replace rshrn2 with 2 8 byte registers and stp

All benchmarks run at 1280×720, 1000 iterations (taskset c0):

Function (1280x720 1000x)     | OldNEON | NewNEON | OldSVE2 | NewSVE2
-------------------------------+---------+---------+---------+--------
TestInterpolatePlane (8-bit)   |   76 ms |   66 ms |  125 ms |   34 ms
TestInterpolatePlane_16        |  195 ms |   66 ms |  195 ms |   64 ms
TestARGBInterpolate (50/50)    |  104 ms |  104 ms |  128 ms |   89 ms
ARGBInterpolate0_Opt (0%)      |  133 ms |  128 ms |  148 ms |  145 ms
ARGBInterpolate64_Opt (25%)    |  211 ms |  181 ms |  244 ms |  222 ms
ARGBInterpolate128_Opt (50%)   |  182 ms |  178 ms |  278 ms |  176 ms
ARGBInterpolate192_Opt (75%)   |  211 ms |  173 ms |  223 ms |  209 ms
ARGBInterpolate255_Opt (99%)   |  211 ms |  183 ms |  315 ms |  221 ms
──────

Function (1280x720 1000x)     | OldNEON | NewNEON | OldSVE2 | NewSVE2
-------------------------------+---------+---------+---------+--------
TestInterpolatePlane (8-bit)   |  164 ms |  124 ms |  119 ms |   50 ms
TestInterpolatePlane_16        |  211 ms |  129 ms |  138 ms |   75 ms
TestARGBInterpolate (50/50)    |  159 ms |  159 ms |  210 ms |  166 ms
ARGBInterpolate0_Opt (0%)      |   92 ms |   92 ms |  148 ms |  138 ms
ARGBInterpolate64_Opt (25%)    |  223 ms |  223 ms |  232 ms |  232 ms
ARGBInterpolate128_Opt (50%)   |  130 ms |  130 ms |  232 ms |  195 ms
ARGBInterpolate192_Opt (75%)   |  223 ms |  223 ms |  232 ms |  232 ms
ARGBInterpolate255_Opt (99%)   |  223 ms |  223 ms |  232 ms |  232 ms

Platform            | NEON   | SVE2   | Result
--------------------+--------+--------+---------------
MediaTek Cortex-C1  | 47 ms  | 34 ms  | SVE2 1.38x win
Qualcomm Oryon v3   | 87 ms  | 73 ms  | SVE2 1.19x win

Testing:
blaze test --config=android_arm64 //third_party/libyuv:libyuv_test --test_filter="*TestInterpolatePlane*"

Bug: None
Change-Id: I503ce5a1269da5e1c5950c6a2c5ce81ddf4aaca5
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8216829
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: George Steed <george.steed@arm.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-08 12:59:08 -07:00
Frank Barchard
7db6591b96 Fix debug build error on row_gcc constants
Bug: 544031197
Change-Id: I4bf113364783622dd5d7318cfbe8ab41e795f47c
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8226309
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-08 12:56:08 -07:00
Frank Barchard
5dc477899b Harden I21xToI420 against oversize heights
I21xToI420 (reached via I210ToI420 / I212ToI420): fix integer overflows
in ScalePlaneVertical_16To8() by switching to HalfRow_16To8.

Add a unit test covering the I21x vertical-scale path. Co-authored-by:
Timothy Nikkel <tnikkel@mozilla.com> Test: libyuv_unittest
--gtest_filter=*.I21xToI420NoHeightOverflow

AMD Zen4
 Was LibYUVConvertTest.I210ToI420_Opt (81 ms)
  30.32% Convert16To8Row_AVX2
  29.81% Convert16To8Row_AVX512BW
  25.72% InterpolateRow_16To8_AVX2

 Now LibYUVConvertTest.I210ToI420_Opt (56 ms)
  41.32% Convert16To8Row_AVX512BW
  40.13% HalfRow_16To8_AVX512BW

Vivo X300 (ARM Lunix C1 Ultra)
 Was LibYUVConvertTest.I210ToI420_Opt (89 ms)
  38.95% InterpolateRow_16To8_NEON
  37.25% Convert16To8Row_NEON

 Now LibYUVConvertTest.I210ToI420_Opt (85 ms)
  47.26% Convert16To8Row_SVE2
  30.39% HalfRow_16To8_SVE2

Bug: chromium:531172025
Change-Id: I23e1215030c40b8577d58617098a8aeec27dd99a
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8221883
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-08-08 12:11:18 -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
Maximilian Hils
240ac24a88 Document why MJPEG databuf size cannot overflow
Change-Id: I584afd17cbb1ecef5d70a9531b7a6cfb2c0441e3
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8075298
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-08-06 12:25:21 -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
b56492e2df [libyuv] Use NV12 and NV21 Matrix wrapper macros in convert_argb_test
Update JNV12ToABGR, JNV21ToABGR, JNV12ToRAW, and JNV21ToRAW test macros
in convert_argb_test.cc to use the public NV12ToABGRMatrix,
NV21ToABGRMatrix, NV12ToRAWMatrix, and NV21ToRAWMatrix wrapper macros.

Test: libyuv_unittest --gtest_filter=*JNV*
libyuv:537503370
Change-Id: I53c2496311cb30f621593f8a9d0011e1106ab501
TAG=agy
CONV=5daf08a8-11bd-4d47-8c71-c5b7a882a788
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8133049
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-07-21 19:42:22 -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
1e06475900 [libyuv] Fix color matrix constants in RAWToI420
RAW format in libyuv is Red-first ([R, G, B] in memory), whereas RGB24
is Blue-first ([B, G, R] in memory).

RGBToYMatrixRow and RGBToUVMatrixRow internally expand 3-byte input
into 4-byte [byte0, byte1, byte2, 255]. For RAW, this buffer becomes
[R, G, B, 255] (matching ABGR byte order). RAWToI420 previously passed
&kArgbI601Constants (which expects [B, G, R, 255]) instead of
&kAbgrI601Constants, causing Red and Blue channels to be swapped.

Pass &kAbgrI601Constants in RAWToI420, fix parameter names in
source/convert.cc, and add a unit test.

Test: libyuv_unittest --gtest_filter=*RAWToI420*
Bug: libyuv:537503370

TAG=agy
CONV=2c54c4b5-f515-421b-80b3-079caa9f948b

Change-Id: Ic72470813eaf15e80046c2c01cf804cb827039ab
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8133048
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-07-21 18:31:48 -07:00