FFmpeg for Windows update to 9.0.2 - #30515
aom v3.15.0
ffmpeg n9.0.2
vpx v1.17.0
openh264 v2.7.0
Closes https://github.com/opencv/opencv/issues/30343
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [ ] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
core: support fp8 depths in countNonZero and hasNonZero - #30463Fixes#30461
### Problem
`countNonZeroTab` (`count_non_zero.simd.hpp`) and `hasNonZeroTab` (`has_non_zero.simd.hpp`) have `0` in the `CV_8F_E4M3FN` and `CV_8F_E4M3FNUZ` slots, so `cv::countNonZero` and `cv::hasNonZero` fail with `func != 0` for fp8 input. `cv::findNonZero` already supports both depths since #30341.
### Fix
- `CV_8F_E4M3FN`: new `countNonZero8f` / `hasNonZero8f` kernels. Same as the 8u kernels, but the sign bit is ignored so `-0.0` (`0x80`) counts as zero: the vector path reuses the `v_add_wrap(x, x)` compare of the 16f kernels, and the scalar tail uses `CHECK_NZ_FP8(x) = ((x) & 0x7f) != 0`.
- `CV_8F_E4M3FNUZ`: the existing 8u kernels. This format has no `-0`; `0x80` is its NaN and counts as non-zero, the same as in `findNonZero`.
### Tests
- `CountNonZero1D` now also runs on both fp8 depths.
- `HasNonZeroNegZeros` now also covers `CV_8F_E4M3FNC1`.
- New `CountNonZeroFP8.sign_bit`, a `TEST_P` over both fp8 depths and n = 1, 100, 1031 (scalar tail, single-vector loop, unrolled loop). It fills a `CV_32F` Mat with random values in ±[0.5, 4), sets every 5th element and the last one to `-0.0`, `NaN` or `+0.0`, converts it to fp8, and checks `countNonZero` / `hasNonZero` against the number of non-zero values set. `-0.0` becomes `0x80` in E4M3FN and must count as zero; `NaN` becomes `0x80` in E4M3FNUZ and must count as non-zero.
These fail on current 5.x (`func != 0`) and pass with this patch. All `*NonZero*` and `*FP8*` tests in `opencv_test_core` pass locally on Apple M1 (190 tests), with OpenCL enabled and with `OPENCV_OPENCL_DEVICE=disabled`.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
core: support 5.x depths in sort and sortIdx - #30506Fixes#30505
### Problem
The kernel tables of `cv::sort` and `cv::sortIdx` (`modules/core/src/matrix_operations.cpp`) only have entries for `CV_8U` to `CV_64F`, so every depth added in 5.x fails with `func != 0`.
### Fix
Both tables now use the existing `sort_<T>` / `sortIdx_<T>` templates for:
- `CV_16F` → `hfloat`, `CV_16BF` → `bfloat`, `CV_8F_E4M3FN` → `fp8_t`, `CV_8F_E4M3FNUZ` → `fp8a_t` (compared through their `float` conversion);
- `CV_Bool` → `uchar`, the same kernel as `CV_8U`;
- `CV_64U` → `uint64_t`, `CV_64S` → `int64_t`, `CV_32U` → `uint32_t`.
### Tests
- `Core/sortIdx.simple` now also runs on `CV_16U`, `CV_16F`, `CV_16BF`, `CV_Bool`, `CV_64U`, `CV_64S`, `CV_32U` and both fp8 depths (`CV_16U` was already supported but not tested), and also checks `cv::sort` against sorting a `CV_64F` copy of the same data; there was no `cv::sort` test before.
- New `Core_sort.large_integers` checks exact `sort` / `sortIdx` results for `CV_32S`, `CV_32U`, `CV_64S` and `CV_64U` with values that need the full type: `INT_MIN` / `INT_MAX`, the unsigned high bit (`0x80000000`, `UINT_MAX`, `2^63`, `UINT64_MAX`) and `2^53` vs `2^53 + 1`. With signed kernels for `CV_32U` / `CV_64U` it fails, while the random `sortIdx` test still passes.
The new cases fail on current 5.x and pass with this patch. All `sortIdx` / `sort` tests in `opencv_test_core` pass locally on Apple M1 Pro (242 tests), with OpenCL enabled and with `OPENCV_OPENCL_DEVICE=disabled`. The full `opencv_test_core` passes, except 7 tests that need `opencv_extra` test data, which I didn't have locally (FileStorage base64 and globbing).
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
imgcodecs(avif): add support for alpha channel quality control #30499
This pull request adds support for independent alpha channel quality control when encoding AVIF images, resolving #30451.
### What was happening
OpenCV previously only controlled color channel compression via `IMWRITE_AVIF_QUALITY`. Alpha channels remained unhandled or were tied to color quality, making it impossible to adjust color and alpha compression independently (for example, keeping crisp lossless alpha edges while compressing background RGB content lossily to save file size).
### What changed
1. In `modules/imgcodecs/include/opencv2/imgcodecs.hpp`, added `IMWRITE_AVIF_ALPHA_QUALITY = 515` (range 0 to 100, default 95), and updated documentation for `IMWRITE_AVIF_QUALITY` to clarify that it controls color planes.
2. In `modules/imgcodecs/src/grfmt_avif.cpp`:
- Registered `IMWRITE_AVIF_ALPHA_QUALITY` in `m_supported_encode_key`.
- Handled `IMWRITE_AVIF_ALPHA_QUALITY` to set `encoder_->qualityAlpha` (and quantizers for fallback paths).
- Removed the automatic fallback that synced alpha quality to color quality, keeping the two parameters decoupled and order-independent.
3. Added dedicated unit test `Imgcodecs_Avif.alpha_quality_control` in `modules/imgcodecs/test/test_avif.cpp` verifying independent lossy/lossless combinations, order independence, and bounds clamping.
### Testing
- Verified with standalone reproducer (`reproduce_opencv_30451.cpp`):
- Quality=100, AlphaQuality=10: 0 color difference (lossless color) with lossy alpha.
- Quality=10, AlphaQuality=100: 0 alpha difference (lossless alpha) with lossy color.
- Parameter order independence confirmed.
- Native test suite: All 413 AVIF tests passed in `opencv_test_imgcodecs`.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
The eight test_qlinearmatmul_{2D,3D}_{int8,uint8}_{float16,float32} cases
and test_quantizelinear_blocked_asymmetric were on the parser denylist
without test data; opencv_extra#1436 (paired with #30289) added the models
and with them all nine pass on current 5.x. The old denylist comment calls
the QLinearMatMul entries float-output variants, but the suffix is the
scale dtype and the outputs are int8/uint8, which the importer and kernels
already handle.
Remove the nine entries from the denylist and add them to the OpenVINO
filter as SKIP, like the other QLinearMatMul/QuantizeLinear cases there.
Verified on macOS arm64 against current opencv_extra: all 18
parameterizations (OCV/CPU, OCV/CPU_FP16) pass and the whole
Test_ONNX_conformance suite stays green.
Check the [1, 1, N, 7] boxes layout in getMemoryShapes so the output size and the box loop agree on every backend. Emit the extrapolation value for samples outside [0, H - 1] x [0, W - 1] and sample the box center for 1-pixel crops, on both the CPU and CUDA paths.
According to the ONNX protobuf specification, boolean tensors may be stored either in raw_data or packed into repeated int32 int32_data as individual 32-bit integers (not a bitmask). Previously, getMatFromTensor only read raw_data, causing assertion failures when parsing ONNX models that serialize boolean initializers into int32_data.
This patch adds int32_data extraction with conversion to CV_Bool, adds specification documentation, removes unreachable duplicate branches for UINT16/UINT32/UINT64, and adds tests in test_onnx_importer using models from opencv_extra.
Test data in opencv_extra under the same branch name as this patch: https://github.com/opencv/opencv_extra/pull/TBD
Addresses #19366.
dnn: fix GatherND division by zero on empty indices - #30503
GatherND divided by zero in `forward_impl` when the indices tensor is empty, which kills the process with SIGFPE on x86-64 (seen with `LightGlueMatcher` when nothing matches). The layer now returns early when the output is empty.
Fixes#30501
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
dnn : int8 optimisation - #30289
### Correctness
- **AVX-VNNI 1x1 conv, leftover pixels:** the last `H*W % 8` output pixels read the VNNI-repacked
weights in the wrong order. Fixes the wrong top-1 of MobileNetV2 and DenseNet121 int8 with VNNI.
- **Padded taps in scalar paths:** the depthwise (AVX2) tail and the NEON kxk scalar path skipped
out-of-image taps instead of using the input zero point. The VNNI kxk kernel now never leaves a
tile under 8 pixels.
### Speed
- **First conv:** quantizing the float image is now parallel and vectorized. A float-input conv
with up to 4 channels runs as a 1x1 conv over each pixel's window. First conv 5-6x faster
(ResNet50: 0.88 -> 0.16 ms). `OPENCV_DNN_INT8_CONV_WINDOW_PACKING=0` disables the window packing.
- **AVX-VNNI depthwise conv:** a new kernel transposes input rows into one row per channel and
adds 4 taps for 8 pixels with one `pshufb` + `vpdpbusd`. Depthwise about 2x faster, output
bit-identical.
- **int8 MatMul at batch 1:** uses all threads instead of one. AlexNet int8: 2.75 -> 1.52 ms.
- **Asymmetric padding:** convs with TF "SAME" padding at stride 2 are now fused to int8 instead of
running in float between Dequantize and Quantize. Float convs in EfficientNet-Lite4 and MP hand
pose: 5 -> 0-1.
- **Broadcast int8 Add/Mul:** copies whole contiguous runs in parallel instead of computing an
index per element.
- **int8 Quantize/Dequantize:** AVX2 fast path for signed int8; per-tensor Q/DQ keep the block
layout.
### Tests
- Companion PR : opencv/opencv_extra#1436 (test data).
### Results (ms, i9-14900KS , default threads)
| Model | 5.x before (ms) | this PR (ms) | ONNX Runtime 1.30 (ms) | Speedup vs 5.x | ORT / this PR |
|---|---|---|---|---|---|
| DenseNet121 int8 | 109.4 | 14.7 | 16.1 | 7.43x | 1.09x |
| PP-OCRv3 det int8 | 65.7 | 12.7 | 33.1 | 5.15x | 2.60x |
| SFace int8 | 8.1 | 3.0 | 19.0 | 2.75x | 6.43x |
| EfficientNet-Lite4 int8 | 4.1 | 2.9 | 1.9 | 1.40x | 0.67x |
| EfficientNet-Lite4 qdq | 4.6 | 3.1 | 2.0 | 1.49x | 0.65x |
| MP hand pose int8 | 2.5 | 0.8 | 2.2 | 3.06x | 2.69x |
| PPHumanSeg int8 | 2.6 | 1.9 | 5.6 | 1.41x | 3.02x |
Co-authored with @Prasadayus
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
imgcodecs(avif): fix norm calculation and extend 16-bit tests - #30431
- Correct lossy test normalization from dividing by total samples (N) to root-mean-square (RMS) error divided by sqrt(N), and recalibrate thresholds with margin for 8/10/12/16-bit tests.
- Extend 16-bit AVIF tests to cover all supported channel counts (1, 3, and 4 channels) using testing::Combine.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
dnn: skip MatMul's zero-fill when there is no bias - #30297
Without a bias, MatMul pre-zeroed the whole output with a single-threaded memset and then still passed beta = 1 into the gemm, forcing every kernel to read and multiply-add against that zeroed buffer. Passing beta = 0 instead removes the memset and lets MLAS/fastGemmThin write the product directly. Measured 31-50% faster on a small, write-heavy, no-bias shape (512x32x512, 8 threads); `MatMul.matmul/41` and the new `MatMul.matmul_dynamicB/41` cover the constant-B and dynamic-B paths.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
imgproc: accept CV_Bool input in morphological operations - #29799
### Pull Request Readiness Checklist
Fixes#29798
In 5.0 `cv::Mat_<bool>::depth()` returns `CV_Bool` instead of `CV_8U`, so the morphology filter factories in `morph.simd.hpp` no longer matched any branch and threw `Unsupported data type`. This worked in 4.x.
`CV_Bool` is a 1-byte 0/1 type, so it is dispatched through the same `uchar` min/max filters as `CV_8U`, and the default border value follows the `CV_8U` case (1 for erode, 0 for dilate). The OpenCL path bails out for `CV_Bool` and falls back to the CPU implementation, since `ocl::typeToStr` has no mapping for it.
Accepting `CV_Bool` also exposed a latent bug in `FilterEngine::init`: `borderElemSize` was computed from `CV_MAT_DEPTH(srcType) >= CV_32S`, which assumes the depth enum is ordered by element size. `CV_Bool` is 9, so a 1-byte type took the `sizeof(int)` branch and `borderElemSize` became 0, leaving `borderTab` empty and making every non-`BORDER_CONSTANT` erode/dilate read through a null pointer. It now keys off `CV_ELEM_SIZE1` instead. `CV_16F`/`CV_16BF` had the same latent miscomputation.
Added a test comparing `Mat_<bool>` against the equivalent `CV_8UC1` mask for erode, dilate, open and close over the three structuring element shapes and four border types, plus in-place and multi-iteration calls.
`MORPH_GRADIENT`/`TOPHAT`/`BLACKHAT` remain unsupported for `CV_Bool`: they subtract two masks, which has no meaning for a boolean type, and they throw rather than returning a wrong result.
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
Do not call Lapack for small operations. - #29909
This reduces the cache for GEMM in calibration: the transposed Jacobian is 6 x 2Number points while the result is 6 x 1.
The previous code was only looking at the input number of rows.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [ ] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
dnn: avoid unused quadratic workspace for MLAS attention - #30405
`AttentionLayerImpl` allocates a dense `[batch * heads, sequence, sequence]` probability buffer before calling MLAS FlashAttention, even though that path never uses it. With 12 heads and 8,192 tokens, this is an unused 3 GiB allocation that can make inference fail before the tiled kernel runs.
This patch shares the existing fast-path eligibility check between memory planning and execution. It keeps one-element placeholders for the unused probability and output workspaces, preserving the internal buffer indices used by RoPE. If MLAS declines the call, the generic path allocates the dense buffers it needs. Masked attention and builds without MLAS keep their existing workspace plans. The numerical kernels are unchanged.
I reproduced the allocation with a generated FP32 ONNX Attention model loaded through `readNetFromONNX`, using the 5.x graph engine. For batch 1, 12 heads, head width 16 and 8,192 tokens:
| Measurement | Before | After |
| --- | ---: | ---: |
| Largest `cv::Mat` allocation | 3 GiB | 18 MiB |
| Peak live `cv::Mat` storage | 3,279,180,288 bytes | 51,663,368 bytes |
| Forward with a 512 MiB address-space limit | Allocation failure | Completes |
| Peak RSS without the limit | 65,664 KiB | 65,616 KiB |
The allocation trace goes through `allocateLayerOutputs` and `Mat::fit` before the layer's `forward`. The same failure is resolved at 4,096 and 16,384 tokens; at 16,384 tokens, the largest allocation drops from 12 GiB to 36 MiB. Outputs from the constrained runs match the unrestricted runs byte for byte.
The limit above is Linux `RLIMIT_AS`, which limits virtual address space. RSS barely changes because the unused buffer is not touched. The allocation measurements cover `cv::Mat` storage only.
Validation on Linux x86-64:
- 40 targeted tests pass with MLAS in Release, and the same 40 pass under ASan/UBSan with MLAS and SIMD disabled. The workspace regression test fails against the baseline library.
- 56 ONNX baseline/patch comparisons are byte-identical, covering sequence lengths, 1/6 threads, static and dynamic weights, masks, and RoPE. Four of these force `mlasFlashAttention` to return false after dispatch to exercise fallback from a compact workspace plan.
- Reusing a graph across changing sequence lengths passes 40 comparisons against fresh graphs on each version. A separate layer-level matrix adds 144 byte-identical comparisons.
- The existing Attention perf fixture passes all five cases at 1 and 6 threads with `--perf_verify_sanity=true` and no regression data files. This includes new constant-weight cases at 257, 1,024, and 4,096 tokens. Separate longer pinned timing runs measured approximately +0.5% at 257 tokens and -1.1% at 1,024 tokens; timings vary on this shared host, so this PR makes no speedup claim.
The half-input audit passed six configurations that the graph promotes to FP32. Static, unmasked FP16 constants exposed a separate existing weight-packing issue: the baseline already produces invalid outputs, and ASan reports an out-of-bounds read in unchanged packing code. Those cases are excluded from passing validation. ARM and other platforms still need CI.
This follows the MLAS integration in #29126. #30126 addresses a different source of memory use (weight ownership), but touches the same class. `AttentionOnnxAiLayerImpl` is outside this change.
### Pull Request Readiness Checklist
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on code under GPL or another license incompatible with OpenCV.
- [x] The PR targets the proper branch (`5.x`).
- [x] Related work is referenced above; the reproducer and measurements describe the bug.
- [x] Accuracy and performance tests are included. They generate their inputs and require no new `opencv_extra` data.
- [x] No public API changes or new samples requiring documentation.
core/dnn: resolve GCC 16 -Wmaybe-uninitialized and -Warray-bounds warnings - #30308
- core(nd_copy): ensure copyBatch only executes runPlans when np > 0.
- dnn(test): add reserve(3) to input vector to quiet compiler bounds checks.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
When compiling with GCC 16.2.0, I encountered the following error:
modules/core/include/opencv2/core/hal/intrin_forward.hpp:204:49: error: 'INT_MAX' was not declared in this scope
204 | SV32 sat = v_xor(v_shr<31>(hi), SETALL_S32(INT_MAX)); \
core: accept both float->int saturation results in OCL ConvertToSaturate test - #30448
Fixes the `macOS-x64 / BuildAndTest` failure from #30386, which makes 5.x macOS-x64 CI red for every PR (e.g. #30302):
```
[ RUN ] OCL_MatrixOperation/ConvertToSaturate.Accuracy/16, where GetParam() = (CV_32F, CV_32S)
test_matrix_operation.cpp:247: Failure
cv::countNonZero(diff)
Which is: 2
```
INT_MAX isn't representable in float, so a saturated `CV_32F -> CV_32S` result can legitimately be either value:
- x86 CPU (`v_round` / `cvRound`) clamps to `CV__FLT2INT_MAX_F` = 2147483520 before converting (since #30007).
- OpenCL `convert_int_sat_rte` and NEON `vcvtnq_s32_f32` give INT_MAX = 2147483647.
So on an x86 host the out-of-range inputs `3e9` and `1e20` differ by 127 between `Mat` and `UMat`. On Apple M1 both sides give INT_MAX, which is why it only shows up on macOS-x64.
For this pair the test now clamps both results to 2147483520 before the exact comparison, i.e. it accepts any value in [2147483520, INT_MAX] as saturated. In-range values and all other depth pairs are still compared exactly.
**Testing** (Apple M1 Pro, OpenCL on; native arm64 build and an x86_64 build run under Rosetta 2)
`Mat::convertTo` vs `UMat::convertTo` for `CV_32F -> CV_32S`:
| input | arm64 CPU | x86_64 CPU | OpenCL |
|---|---|---|---|
| 3e9 | 2147483647 | 2147483520 | 2147483647 |
| 1e20 | 2147483647 | 2147483520 | 2147483647 |
The x86_64 build reproduces the CI mismatch. With this change, on both builds:
- `opencv_test_core --gtest_filter=*ConvertToSaturate*`: 135 passed.
- `opencv_test_core --gtest_filter=OCL_*:*ConvertTo*:*convertTo*:*Core_ConvertScale*`: 7549 passed.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
dnn: enable vendored MLAS on Windows ARM64 with MSVC - #30332
Close https://github.com/opencv/opencv/issues/30330
After https://github.com/opencv/opencv/pull/30331
### Summary
Enable OpenCV DNN’s vendored MLAS implementation on Windows ARM64 using Microsoft’s C++ compiler (`cl.exe`).
This change builds on the separate MLAS target architecture detection fix.
MLAS is currently disabled on all Windows targets. Enabling ARM64 requires more than removing that restriction: the GNU-style `.S` sources cannot be used by the MSVC toolchain, and the vendored Windows sources lack the SGEMV kernel used by the single-row fast path.
This change:
- Adds the Windows ARM64 SGEMV kernel from the same ONNX Runtime revision as the existing vendored sources.
- Preprocesses the native SGEMM and SGEMV `.asm` files with `cl.exe`, then assembles them with `armasm64`.
- Includes the generated assembly objects in `opencv_dnn`, with configuration-specific output paths.
- Enables MLAS only for Microsoft `cl.exe` targeting ARM64. Other Windows toolchains and targets remain disabled.
- Adds GEMM and SDPA accuracy coverage and documents the Windows build requirements.
The implementation uses the existing upstream `MlasHGemmSupported` probe. No additional HGEMM or FP16 workaround is introduced.
### Validation
On Windows ARM64, based on upstream commit `3074f64`:
- Release and Debug DNN builds linked successfully.
- MLAS and both NEON assembly kernels were enabled.
- All **116 selected tests passed in each configuration**, covering GEMM, single-row GEMV through FlashAttention, transposition, odd-sized tails, and accumulation across FlashAttention blocks.
- CMake guard checks confirmed unsupported Windows compiler/target combinations remain disabled.
A complete Python wheel has not been rebuilt, and performance benchmarks have not been run.
### Related work
- [[opencv/opencv#29343](https://github.com/opencv/opencv/pull/29343)](https://github.com/opencv/opencv/pull/29343): temporary blanket Windows disable; this PR enables only the supported MSVC ARM64 configuration.
- [[opencv/opencv#29885](https://github.com/opencv/opencv/issues/29885)](https://github.com/opencv/opencv/issues/29885): related Windows x86/x64 and clang-cl problems, outside this PR’s scope.
- [[opencv/opencv#29362](https://github.com/opencv/opencv/pull/29362)](https://github.com/opencv/opencv/pull/29362): existing HGEMM capability-probe fix, retained unchanged.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [ ] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake