convert/intel/convert_planar_avx2.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Avisynth v2.5. Copyright 2002 Ben Rudiak-Gould et al. | ||
| 2 | // http://avisynth.nl | ||
| 3 | |||
| 4 | // This program is free software; you can redistribute it and/or modify | ||
| 5 | // it under the terms of the GNU General Public License as published by | ||
| 6 | // the Free Software Foundation; either version 2 of the License, or | ||
| 7 | // (at your option) any later version. | ||
| 8 | // | ||
| 9 | // This program is distributed in the hope that it will be useful, | ||
| 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | // GNU General Public License for more details. | ||
| 13 | // | ||
| 14 | // You should have received a copy of the GNU General Public License | ||
| 15 | // along with this program; if not, write to the Free Software | ||
| 16 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit | ||
| 17 | // http://www.gnu.org/copyleft/gpl.html . | ||
| 18 | // | ||
| 19 | // Linking Avisynth statically or dynamically with other modules is making a | ||
| 20 | // combined work based on Avisynth. Thus, the terms and conditions of the GNU | ||
| 21 | // General Public License cover the whole combination. | ||
| 22 | // | ||
| 23 | // As a special exception, the copyright holders of Avisynth give you | ||
| 24 | // permission to link Avisynth with independent modules that communicate with | ||
| 25 | // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license | ||
| 26 | // terms of these independent modules, and to copy and distribute the | ||
| 27 | // resulting combined work under terms of your choice, provided that | ||
| 28 | // every copy of the combined work is accompanied by a complete copy of | ||
| 29 | // the source code of Avisynth (the version of Avisynth used to produce the | ||
| 30 | // combined work), being distributed under the terms of the GNU General | ||
| 31 | // Public License plus this exception. An independent module is a module | ||
| 32 | // which is not derived from or based on Avisynth, such as 3rd-party filters, | ||
| 33 | // import and export plugins, or graphical user interfaces. | ||
| 34 | |||
| 35 | |||
| 36 | #include <avs/alignment.h> | ||
| 37 | #ifdef _MSC_VER | ||
| 38 | #include <intrin.h> | ||
| 39 | #else | ||
| 40 | #include <x86intrin.h> | ||
| 41 | #endif | ||
| 42 | #include <immintrin.h> | ||
| 43 | |||
| 44 | #include "convert_planar_avx2.h" | ||
| 45 | #include "../convert_planar.h" | ||
| 46 | #include "../convert_helper.h" | ||
| 47 | |||
| 48 | #ifndef _mm256_set_m128i | ||
| 49 | #define _mm256_set_m128i(v0, v1) _mm256_insertf128_si256(_mm256_castsi128_si256(v1), (v0), 1) | ||
| 50 | #endif | ||
| 51 | |||
| 52 | DISABLE_WARNING_PUSH | ||
| 53 | DISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE | ||
| 54 | |||
| 55 | // no srai64 in AVX2, only in AVX512 + VL | ||
| 56 | // AVX2 logical shift (_mm256_srl_epi64) plus sign fill | ||
| 57 | static AVS_FORCEINLINE __m256i mm256_srai_epi64_simul(__m256i x, int count) { | ||
| 58 | // logical right shift on 64bit lanes | ||
| 59 | const __m128i cnt = _mm_cvtsi32_si128(count); | ||
| 60 | const __m256i logical = _mm256_srl_epi64(x, cnt); | ||
| 61 | |||
| 62 | // have the sign bit present in both 32 bit halves of each 64bit lane before we do a 32bit arithmetic shift. | ||
| 63 | const __m256i hi_dup = _mm256_shuffle_epi32(x, _MM_SHUFFLE(3, 3, 1, 1)); | ||
| 64 | const __m256i sign_shifted = _mm256_sra_epi32(hi_dup, cnt); | ||
| 65 | |||
| 66 | // mask back sign extension | ||
| 67 | const __m256i upper_mask = _mm256_set1_epi64x(0xFFFFFFFF00000000ULL); | ||
| 68 | const __m256i sign_ext = _mm256_and_si256(sign_shifted, upper_mask); | ||
| 69 | |||
| 70 | return _mm256_or_si256(logical, sign_ext); | ||
| 71 | } | ||
| 72 | |||
| 73 | // packed rgb helper | ||
| 74 | static AVS_FORCEINLINE __m256i convert_yuv_to_rgb_avx2_core(const __m256i& px0189, const __m256i& px23AB, const __m256i& px45CD, const __m256i& px67EF, const __m256i& zero, const __m256i& matrix, const __m256i& round_mask_plus_rgb_offset) { | ||
| 75 | //int b = (((int)m[0] * Y + (int)m[1] * U + (int)m[ 2] * V + 4096 + rgb_offset)>>13); | ||
| 76 | |||
| 77 | //px01 - xx xx 00 V1 00 U1 00 Y1 xx xx 00 V0 00 U0 00 Y0 | ||
| 78 | |||
| 79 | 288 | auto low_lo = _mm256_madd_epi16(px0189, matrix); //xx*0 + v1*m2 | u1*m1 + y1*m0 | xx*0 + v0*m2 | u0*m1 + y0*m0 | |
| 80 | 144 | auto low_hi = _mm256_madd_epi16(px23AB, matrix); //xx*0 + v3*m2 | u3*m1 + y3*m0 | xx*0 + v2*m2 | u2*m1 + y2*m0 | |
| 81 | 144 | auto high_lo = _mm256_madd_epi16(px45CD, matrix); | |
| 82 | 288 | auto high_hi = _mm256_madd_epi16(px67EF, matrix); | |
| 83 | |||
| 84 | 432 | auto low_v = _mm256_castps_si256(_mm256_shuffle_ps(_mm256_castsi256_ps(low_lo), _mm256_castsi256_ps(low_hi), _MM_SHUFFLE(3, 1, 3, 1))); // v3*m2 | v2*m2 | v1*m2 | v0*m2 | |
| 85 | 432 | auto high_v = _mm256_castps_si256(_mm256_shuffle_ps(_mm256_castsi256_ps(high_lo), _mm256_castsi256_ps(high_hi), _MM_SHUFFLE(3, 1, 3, 1))); | |
| 86 | |||
| 87 | 432 | auto low_yu = _mm256_castps_si256(_mm256_shuffle_ps(_mm256_castsi256_ps(low_lo), _mm256_castsi256_ps(low_hi), _MM_SHUFFLE(2, 0, 2, 0))); // u3*m1 + y3*m0 | u2*m1 + y2*m0 | u1*m1 + y1*m0 | u0*m1 + y0*m0 | |
| 88 | 432 | auto high_yu = _mm256_castps_si256(_mm256_shuffle_ps(_mm256_castsi256_ps(high_lo), _mm256_castsi256_ps(high_hi), _MM_SHUFFLE(2, 0, 2, 0))); | |
| 89 | |||
| 90 | 144 | auto t_lo = _mm256_add_epi32(low_v, low_yu); // v3*m2 + u3*m1 + y3*m0... | |
| 91 | 144 | auto t_hi = _mm256_add_epi32(high_v, high_yu); | |
| 92 | |||
| 93 | // v3*m2 + u3*m1 + y3*m0 + 4096 + rgb_offset | ||
| 94 | 144 | t_lo = _mm256_add_epi32(t_lo, round_mask_plus_rgb_offset); | |
| 95 | 288 | t_hi = _mm256_add_epi32(t_hi, round_mask_plus_rgb_offset); | |
| 96 | |||
| 97 | 144 | t_lo = _mm256_srai_epi32(t_lo, 13); // (v3*m2 + u3*m1 + y3*m0 + 4096) >> 13... | |
| 98 | 144 | t_hi = _mm256_srai_epi32(t_hi, 13); | |
| 99 | |||
| 100 | 144 | auto result = _mm256_packs_epi32(t_lo, t_hi); | |
| 101 | 144 | result = _mm256_packus_epi16(result, zero); //00 00 00 00 00 00 00 00 b15 b14 b14 b12 b11 b10 b9 b8 00 00 00 00 00 00 00 00 b7 b6 b5 b4 b3 b2 b1 b0 | |
| 102 | 144 | return result; | |
| 103 | } | ||
| 104 | |||
| 105 | template<int rgb_pixel_step, bool hasAlpha> | ||
| 106 | 8 | void convert_yv24_to_rgb_avx2(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE* srcV, const BYTE* srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix& matrix) | |
| 107 | { | ||
| 108 | 8 | dstp += dst_pitch * (height - 1); // We start at last line | |
| 109 | |||
| 110 | 8 | size_t mod16_width = rgb_pixel_step == 3 ? width / 16 * 16 : width; | |
| 111 | // for rgb32 target we can process pixels beyond width, but we have 64bit alignment at target 16 pixels to 16*4=64 rgb pixels | ||
| 112 | // if alignment would only be 32 bytes, we'd do the last cycle to process only 8 source pixels | ||
| 113 | |||
| 114 | 8 | auto matrix_b = _mm256_set_epi16(0, matrix.v_b, matrix.u_b, matrix.y_b, 0, matrix.v_b, matrix.u_b, matrix.y_b, 0, matrix.v_b, matrix.u_b, matrix.y_b, 0, matrix.v_b, matrix.u_b, matrix.y_b); | |
| 115 | 8 | auto matrix_g = _mm256_set_epi16(0, matrix.v_g, matrix.u_g, matrix.y_g, 0, matrix.v_g, matrix.u_g, matrix.y_g, 0, matrix.v_g, matrix.u_g, matrix.y_g, 0, matrix.v_g, matrix.u_g, matrix.y_g); | |
| 116 | 16 | auto matrix_r = _mm256_set_epi16(0, matrix.v_r, matrix.u_r, matrix.y_r, 0, matrix.v_r, matrix.u_r, matrix.y_r, 0, matrix.v_r, matrix.u_r, matrix.y_r, 0, matrix.v_r, matrix.u_r, matrix.y_r); | |
| 117 | |||
| 118 | 8 | auto zero128 = _mm_setzero_si128(); | |
| 119 | 8 | auto zero = _mm256_setzero_si256(); | |
| 120 | |||
| 121 | // .13 bit frac integer arithmetic | ||
| 122 | 8 | int round_mask_plus_rgb_offset_i = (1 << 12) + (matrix.offset_rgb << 13); | |
| 123 | 8 | auto round_mask_plus_rgb_offset = _mm256_set1_epi32(round_mask_plus_rgb_offset_i); | |
| 124 | 8 | auto offset = _mm256_set_epi16(0, -128, -128, matrix.offset_y, 0, -128, -128, matrix.offset_y, 0, -128, -128, matrix.offset_y, 0, -128, -128, matrix.offset_y); | |
| 125 | |||
| 126 | // 16 YUV(A) pixels --> 4x16 RGB quads = 64 bytes. Avisynth's alignment is 64 fortunately. | ||
| 127 | |||
| 128 |
6/8void convert_yv24_to_rgb_avx2<3, false>(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, ConversionMatrix const&):
✓ Branch 251 → 17 taken 9 times.
✓ Branch 251 → 252 taken 3 times.
void convert_yv24_to_rgb_avx2<3, true>(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, ConversionMatrix const&):
✗ Branch 257 → 17 not taken.
✗ Branch 257 → 258 not taken.
void convert_yv24_to_rgb_avx2<4, false>(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, ConversionMatrix const&):
✓ Branch 221 → 17 taken 6 times.
✓ Branch 221 → 222 taken 2 times.
void convert_yv24_to_rgb_avx2<4, true>(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, ConversionMatrix const&):
✓ Branch 227 → 17 taken 9 times.
✓ Branch 227 → 228 taken 3 times.
|
32 | for (size_t y = 0; y < height; ++y) { |
| 129 |
6/8void convert_yv24_to_rgb_avx2<3, false>(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, ConversionMatrix const&):
✓ Branch 243 → 18 taken 18 times.
✓ Branch 243 → 244 taken 9 times.
void convert_yv24_to_rgb_avx2<3, true>(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, ConversionMatrix const&):
✗ Branch 249 → 18 not taken.
✗ Branch 249 → 250 not taken.
void convert_yv24_to_rgb_avx2<4, false>(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, ConversionMatrix const&):
✓ Branch 219 → 18 taken 12 times.
✓ Branch 219 → 220 taken 6 times.
void convert_yv24_to_rgb_avx2<4, true>(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, ConversionMatrix const&):
✓ Branch 225 → 18 taken 18 times.
✓ Branch 225 → 226 taken 9 times.
|
72 | for (size_t x = 0; x < mod16_width; x += 16) { |
| 130 | 48 | __m128i src_y = _mm_load_si128(reinterpret_cast<const __m128i*>(srcY + x)); //Y15 .. Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 | |
| 131 | 48 | __m128i src_u = _mm_load_si128(reinterpret_cast<const __m128i*>(srcU + x)); //U15 .. U7 U6 U5 U4 U3 U2 U1 U0 | |
| 132 | 78 | __m128i src_v = _mm_load_si128(reinterpret_cast<const __m128i*>(srcV + x)); //V15 .. V7 V6 V5 V4 V3 V2 V1 V0 | |
| 133 | [[maybe_unused]] __m128i src_a; | ||
| 134 | if constexpr(hasAlpha) | ||
| 135 | 36 | src_a = _mm_load_si128(reinterpret_cast<const __m128i*>(srcA + x)); //A15 .. A7 A6 A5 A4 A3 A2 A1 A0 | |
| 136 | |||
| 137 | 48 | __m128i t1_lo = _mm_unpacklo_epi8(src_y, src_u); //U7 Y7 U6 Y6 U5 Y5 U4 Y4 U3 Y3 U2 Y2 U1 Y1 U0 Y0 | |
| 138 | 48 | __m128i t1_hi = _mm_unpackhi_epi8(src_y, src_u); //U15 Y15 U14 Y14 U13 Y13 U12 Y12 U11 Y11 U10 Y10 U9 Y9 U8 Y8 | |
| 139 | 48 | __m128i t2_lo = _mm_unpacklo_epi8(src_v, zero128); //00 V7 00 V6 00 V5 00 V4 00 V3 00 V2 00 V1 00 V0 | |
| 140 | 48 | __m128i t2_hi = _mm_unpackhi_epi8(src_v, zero128); //00 V15 00 V14 00 V13 00 V12 00 V11 00 V10 00 V9 00 V8 | |
| 141 | |||
| 142 | 48 | __m256i t1 = _mm256_set_m128i(t1_hi, t1_lo); | |
| 143 | 48 | __m256i t2 = _mm256_set_m128i(t2_hi, t2_lo); | |
| 144 | 48 | t1 = _mm256_permute4x64_epi64(t1, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6)); | |
| 145 | 48 | t2 = _mm256_permute4x64_epi64(t2, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6)); | |
| 146 | |||
| 147 | 48 | __m256i low = _mm256_unpacklo_epi16(t1, t2); //xx V11 U11 Y11 xx V10 U10 Y10 xx V9 U9 Y9 xx V8 U8 Y8 xx V3 U3 Y3 xx V2 U2 Y2 xx V1 U1 Y1 xx V0 U0 Y0 | |
| 148 | 48 | __m256i high = _mm256_unpackhi_epi16(t1, t2); //xx V15 U15 Y15 xx V14 U14 Y14 xx V13 U13 Y13 xx V12 U12 Y12 xx V7 U7 Y7 xx V6 U6 Y6 xx V5 U5 Y5 xx V4 U4 Y4 | |
| 149 | |||
| 150 | 48 | __m256i px0189 = _mm256_unpacklo_epi8(low, zero); //xx xx 00 V1 00 U1 00 Y1 xx xx 00 V0 00 U0 00 Y0 | |
| 151 | 48 | __m256i px23AB = _mm256_unpackhi_epi8(low, zero); //xx xx 00 V3 00 U3 00 Y3 xx xx 00 V2 00 U2 00 Y2 | |
| 152 | 48 | __m256i px45CD = _mm256_unpacklo_epi8(high, zero); //xx xx 00 V5 00 U5 00 Y5 xx xx 00 V4 00 U4 00 Y4 | |
| 153 | 48 | __m256i px67EF = _mm256_unpackhi_epi8(high, zero); //xx xx 00 V7 00 U7 00 Y7 xx xx 00 V6 00 U6 00 Y6 | |
| 154 | |||
| 155 | 48 | px0189 = _mm256_add_epi16(px0189, offset); | |
| 156 | 48 | px23AB = _mm256_add_epi16(px23AB, offset); | |
| 157 | 48 | px45CD = _mm256_add_epi16(px45CD, offset); | |
| 158 | 96 | px67EF = _mm256_add_epi16(px67EF, offset); | |
| 159 | |||
| 160 | 48 | __m256i result_b = convert_yuv_to_rgb_avx2_core(px0189, px23AB, px45CD, px67EF, zero, matrix_b, round_mask_plus_rgb_offset); // b15..0 | |
| 161 | 48 | __m256i result_g = convert_yuv_to_rgb_avx2_core(px0189, px23AB, px45CD, px67EF, zero, matrix_g, round_mask_plus_rgb_offset); // g15..0 | |
| 162 | 48 | __m256i result_r = convert_yuv_to_rgb_avx2_core(px0189, px23AB, px45CD, px67EF, zero, matrix_r, round_mask_plus_rgb_offset); // r15..0 | |
| 163 | |||
| 164 | 48 | __m256i result_bg = _mm256_unpacklo_epi8(result_b, result_g); //g15 b15 g14 b14 g13 b13 g12 b12 g11 b11 g10 b10 g9 b9 g8 b8 | g7 b7 g6 b6 g5 b5 g4 b4 g3 b3 g2 b2 g1 b1 g0 b0 | |
| 165 | __m256i alpha; | ||
| 166 | if constexpr(hasAlpha) { | ||
| 167 | 18 | __m128i a_lo = _mm_unpacklo_epi8(src_a, zero128); //00 A7 00 A6 00 A5 00 A4 00 A3 00 A2 00 A1 00 A0 | |
| 168 | 18 | __m128i a_hi = _mm_unpackhi_epi8(src_a, zero128); //00 A15 00 A14 00 A13 00 A12 00 A11 00 A10 00 A9 00 A8 | |
| 169 | 18 | alpha = _mm256_set_m128i(a_hi, a_lo); // a15 .. a0 at low of each m128i part | |
| 170 | 18 | alpha = _mm256_permute4x64_epi64(alpha, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6)); | |
| 171 | } | ||
| 172 | else | ||
| 173 | 30 | alpha = _mm256_cmpeq_epi32(result_r, result_r); // FF FF FF FF ... default alpha transparent | |
| 174 | |||
| 175 | 48 | __m256i result_ra = _mm256_unpacklo_epi8(result_r, alpha); //a7 r7 a6 r6 a5 r5 a4 r4 a3 r3 a2 r2 a1 r1 a0 r0 | |
| 176 | |||
| 177 | 48 | __m256i result_lo = _mm256_unpacklo_epi16(result_bg, result_ra); // a11 r11 g11 b11 | a10 r10 g10 b10 | a9 r9 g9 b9 | a8 r8 g8 b8 | a3 r3 g3 b3 | a2 r2 g2 b2 | a1 r1 g1 b1 | a0 r0 g0 b0 | |
| 178 | 48 | __m256i result_hi = _mm256_unpackhi_epi16(result_bg, result_ra); | |
| 179 | // note: actual pixel indexes are different from the numbers in comments, they are kept to be follow more easily | ||
| 180 | // Initial _mm256_permute4x64_epi64 ensures that the order here is properly argb7..argb0 and argb15..argb8 | ||
| 181 | |||
| 182 | if constexpr (rgb_pixel_step == 4) { | ||
| 183 | //rgb32 | ||
| 184 | 30 | _mm256_store_si256(reinterpret_cast<__m256i*>(dstp + x * 4), result_lo); | |
| 185 | 30 | _mm256_store_si256(reinterpret_cast<__m256i*>(dstp + x * 4 + 32), result_hi); | |
| 186 | } | ||
| 187 | else { | ||
| 188 | // rgb24 | ||
| 189 | // 16*4 bytes to 16*3 bytes | ||
| 190 | 18 | __m256i perm10 = _mm256_set_epi32(0, 0, 6, 5, 4, 2, 1, 0); | |
| 191 | 18 | __m256i shuffle_lo = _mm256_set_epi8( | |
| 192 | 0, 0, 0, 0, 14, 13, 12, 10, 9, 8, 6, 5, 4, 2, 1, 0, | ||
| 193 | 0, 0, 0, 0, 14, 13, 12, 10, 9, 8, 6, 5, 4, 2, 1, 0 | ||
| 194 | ); | ||
| 195 | 18 | __m128i shuffle_hi_lo = _mm_set_epi8(9, 8, 6, 5, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); | |
| 196 | |||
| 197 | 18 | __m128i result_hi_lo = _mm256_extracti128_si256(result_hi, 0); // aBbBgBrB aAbAgArA a9b9g9r9 a8b8g8r8 | |
| 198 | 18 | __m128i result_hi_hi = _mm256_extracti128_si256(result_hi, 1); // aFbFgFrF aEbEgErE aDbDgDrD aCbCgCrC | |
| 199 | |||
| 200 | 18 | __m256i result_lo_reorg = _mm256_shuffle_epi8(result_lo, shuffle_lo); | |
| 201 | // x x x x b7g7r7 b6g6r6 b5g5r5 b4g4r4 x x x x b3g3r3 b2g2r2 b1g1r1 b0g0r0 | ||
| 202 | 18 | result_lo_reorg = _mm256_permutevar8x32_epi32(result_lo_reorg, perm10); | |
| 203 | // x x x x x x x x b7g7r7 b6g6r6 b5g5r5 b4g4r4 b3g3r3 b2g2r2 b1g1r1 b0g0r0 | ||
| 204 | |||
| 205 | 18 | __m128i result_hi_lo_reorg = _mm_shuffle_epi8(result_hi_lo, shuffle_hi_lo); | |
| 206 | // gA rA b9 g9 r9 b8 g8 r8 x x x x x x x x | ||
| 207 | |||
| 208 | 18 | __m256i dummy_y0 = _mm256_undefined_si256(); | |
| 209 | 18 | auto result_hi_lo_reorg_2 = _mm256_inserti128_si256(dummy_y0, result_hi_lo_reorg, 1); | |
| 210 | // | ||
| 211 | // gA rA b9 g9|r9 b8 g8 r8|x x x x|x x x x|x x x x |x x x x|x x x x|x x x x // result_hi_lo_reorg_2 | ||
| 212 | // x x x x x x x x b7g7r7 b6g6r6 b5g5r5 b4g4r4 b3g3r3 b2g2r2 b1g1r1 b0g0r0 // result_lo_reorg | ||
| 213 | 18 | auto result_0_15 = _mm256_blend_epi32(result_lo_reorg, result_hi_lo_reorg_2, 0xC0); // 11000000 | |
| 214 | 18 | _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + x * 3), result_0_15); // not necessarily 32 bytes aligned | |
| 215 | |||
| 216 | // => x x x x x x x x x x x x bB gB rB bA | ||
| 217 | 18 | __m128i shuffle_hi_lo_2 = _mm_set_epi8((char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, 14, 13, 12, 10); | |
| 218 | 18 | __m128i xmm4 = _mm_shuffle_epi8(result_hi_lo, shuffle_hi_lo_2); | |
| 219 | |||
| 220 | // => bF gF rF bE gE rE bD gD rD bC gC rC x x x x | ||
| 221 | 18 | __m128i shuffle_hi_hi = _mm_set_epi8(14, 13, 12, 10, 9, 8, 6, 5, 4, 2, 1, 0, (char)0x80, (char)0x80, (char)0x80, (char)0x80); | |
| 222 | 18 | __m128i xmm5 = _mm_shuffle_epi8(result_hi_hi, shuffle_hi_hi); | |
| 223 | |||
| 224 | // => bF gF rF bE gE rE bD gD rD bC gC rC bB gB rB bA | ||
| 225 | 18 | __m128i result_16_23 = _mm_or_si128(xmm4, xmm5); | |
| 226 | 18 | _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x * 3 + 32), result_16_23); | |
| 227 | #if 0 | ||
| 228 | // Intel compiler can cope with it 100% optimized. No store, just shuffles and blends as above. | ||
| 229 | alignas(32) BYTE temp[64]; | ||
| 230 | _mm256_store_si256(reinterpret_cast<__m256i*>(temp), result_lo); | ||
| 231 | _mm256_store_si256(reinterpret_cast<__m256i*>(temp + 32), result_hi); | ||
| 232 | for (int i = 0; i < 16; ++i) { | ||
| 233 | dstp[(x + i) * 3 + 0] = temp[i * 4 + 0]; | ||
| 234 | dstp[(x + i) * 3 + 1] = temp[i * 4 + 1]; | ||
| 235 | dstp[(x + i) * 3 + 2] = temp[i * 4 + 2]; | ||
| 236 | } | ||
| 237 | #endif | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | if constexpr (rgb_pixel_step == 3) { | ||
| 242 | // for rgb32 (pixel_step == 4) we processed full width and more, including padded bytes | ||
| 243 |
2/4void convert_yv24_to_rgb_avx2<3, false>(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, ConversionMatrix const&):
✓ Branch 249 → 245 taken 27 times.
✓ Branch 249 → 250 taken 9 times.
void convert_yv24_to_rgb_avx2<3, true>(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, ConversionMatrix const&):
✗ Branch 255 → 251 not taken.
✗ Branch 255 → 256 not taken.
|
36 | for (size_t x = mod16_width; x < width; ++x) { |
| 244 | 27 | int Y = srcY[x] + matrix.offset_y; | |
| 245 | 27 | int U = srcU[x] - 128; | |
| 246 | 27 | int V = srcV[x] - 128; | |
| 247 | 27 | int b = (((int)matrix.y_b * Y + (int)matrix.u_b * U + (int)matrix.v_b * V + round_mask_plus_rgb_offset_i) >> 13); | |
| 248 | 27 | int g = (((int)matrix.y_g * Y + (int)matrix.u_g * U + (int)matrix.v_g * V + round_mask_plus_rgb_offset_i) >> 13); | |
| 249 | 27 | int r = (((int)matrix.y_r * Y + (int)matrix.u_r * U + (int)matrix.v_r * V + round_mask_plus_rgb_offset_i) >> 13); | |
| 250 | 27 | dstp[x * rgb_pixel_step + 0] = PixelClip(b); | |
| 251 | 27 | dstp[x * rgb_pixel_step + 1] = PixelClip(g); | |
| 252 | 27 | dstp[x * rgb_pixel_step + 2] = PixelClip(r); | |
| 253 | if constexpr (rgb_pixel_step == 4) { // n/a | ||
| 254 | dstp[x * 4 + 3] = 255; | ||
| 255 | } | ||
| 256 | } | ||
| 257 | } | ||
| 258 | 24 | dstp -= dst_pitch; | |
| 259 | 24 | srcY += src_pitch_y; | |
| 260 | 24 | srcU += src_pitch_uv; | |
| 261 | 24 | srcV += src_pitch_uv; | |
| 262 | if constexpr(hasAlpha) | ||
| 263 | 9 | srcA += src_pitch_a; | |
| 264 | } | ||
| 265 | 8 | } | |
| 266 | |||
| 267 | //instantiate | ||
| 268 | //template<int rgb_pixel_step, bool targetHasAlpha> | ||
| 269 | template void convert_yv24_to_rgb_avx2<3, false>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE* srcV, const BYTE* srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix& matrix); | ||
| 270 | template void convert_yv24_to_rgb_avx2<4, false>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE* srcV, const BYTE* srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix& matrix); | ||
| 271 | template void convert_yv24_to_rgb_avx2<3, true>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE* srcV, const BYTE* srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix& matrix); | ||
| 272 | template void convert_yv24_to_rgb_avx2<4, true>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE* srcV, const BYTE* srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix& matrix); | ||
| 273 | |||
| 274 | #define XP_LAMBDA_CAPTURE_FIX(x) (void)(x) | ||
| 275 | /* | ||
| 276 | ================================================================================ | ||
| 277 | YUV ↔ RGB Color Space Conversion - Unified Implementation | ||
| 278 | ================================================================================ | ||
| 279 | |||
| 280 | This module provides a unified, highly optimized implementation for color space | ||
| 281 | conversions between YUV and RGB formats, supporting all bit depths (8-16 bit | ||
| 282 | integer and 32-bit float) with optional bit-depth conversion. | ||
| 283 | |||
| 284 | CONVERSION DIRECTIONS: | ||
| 285 | - YUV_TO_RGB: YUV → RGB (e.g., video decode path) | ||
| 286 | - RGB_TO_YUV: RGB → YUV (e.g., video encode path) | ||
| 287 | - YUV_TO_YUV: YUV → YUV (e.g., BT.601 → BT.709 matrix conversion) | ||
| 288 | - RGB_TO_RGB: RGB → RGB (e.g., gamut/color correction) | ||
| 289 | |||
| 290 | ARITHMETIC PRECISION: | ||
| 291 | - YUV→RGB / RGB→RGB: 13-bit fixed-point (coefficients scaled by 2^13 = 8192) | ||
| 292 | - RGB→YUV: 15-bit fixed-point (coefficients scaled by 2^15 = 32768) | ||
| 293 | - YUV→YUV: 14-bit fixed-point (fused matrix precision) | ||
| 294 | |||
| 295 | PLANE MEMORY LAYOUT: | ||
| 296 | - YUV: Plane[0]=Y, Plane[1]=U, Plane[2]=V | ||
| 297 | - RGB: Plane[0]=G, Plane[1]=B, Plane[2]=R (AviSynth convention) | ||
| 298 | |||
| 299 | ================================================================================ | ||
| 300 | */ | ||
| 301 | |||
| 302 | /** | ||
| 303 | * @enum YuvRgbConversionType | ||
| 304 | * @brief Defines the conversion workflow type for color space transformations | ||
| 305 | * | ||
| 306 | * Each conversion type determines: | ||
| 307 | * - Whether to use integer or float arithmetic for the matrix multiply | ||
| 308 | * - How input/output offsets are applied | ||
| 309 | * - Whether bit-depth conversion is integrated into the workflow | ||
| 310 | * - Whether 16-bit pivot trick is needed for exact 16-bit integer paths | ||
| 311 | * | ||
| 312 | * CONVERSION TYPE COMPARISON TABLE: | ||
| 313 | * ┌─────────────────────┬────────────┬─────────────┬──────────────┬─────────────┬──────────────┐ | ||
| 314 | * │ Conversion Type │ 16-bit │ Input │ Matrix │ Post-Matrix │ Bit-Depth │ | ||
| 315 | * │ │ Pivot? │ Offset │ Coefficients │ Rounding │ Scaling │ | ||
| 316 | * ├─────────────────────┼────────────┼─────────────┼──────────────┼─────────────┼──────────────┤ | ||
| 317 | * │ NATIVE_INT │ Yes (16) │ After load │ Integer │ Yes (shift) │ None │ | ||
| 318 | * │ │ No (<16) │ (16-bit add)│ (13/15-bit) │ Integrated │ │ | ||
| 319 | * ├─────────────────────┼────────────┼─────────────┼──────────────┼─────────────┼──────────────┤ | ||
| 320 | * │ FORCE_FLOAT │ N/A │ Pre-matrix │ Float │ Float+0.5 │ In scale_f │ | ||
| 321 | * │ │ │ (float add) │ (scaled) │ (if int out)│ │ | ||
| 322 | * ├─────────────────────┼────────────┼─────────────┼──────────────┼─────────────┼──────────────┤ | ||
| 323 | * │ FLOAT_OUTPUT │ Yes (16) │ After load │ Integer │ No shift │ Post-matrix │ | ||
| 324 | * │ │ No (<16) │ (16-bit add)│ (13/15-bit) │ (int→float) │ (scale_f) │ | ||
| 325 | * ├─────────────────────┼────────────┼─────────────┼──────────────┼─────────────┼──────────────┤ | ||
| 326 | * │ BITCONV_INT_LIMITED │ Yes (16) │ After load │ Integer │ Yes (adj. │ Integrated │ | ||
| 327 | * │ │ No (<16) │ (16-bit add)│ (13/15-bit) │ shift) │ into shift │ | ||
| 328 | * ├─────────────────────┼────────────┼─────────────┼──────────────┼─────────────┼──────────────┤ | ||
| 329 | * │ BITCONV_INT_FULL │ N/A │ Pre-matrix │ Float │ Float+0.5 │ In scale_f │ | ||
| 330 | * │ │ │ (float add) │ (scaled) │ (if int out)│ │ | ||
| 331 | * └─────────────────────┴────────────┴─────────────┴──────────────┴─────────────┴──────────────┘ | ||
| 332 | * | ||
| 333 | * OFFSET APPLICATION DETAILS: | ||
| 334 | * ┌─────────────────────┬─────────────────────────────────────────────────────────────────────┐ | ||
| 335 | * │ Conversion Type │ Offset Application Strategy │ | ||
| 336 | * ├─────────────────────┼─────────────────────────────────────────────────────────────────────┤ | ||
| 337 | * │ NATIVE_INT │ • <16-bit: offset_in added as int16 after load │ | ||
| 338 | * │ │ • 16-bit: offset_in in 32-bit patch after MADD (with pivot) │ | ||
| 339 | * │ │ • Output: offset_out in MADD rounding constant (scaled by 2^13/15) │ | ||
| 340 | * ├─────────────────────┼─────────────────────────────────────────────────────────────────────┤ | ||
| 341 | * │ FORCE_FLOAT │ • Input: offset_in added as float before matrix multiply │ | ||
| 342 | * │ │ • Output: offset_out added as float in matrix result │ | ||
| 343 | * │ │ • Coefficients pre-scaled by scale_f for bit-depth conversion │ | ||
| 344 | * ├─────────────────────┼─────────────────────────────────────────────────────────────────────┤ | ||
| 345 | * │ FLOAT_OUTPUT │ • Input: Same as NATIVE_INT (int16 or 32-bit patch) │ | ||
| 346 | * │ │ • Output: No offset in MADD; added post-conversion in float domain │ | ||
| 347 | * │ │ • Result: int32 → float with scale_f, then + offset_out_f │ | ||
| 348 | * ├─────────────────────┼─────────────────────────────────────────────────────────────────────┤ | ||
| 349 | * │ BITCONV_INT_LIMITED │ • Same as NATIVE_INT but with adjusted shift (13 - bit_diff) │ | ||
| 350 | * │ │ • Chroma offset uses SOURCE bit depth (half_pixel_offset) │ | ||
| 351 | * │ │ • Bit-depth scaling integrated into the right-shift operation │ | ||
| 352 | * ├─────────────────────┼─────────────────────────────────────────────────────────────────────┤ | ||
| 353 | * │ BITCONV_INT_FULL │ • Same as FORCE_FLOAT (uses float workflow internally) │ | ||
| 354 | * │ │ • Required for full-range bit-depth conversions (e.g., 10→8 full) │ | ||
| 355 | * └─────────────────────┴─────────────────────────────────────────────────────────────────────┘ | ||
| 356 | * | ||
| 357 | * 16-BIT PIVOT TECHNIQUE (for integer paths only): | ||
| 358 | * Problem: uint16 range [0, 65535] doesn't fit in signed int16 [-32768, 32767] | ||
| 359 | * Solution: Flip MSB to pivot unsigned to signed: Y_signed = Y XOR 0x8000 | ||
| 360 | * - 0 → -32768, 65535 → 32767 (all values fit in int16) | ||
| 361 | * - Correction applied in 32-bit patch: add (32768 + offset_in) × coefficients | ||
| 362 | * - See detailed explanation at top of function | ||
| 363 | * | ||
| 364 | * CHROMA CENTERING: | ||
| 365 | * YUV Input: U/V centered around half (e.g., 128 for 8-bit) → subtract half | ||
| 366 | * YUV Output: U/V centered around half → add half after matrix | ||
| 367 | * RGB: No centering (all values have same zero point) | ||
| 368 | * | ||
| 369 | * PERFORMANCE CHARACTERISTICS: | ||
| 370 | * - AVX2: 32 pixels per iteration (primary target, 2013+ CPUs) | ||
| 371 | * - SSE2: 8 pixels per iteration (legacy compatibility) | ||
| 372 | * - Integer MADD path: ~4000-5400 fps (1920×1080, 8-bit, Ryzen) | ||
| 373 | * - Float workflow: ~3200-3900 fps (10-26% slower, but necessary for some cases) | ||
| 374 | * | ||
| 375 | * EXAMPLE USE CASES: | ||
| 376 | * YUV→RGB, 10-bit→10-bit, limited range: | ||
| 377 | * → NATIVE_INT (integer MADD, no bit conversion) | ||
| 378 | * | ||
| 379 | * YUV→RGB, 10-bit→8-bit, limited→limited: | ||
| 380 | * → BITCONV_INT_LIMITED (integrated bit scaling in shift) | ||
| 381 | * | ||
| 382 | * YUV→RGB, 10-bit→8-bit, full→full: | ||
| 383 | * → BITCONV_INT_FULL (uses float workflow internally) | ||
| 384 | * | ||
| 385 | * YUV→RGB, 16-bit→32-bit float: | ||
| 386 | * → FORCE_FLOAT (required for float input) | ||
| 387 | * | ||
| 388 | * YUV→RGB, 8-bit→32-bit float, limited→full: | ||
| 389 | * → FLOAT_OUTPUT (integer matrix, float output with range expansion) | ||
| 390 | * | ||
| 391 | * YUV(BT.601)→YUV(BT.709), 10-bit→10-bit: | ||
| 392 | * → NATIVE_INT with fused conversion matrix (avoids RGB intermediate) | ||
| 393 | */ | ||
| 394 | |||
| 395 | /** | ||
| 396 | * @brief Universal color space conversion function (AVX2 optimized) | ||
| 397 | * | ||
| 398 | * Converts between YUV and RGB color spaces with optional bit-depth conversion. | ||
| 399 | * Supports all combinations of 8/10/12/14/16-bit integer and 32-bit float formats. | ||
| 400 | * | ||
| 401 | * @tparam direction Conversion direction (YUV_TO_RGB, RGB_TO_YUV, YUV_TO_YUV, RGB_TO_RGB) | ||
| 402 | * @tparam pixel_t Input pixel type (uint8_t, uint16_t, or float) | ||
| 403 | * @tparam lessthan16bit True if input is 8/10/12/14-bit (enables optimizations) | ||
| 404 | * @tparam lessthan16bit_target True if output is 8/10/12/14-bit (enables clamping) | ||
| 405 | * @tparam pixel_t_dst Output pixel type (uint8_t, uint16_t, or float) | ||
| 406 | * @tparam conv_type Conversion workflow type (see YuvRgbConversionType) | ||
| 407 | * | ||
| 408 | * @param dstp Output plane pointers [3] (G/Y, B/U, R/V) | ||
| 409 | * @param dstPitch Output plane pitches in bytes [3] | ||
| 410 | * @param srcp Input plane pointers [3] (G/Y, B/U, R/V) | ||
| 411 | * @param srcPitch Input plane pitches in bytes [3] | ||
| 412 | * @param width Frame width in pixels | ||
| 413 | * @param height Frame height in pixels | ||
| 414 | * @param m Conversion matrix with coefficients and offsets | ||
| 415 | * @param bits_per_pixel Input bit depth (8-16) | ||
| 416 | * @param bits_per_pixel_target Output bit depth (8-16) | ||
| 417 | * | ||
| 418 | * @note Matrix coefficients in ConversionMatrix must be pre-scaled: | ||
| 419 | * - Integer coefficients: scaled by 2^13 (YUV↔RGB) or 2^15 (RGB→YUV) | ||
| 420 | * - Float coefficients: unscaled, will be multiplied by scale_f internally | ||
| 421 | * | ||
| 422 | * @note For 16-bit integer paths, the function uses a pivot trick to work around | ||
| 423 | * signed int16 range limitations. See detailed comment at function start. | ||
| 424 | * | ||
| 425 | * @note Processes 32 pixels per iteration on AVX2. For float input/output, includes | ||
| 426 | * safety checks to respect 64-byte scanline alignment guarantees. | ||
| 427 | */ | ||
| 428 | template<ConversionDirection direction, typename pixel_t, bool lessthan16bit, bool lessthan16bit_target, typename pixel_t_dst, YuvRgbConversionType conv_type> | ||
| 429 | 52 | static void convert_yuv_to_planarrgb_avx2_internal(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, | |
| 430 | int bits_per_pixel, int bits_per_pixel_target) | ||
| 431 | { | ||
| 432 | |||
| 433 | 52 | constexpr int INT_ARITH_SHIFT = | |
| 434 | (direction == ConversionDirection::YUV_TO_RGB) ? 13 : | ||
| 435 | (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_Y) ? 15 : | ||
| 436 | (direction == ConversionDirection::YUV_TO_YUV) ? 14 : 13; | ||
| 437 | |||
| 438 | // 8 bit uint8_t | ||
| 439 | // 10,12,14 bit uint16_t (signed range) | ||
| 440 | // 16 bit logic: | ||
| 441 | /* | ||
| 442 | 1. pivot the pixel: | ||
| 443 | Convert uint16 pixel Y to a signed int16 by flipping the MSB (this is mathematically identical to Y−32768). | ||
| 444 | 0 becomes −32768. | ||
| 445 | 65535 becomes 32767. | ||
| 446 | All values now fit in int16 without saturation. | ||
| 447 | 2. reorganize the formula (offset_in is negative when exists, e.g. -4096): | ||
| 448 | Original: (Y + offset_y) * Cy | ||
| 449 | Substitute | ||
| 450 | Y = (Ysigned + 32768) | ||
| 451 | => (Ysigned + 32768 + offset_y) * Cy | ||
| 452 | => (Ysigned * Cy) + (32768 + offset_y) * Cy) | ||
| 453 | 3. correction after the madd section: | ||
| 454 | Add ((32768 + offset_y) * Cy) to the existing 32-bit rounding/offset_in constant. | ||
| 455 | 4. Output rgb offset_in is also added to the precalculated patch. | ||
| 456 | */ | ||
| 457 | |||
| 458 | // When input is float (pixel_t), float workflow (FORCE_FLOAT) is compulsory. | ||
| 459 | // But not the opposite: FORCE_FLOAT and not float input is fine | ||
| 460 | // make a static assert | ||
| 461 | static_assert(!(std::is_floating_point<pixel_t>::value && conv_type != YuvRgbConversionType::FORCE_FLOAT), "FORCE_FLOAT conversion type is required for float input pixel type"); | ||
| 462 | |||
| 463 | 52 | constexpr bool final_is_float = std::is_floating_point<pixel_t_dst>::value; | |
| 464 | 52 | constexpr bool would_need_64bit_v_patch = !lessthan16bit && !final_is_float && (INT_ARITH_SHIFT == 15); | |
| 465 | // RGB_TO_YUV, RGB_TO_Y 16 bit origin case needs 64 bit extension at one point to avoid overflow | ||
| 466 | // but it makes it much slower than the full-float path, so we force float path for that case as well | ||
| 467 | |||
| 468 | // effectively full-float-inside for int full range conversion, but with the same output rules as other float conversions | ||
| 469 | 52 | constexpr bool force_float = (conv_type == YuvRgbConversionType::FORCE_FLOAT) || would_need_64bit_v_patch; | |
| 470 | |||
| 471 | 52 | constexpr bool need_int_conversion_narrow_range = conv_type == YuvRgbConversionType::BITCONV_INT_LIMITED; // full_d is false | |
| 472 | 52 | constexpr bool need_int_conversion_full_range = conv_type == YuvRgbConversionType::BITCONV_INT_FULL; // full_d is true | |
| 473 | 52 | constexpr bool need_int_conversion = conv_type == YuvRgbConversionType::BITCONV_INT_FULL || conv_type == YuvRgbConversionType::BITCONV_INT_LIMITED || | |
| 474 | (conv_type == YuvRgbConversionType::FORCE_FLOAT && !final_is_float); | ||
| 475 | |||
| 476 | 52 | constexpr bool float_matrix_workflow = force_float || need_int_conversion_full_range; // effectively full-float-inside for int full range conversion | |
| 477 | |||
| 478 | // quasi-constexpr, may help optimizer | ||
| 479 | 22 | if constexpr (std::is_same<pixel_t, uint8_t>::value) bits_per_pixel = 8; | |
| 480 | 19 | if constexpr (std::is_same<pixel_t_dst, uint8_t>::value) bits_per_pixel_target = 8; | |
| 481 | 11 | if constexpr (std::is_same<pixel_t, uint16_t>::value && !lessthan16bit) bits_per_pixel = 16; | |
| 482 | 11 | if constexpr (std::is_same<pixel_t_dst, uint16_t>::value && !lessthan16bit_target) bits_per_pixel_target = 16; | |
| 483 | 28 | if constexpr (conv_type == YuvRgbConversionType::NATIVE_INT) bits_per_pixel_target = bits_per_pixel; | |
| 484 | |||
| 485 | 52 | const int bit_diff = need_int_conversion ? bits_per_pixel_target - bits_per_pixel : 0; | |
| 486 | 52 | const int target_shift = need_int_conversion_narrow_range ? INT_ARITH_SHIFT - bit_diff : INT_ARITH_SHIFT; // int->int narrow range: integrate the bit depth conversion into the scaling back | |
| 487 | |||
| 488 | 52 | const int ROUNDER = (final_is_float || float_matrix_workflow) ? 0 : (1 << (target_shift - 1)); // 0 when float internal calculation is involved | |
| 489 | |||
| 490 | // For integer workflow + final is float: | ||
| 491 | 52 | const float out_offset_f = m.offset_out_f_32; // for post-32-bit float conversion | |
| 492 | |||
| 493 | 52 | const int half_pixel_offset = 1 << (bits_per_pixel - 1); // YUV --> // at input is float: n/a | |
| 494 | 52 | const int half_pixel_offset_target = 1 << (bits_per_pixel_target - 1); // For float_matrix_workflow or output is float | |
| 495 | 52 | const int max_pixel_value_target = (1 << bits_per_pixel_target) - 1; | |
| 496 | |||
| 497 | 52 | bits_conv_constants conversion_ranges; | |
| 498 | 52 | const bool full_scale_d = m.offset_out == 0; | |
| 499 | // matrix is handling only the same-bit-depth factor. Output result must be scaled as if | ||
| 500 | // we further correct it with a post-matrix scaling for bit depth conversion which depends only | ||
| 501 | // on the destination limite/full | ||
| 502 |
23/320void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 4 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned char, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 8 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 2 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 4 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned char, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 5 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 2 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned char, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 2 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned char, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 2 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 2 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 2 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 24 not taken.
|
52 | get_bits_conv_constants(conversion_ranges, false, full_scale_d, full_scale_d, bits_per_pixel, bits_per_pixel_target); // our final scale would be as if work to float |
| 503 | |||
| 504 | 52 | constexpr int int_arithmetic_shift = 1 << INT_ARITH_SHIFT; | |
| 505 | 52 | float scale_f = conversion_ranges.mul_factor; | |
| 506 | // Integer matrix workflow + 32 bit final float output extra rules | ||
| 507 | // - no rounding and scaling back INT_ARITH_SHIFT e.g. 13 for YUV-RGB, 15 for RGB-YUV bits | ||
| 508 | // - no clamping to bit depth limits | ||
| 509 | // - the INT_ARITH_SHIFT-bit scaling factor is integrated into the bits_per_pixel shift | ||
| 510 | if (final_is_float && !float_matrix_workflow) | ||
| 511 | ✗ | scale_f = scale_f / int_arithmetic_shift; // int workflow, float at the end | |
| 512 | |||
| 513 | 52 | __m256i half = _mm256_set1_epi16((short)half_pixel_offset); // 128 | |
| 514 | 52 | __m256i limit = _mm256_set1_epi16((short)max_pixel_value_target); // 255 | |
| 515 | |||
| 516 | // to be able to use it as signed 16 bit in madd; 4096+(16<<13) would not fit into i16 | ||
| 517 | // multiplier is 4096 instead of 1: | ||
| 518 | // original : 1 * 4096 | ||
| 519 | // needed : 1 * (4096 + offset_rgb<<13) (4096 + 131072 overflows i16) | ||
| 520 | // changed to : 4096 * (1 + offset_rgb>>(13-1) | ||
| 521 | // Except for exact 16 bit, where we do the output offset_in adjustment along with the 16 bit signed-unsigned pivot fix | ||
| 522 | 52 | constexpr int ROUND_SCALE = 1 << (INT_ARITH_SHIFT - 1); // 1 << 12, for 13 bit integer arithmetic: "0.5" | |
| 523 | 52 | const __m256i m256i_round_scale = _mm256_set1_epi16(ROUND_SCALE); | |
| 524 | |||
| 525 | int round_mask_plus_offset_out_scaled_i; | ||
| 526 | int round_mask_plus_offset_out_chroma_scaled_i; | ||
| 527 | |||
| 528 | // integer workflow + exact 16 bit path: needs a special handling for the pivot and input offset_in and output rgb offset_out | ||
| 529 | __m256i v_patch_G, v_patch_B, v_patch_R; | ||
| 530 | 52 | __m256i sign_flip_mask = _mm256_set1_epi16((short)0x8000); // for 16 bit pivot | |
| 531 | |||
| 532 | // Full-range is float-workflow inside, so no need to do any of the above adjustments in | ||
| 533 | // integer arithmetic, just do the full float conversion and clamp at the end if needed | ||
| 534 | |||
| 535 | // Input offset_in handling | ||
| 536 | 52 | const int offset_in_scalar = m.offset_in; | |
| 537 | 52 | const int offset_out_scalar = m.offset_out; | |
| 538 | |||
| 539 | __m256i offset_in; | ||
| 540 | __m256 offset_in_f; | ||
| 541 | if constexpr (float_matrix_workflow) { | ||
| 542 | 25 | offset_in = _mm256_set1_epi32(offset_in_scalar); // float workflow, integer inputs | |
| 543 | 50 | offset_in_f = _mm256_set1_ps(m.offset_in_f); // float workflow, float inputs | |
| 544 | } | ||
| 545 | else if constexpr (lessthan16bit) // integer workflow, lessthan16 bit path | ||
| 546 | 22 | offset_in = _mm256_set1_epi16((short)offset_in_scalar); // input offset_in correction can happen in 16 bit arithmetic | |
| 547 | else // n/a, for exact 16 bit integer workflow, the offset_in is handled in the 32-bit patch together with the pivot adjustment | ||
| 548 | 5 | offset_in = _mm256_setzero_si256(); | |
| 549 | |||
| 550 | if constexpr (!float_matrix_workflow) { | ||
| 551 | // integer preparations for the madd-based main loop | ||
| 552 | if constexpr (lessthan16bit) { | ||
| 553 | // 8-14 bit | ||
| 554 | // offset of same magnitude as coeffs, also in simd madd | ||
| 555 | 22 | round_mask_plus_offset_out_scaled_i = final_is_float ? 0 : (ROUNDER + (offset_out_scalar << INT_ARITH_SHIFT)) / ROUND_SCALE; | |
| 556 | 22 | round_mask_plus_offset_out_chroma_scaled_i = final_is_float ? 0 : (ROUNDER + (half_pixel_offset << INT_ARITH_SHIFT)) / ROUND_SCALE; | |
| 557 | 22 | v_patch_G = v_patch_B = v_patch_R = _mm256_setzero_si256(); // No patch needed, since the signed 16-bit workaround is not needed. | |
| 558 | } | ||
| 559 | else { | ||
| 560 | // exact 16 bit | ||
| 561 | // keep madd simple: only handle the rounding (ROUND_SCALE * 1) | ||
| 562 | // rgb offset is handled later in the patch, after the madd, added to the same place as the pivot adjustment | ||
| 563 | 5 | round_mask_plus_offset_out_scaled_i = ROUNDER / ROUND_SCALE; // effectively 1 or 0 (final_is_float) | |
| 564 | 5 | round_mask_plus_offset_out_chroma_scaled_i = ROUNDER / ROUND_SCALE; // effectively 1 or 0 (final_is_float) | |
| 565 | |||
| 566 | // move BOTH the pivot and the output offset to the 32-bit patch | ||
| 567 | // Since we have to do the patching anyway, we can combine both adjustments here | ||
| 568 | 5 | const int luma_or_rgbin_pivot = 32768 + offset_in_scalar; | |
| 569 | 5 | const int chroma_pivot = 32768; | |
| 570 | 5 | const int offset_out_for_patch = final_is_float ? 0 : (offset_out_scalar << INT_ARITH_SHIFT); // 32-bit post-conversion adds offset in float domain. | |
| 571 | 5 | const int chroma_offset_out_for_patch = final_is_float ? 0 : (half_pixel_offset << INT_ARITH_SHIFT); // 32-bit post-conversion adds offset in float domain. | |
| 572 | |||
| 573 | if constexpr (direction == ConversionDirection::YUV_TO_RGB) { | ||
| 574 | // for YUV->RGB, the pivot adjustment is needed for all three channels since the luma coeffs are not zero, but pivot only the Y | ||
| 575 | 3 | v_patch_G = _mm256_set1_epi32(luma_or_rgbin_pivot * m.y_g + offset_out_for_patch); | |
| 576 | 3 | v_patch_B = _mm256_set1_epi32(luma_or_rgbin_pivot * m.y_b + offset_out_for_patch); | |
| 577 | 6 | v_patch_R = _mm256_set1_epi32(luma_or_rgbin_pivot * m.y_r + offset_out_for_patch); | |
| 578 | } | ||
| 579 | else if constexpr (direction == ConversionDirection::RGB_TO_RGB) { | ||
| 580 | // for RGB->RGB, the pivot adjustment is needed for all three channels in and aout | ||
| 581 | v_patch_G = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.y_g + m.u_g + m.v_g) + offset_out_for_patch); | ||
| 582 | v_patch_B = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.y_b + m.u_b + m.v_b) + offset_out_for_patch); | ||
| 583 | v_patch_R = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.y_r + m.u_r + m.v_r) + offset_out_for_patch); | ||
| 584 | } | ||
| 585 | else if constexpr (direction == ConversionDirection::RGB_TO_YUV) { | ||
| 586 | // RGB→YUV: All RGB inputs are pivoted, need to account for all three | ||
| 587 | // Out0=Y (luma offset), Out1=U and Out2=V (chroma offset) | ||
| 588 | // Y output = y_r*R + y_g*G + y_b*B | ||
| 589 | if constexpr (!would_need_64bit_v_patch) { | ||
| 590 | ✗ | v_patch_G = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.y_r + m.y_g + m.y_b) + offset_out_for_patch); | |
| 591 | // U output = u_r*R + u_g*G + u_b*B | ||
| 592 | ✗ | v_patch_B = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.u_r + m.u_g + m.u_b) + chroma_offset_out_for_patch); | |
| 593 | // V output = v_r*R + v_g*G + v_b*B | ||
| 594 | ✗ | v_patch_R = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.v_r + m.v_g + m.v_b) + chroma_offset_out_for_patch); | |
| 595 | } | ||
| 596 | else { | ||
| 597 | // this path must error out, never can be used, redirected to full-float workflow for this case due to speed reasons. | ||
| 598 | static_assert(!would_need_64bit_v_patch, "64-bit patch needed for RGB->YUV conversion, but not supported in this path. Redirected to float workflow instead."); | ||
| 599 | v_patch_G = _mm256_set1_epi64x(luma_or_rgbin_pivot * (m.y_r + m.y_g + m.y_b) + offset_out_for_patch); | ||
| 600 | v_patch_B = _mm256_set1_epi64x(luma_or_rgbin_pivot * (m.u_r + m.u_g + m.u_b) + chroma_offset_out_for_patch); | ||
| 601 | v_patch_R = _mm256_set1_epi64x(luma_or_rgbin_pivot * (m.v_r + m.v_g + m.v_b) + chroma_offset_out_for_patch); | ||
| 602 | } | ||
| 603 | } | ||
| 604 | else if constexpr (direction == ConversionDirection::RGB_TO_Y) { | ||
| 605 | // RGB→YUV: All RGB inputs are pivoted, need to account for all three | ||
| 606 | // Out0=Y (luma offset), No chroma | ||
| 607 | // Y output = y_r*R + y_g*G + y_b*B | ||
| 608 | if constexpr (!would_need_64bit_v_patch) { | ||
| 609 | ✗ | v_patch_G = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.y_r + m.y_g + m.y_b) + offset_out_for_patch); | |
| 610 | //v_patch_B = _mm256_set1_epi32(0); // no chroma | ||
| 611 | //v_patch_R = _mm256_set1_epi32(0); // no chroma | ||
| 612 | } | ||
| 613 | else { | ||
| 614 | // this path must error out, never can be used, redirected to full-float workflow for this case due to speed reasons. | ||
| 615 | static_assert(!would_need_64bit_v_patch, "64-bit patch needed for RGB->Y conversion, but not supported in this path. Redirected to float workflow instead."); | ||
| 616 | v_patch_G = _mm256_set1_epi64x(luma_or_rgbin_pivot * (m.y_r + m.y_g + m.y_b) + offset_out_for_patch); | ||
| 617 | //v_patch_B = _mm256_set1_epi64x(0); // no chroma | ||
| 618 | //v_patch_R = _mm256_set1_epi64x(0); // no chroma | ||
| 619 | } | ||
| 620 | } | ||
| 621 | else if constexpr (direction == ConversionDirection::YUV_TO_YUV) { | ||
| 622 | // for YUV->YUV | ||
| 623 | // FIXME: untested, no AviSynth caller yet. Suspect m.y_b/m.y_r should be | ||
| 624 | // m.u_b/m.v_r (chroma diagonal), and offset should be chroma_offset_out_for_patch. | ||
| 625 | 2 | v_patch_G = _mm256_set1_epi32(luma_or_rgbin_pivot * m.y_g + offset_out_for_patch); | |
| 626 | 2 | v_patch_B = _mm256_set1_epi32(chroma_pivot * m.y_b + offset_out_for_patch); | |
| 627 | 4 | v_patch_R = _mm256_set1_epi32(chroma_pivot * m.y_r + offset_out_for_patch); | |
| 628 | } | ||
| 629 | } | ||
| 630 | } | ||
| 631 | |||
| 632 | // For integer workflow + final is float | ||
| 633 | 52 | const __m256 out_offset_f_avx2 = _mm256_set1_ps(out_offset_f); | |
| 634 | |||
| 635 | 52 | __m256i zero = _mm256_setzero_si256(); | |
| 636 | 52 | const __m256 scale_f_avx2 = _mm256_set1_ps(scale_f); | |
| 637 | |||
| 638 | // For integer workflow | ||
| 639 | __m256i m_uy_G, m_vr_G, m_uy_B, m_vr_B, m_uy_R, m_vr_R; // integer arithmetic, including 32-bit float target when non-float_matrix_workflow | ||
| 640 | // For float_matrix_workflow: define coefficient accessors based on direction | ||
| 641 | __m256 coeff_out0_in0, coeff_out0_in1, coeff_out0_in2; // First output row | ||
| 642 | __m256 coeff_out1_in0, coeff_out1_in1, coeff_out1_in2; // Second output row | ||
| 643 | __m256 coeff_out2_in0, coeff_out2_in1, coeff_out2_in2; // Third output row | ||
| 644 | |||
| 645 | __m256 m_offset_out_y_or_g_f, m_offset_out_u_or_b_f, m_offset_out_v_or_r_f; // three separate offsets, in YUV-RGB they are the same, in RGB-YUV they are different for luma and chroma | ||
| 646 | |||
| 647 | if constexpr (float_matrix_workflow) { | ||
| 648 | __m256 m_y_g_f, m_y_b_f, m_y_r_f, m_u_g_f, m_u_b_f, m_u_r_f, m_v_g_f, m_v_b_f, m_v_r_f; | ||
| 649 | 50 | m_y_g_f = _mm256_mul_ps(_mm256_set1_ps(m.y_g_f), scale_f_avx2); | |
| 650 | 50 | m_y_b_f = _mm256_mul_ps(_mm256_set1_ps(m.y_b_f), scale_f_avx2); | |
| 651 | 50 | m_y_r_f = _mm256_mul_ps(_mm256_set1_ps(m.y_r_f), scale_f_avx2); | |
| 652 | if constexpr (direction != ConversionDirection::RGB_TO_Y) { | ||
| 653 | 30 | m_u_g_f = _mm256_mul_ps(_mm256_set1_ps(m.u_g_f), scale_f_avx2); | |
| 654 | 30 | m_u_b_f = _mm256_mul_ps(_mm256_set1_ps(m.u_b_f), scale_f_avx2); | |
| 655 | 30 | m_u_r_f = _mm256_mul_ps(_mm256_set1_ps(m.u_r_f), scale_f_avx2); | |
| 656 | 30 | m_v_g_f = _mm256_mul_ps(_mm256_set1_ps(m.v_g_f), scale_f_avx2); | |
| 657 | 30 | m_v_b_f = _mm256_mul_ps(_mm256_set1_ps(m.v_b_f), scale_f_avx2); | |
| 658 | 30 | m_v_r_f = _mm256_mul_ps(_mm256_set1_ps(m.v_r_f), scale_f_avx2); | |
| 659 | } | ||
| 660 | |||
| 661 | if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::RGB_TO_RGB) { | ||
| 662 | // RGB output: same offset for all channels | ||
| 663 | 5 | float rgb_out_offset_scaled = m.offset_out_f * scale_f; | |
| 664 | 5 | m_offset_out_y_or_g_f = _mm256_set1_ps(rgb_out_offset_scaled); | |
| 665 | 5 | m_offset_out_u_or_b_f = _mm256_set1_ps(rgb_out_offset_scaled); | |
| 666 | 5 | m_offset_out_v_or_r_f = _mm256_set1_ps(rgb_out_offset_scaled); | |
| 667 | } | ||
| 668 | else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::YUV_TO_YUV) { | ||
| 669 | |||
| 670 | // YUV output | ||
| 671 | 10 | float y_out_offset = m.offset_out_f; | |
| 672 | 10 | float y_out_offset_scaled = y_out_offset * scale_f; | |
| 673 | |||
| 674 | // U/V center offset - should NOT be scaled by scale_f! | ||
| 675 | // The matrix output is already in the target range, just add the center | ||
| 676 | 10 | float uv_center_offset = final_is_float ? 0.0f : (float)half_pixel_offset_target; | |
| 677 | |||
| 678 | 10 | m_offset_out_y_or_g_f = _mm256_set1_ps(y_out_offset_scaled); | |
| 679 | 10 | m_offset_out_u_or_b_f = _mm256_set1_ps(uv_center_offset); | |
| 680 | 10 | m_offset_out_v_or_r_f = _mm256_set1_ps(uv_center_offset); | |
| 681 | } | ||
| 682 | else if constexpr (direction == ConversionDirection::RGB_TO_Y) { | ||
| 683 | // no chroma output | ||
| 684 | 10 | float y_out_offset_scaled = m.offset_out_f * scale_f; | |
| 685 | 10 | m_offset_out_y_or_g_f = _mm256_set1_ps(y_out_offset_scaled); | |
| 686 | } | ||
| 687 | |||
| 688 | if constexpr (direction == ConversionDirection::YUV_TO_RGB) { | ||
| 689 | // YUV→RGB: outputs are RGB (rows G,B,R), inputs are YUV (columns Y,U,V) | ||
| 690 | // Out0=G, Out1=B, Out2=R | ||
| 691 | 5 | coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_u_g_f; coeff_out0_in2 = m_v_g_f; | |
| 692 | 5 | coeff_out1_in0 = m_y_b_f; coeff_out1_in1 = m_u_b_f; coeff_out1_in2 = m_v_b_f; | |
| 693 | 5 | coeff_out2_in0 = m_y_r_f; coeff_out2_in1 = m_u_r_f; coeff_out2_in2 = m_v_r_f; | |
| 694 | } | ||
| 695 | else if constexpr (direction == ConversionDirection::RGB_TO_YUV) { | ||
| 696 | // RGB→YUV: outputs are YUV (rows Y,U,V), inputs are RGB in memory order (G, B, R) | ||
| 697 | // Out0=Y, Out1=U, Out2=V | ||
| 698 | // Inputs: in0=G, in1=B, in2=R | ||
| 699 | // Y = y_r*R + y_g*G + y_b*B | ||
| 700 | // = y_g*in0 + y_b*in1 + y_r*in2 | ||
| 701 | 9 | coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_y_b_f; coeff_out0_in2 = m_y_r_f; | |
| 702 | |||
| 703 | // U = u_r*R + u_g*G + u_b*B | ||
| 704 | // = u_g*in0 + u_b*in1 + u_r*in2 | ||
| 705 | 9 | coeff_out1_in0 = m_u_g_f; coeff_out1_in1 = m_u_b_f; coeff_out1_in2 = m_u_r_f; | |
| 706 | |||
| 707 | // V = v_r*R + v_g*G + v_b*B | ||
| 708 | // = v_g*in0 + v_b*in1 + v_r*in2 | ||
| 709 | 9 | coeff_out2_in0 = m_v_g_f; coeff_out2_in1 = m_v_b_f; coeff_out2_in2 = m_v_r_f; | |
| 710 | } | ||
| 711 | else if constexpr (direction == ConversionDirection::RGB_TO_Y) { | ||
| 712 | // RGB→YUV: outputs are YUV (rows Y,U,V), inputs are RGB in memory order (G, B, R) | ||
| 713 | // Out0=Y, No chroma output | ||
| 714 | // Inputs: in0=G, in1=B, in2=R | ||
| 715 | // Y = y_r*R + y_g*G + y_b*B | ||
| 716 | // = y_g*in0 + y_b*in1 + y_r*in2 | ||
| 717 | 10 | coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_y_b_f; coeff_out0_in2 = m_y_r_f; | |
| 718 | } | ||
| 719 | else if constexpr (direction == ConversionDirection::YUV_TO_YUV) { | ||
| 720 | // YUV→YUV: outputs are YUV (rows Y,U,V), inputs are YUV (columns Y,U,V) | ||
| 721 | // For BT.601→BT.709 conversion, this is a fused matrix | ||
| 722 | // Out0=Y_out, Out1=U_out, Out2=V_out | ||
| 723 | 1 | coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_u_g_f; coeff_out0_in2 = m_v_g_f; | |
| 724 | 1 | coeff_out1_in0 = m_y_b_f; coeff_out1_in1 = m_u_b_f; coeff_out1_in2 = m_v_b_f; | |
| 725 | 1 | coeff_out2_in0 = m_y_r_f; coeff_out2_in1 = m_u_r_f; coeff_out2_in2 = m_v_r_f; | |
| 726 | } | ||
| 727 | else if constexpr (direction == ConversionDirection::RGB_TO_RGB) { // RGB_TO_RGB | ||
| 728 | // RGB→RGB: outputs are RGB (rows R,G,B), inputs are RGB (columns R,G,B) | ||
| 729 | // For gamut conversion or color correction | ||
| 730 | // Out0=G_out, Out1=B_out, Out2=R_out | ||
| 731 | coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_u_g_f; coeff_out0_in2 = m_v_g_f; | ||
| 732 | coeff_out1_in0 = m_y_b_f; coeff_out1_in1 = m_u_b_f; coeff_out1_in2 = m_v_b_f; | ||
| 733 | coeff_out2_in0 = m_y_r_f; coeff_out2_in1 = m_u_r_f; coeff_out2_in2 = m_v_r_f; | ||
| 734 | } | ||
| 735 | } | ||
| 736 | else { | ||
| 737 | // Integer workflow coefficient setup | ||
| 738 | int round_and_out_offset_y_or_g; | ||
| 739 | int round_and_out_offset_u_or_b; | ||
| 740 | int round_and_out_offset_v_or_r; | ||
| 741 | |||
| 742 | if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::RGB_TO_RGB) { | ||
| 743 | // output RGB: same offset for all channels | ||
| 744 | 13 | round_and_out_offset_y_or_g = round_mask_plus_offset_out_scaled_i; | |
| 745 | 13 | round_and_out_offset_u_or_b = round_mask_plus_offset_out_scaled_i; | |
| 746 | 13 | round_and_out_offset_v_or_r = round_mask_plus_offset_out_scaled_i; | |
| 747 | } | ||
| 748 | else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::YUV_TO_YUV) { | ||
| 749 | // output YUV: different offsets for Y vs U/V | ||
| 750 | 9 | round_and_out_offset_y_or_g = round_mask_plus_offset_out_scaled_i; | |
| 751 | 9 | round_and_out_offset_u_or_b = round_mask_plus_offset_out_chroma_scaled_i; | |
| 752 | 9 | round_and_out_offset_v_or_r = round_mask_plus_offset_out_chroma_scaled_i; | |
| 753 | } | ||
| 754 | else if constexpr (direction == ConversionDirection::RGB_TO_Y) { | ||
| 755 | // no chroma output | ||
| 756 | 5 | round_and_out_offset_y_or_g = round_mask_plus_offset_out_scaled_i; | |
| 757 | } | ||
| 758 | |||
| 759 | // Pack coefficients based on direction | ||
| 760 | // For MADD packing: [coeff_in1, coeff_in0] and [coeff_in2, round] | ||
| 761 | |||
| 762 | if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) { | ||
| 763 | // YUV→RGB: Out0=G, Out1=B, Out2=R | ||
| 764 | // YUV→YUV: Out0=Y, Out1=U, Out2=V | ||
| 765 | // G = y_g*Y + u_g*U + v_g*V | ||
| 766 | // Inputs are: in0=Y, in1=U, in2=V | ||
| 767 | 16 | m_uy_G = _mm256_set1_epi32((static_cast<uint16_t>(m.y_g) << 16) | static_cast<uint16_t>(m.u_g)); | |
| 768 | 16 | m_vr_G = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_y_or_g) << 16) | static_cast<uint16_t>(m.v_g)); | |
| 769 | |||
| 770 | // B = y_b*Y + u_b*U + v_b*V | ||
| 771 | 16 | m_uy_B = _mm256_set1_epi32((static_cast<uint16_t>(m.y_b) << 16) | static_cast<uint16_t>(m.u_b)); | |
| 772 | 16 | m_vr_B = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_u_or_b) << 16) | static_cast<uint16_t>(m.v_b)); | |
| 773 | |||
| 774 | // R = y_r*Y + u_r*U + v_r*V | ||
| 775 | 16 | m_uy_R = _mm256_set1_epi32((static_cast<uint16_t>(m.y_r) << 16) | static_cast<uint16_t>(m.u_r)); | |
| 776 | 16 | m_vr_R = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_v_or_r) << 16) | static_cast<uint16_t>(m.v_r)); | |
| 777 | } | ||
| 778 | else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_RGB) { | ||
| 779 | // RGB→YUV: Out0=Y, Out1=U, Out2=V | ||
| 780 | // RGB→RGB: Out0=G, Out1=B, Out2=R | ||
| 781 | // Inputs are: in0=G, in1=B, in2=R | ||
| 782 | |||
| 783 | // Y = y_r*R + y_g*G + y_b*B | ||
| 784 | // = y_g*in0 + y_b*in1 + y_r*in2 | ||
| 785 | 6 | m_uy_G = _mm256_set1_epi32((static_cast<uint16_t>(m.y_g) << 16) | static_cast<uint16_t>(m.y_b)); | |
| 786 | 6 | m_vr_G = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_y_or_g) << 16) | static_cast<uint16_t>(m.y_r)); | |
| 787 | |||
| 788 | // U = u_r*R + u_g*G + u_b*B | ||
| 789 | // = u_g*in0 + u_b*in1 + u_r*in2 | ||
| 790 | 6 | m_uy_B = _mm256_set1_epi32((static_cast<uint16_t>(m.u_g) << 16) | static_cast<uint16_t>(m.u_b)); | |
| 791 | 6 | m_vr_B = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_u_or_b) << 16) | static_cast<uint16_t>(m.u_r)); | |
| 792 | |||
| 793 | // V = v_r*R + v_g*G + v_b*B | ||
| 794 | // = v_g*in0 + v_b*in1 + v_r*in2 | ||
| 795 | 6 | m_uy_R = _mm256_set1_epi32((static_cast<uint16_t>(m.v_g) << 16) | static_cast<uint16_t>(m.v_b)); | |
| 796 | 6 | m_vr_R = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_v_or_r) << 16) | static_cast<uint16_t>(m.v_r)); | |
| 797 | } | ||
| 798 | else if constexpr (direction == ConversionDirection::RGB_TO_Y) { | ||
| 799 | // RGB→Y: Out0=Y, No chroma output | ||
| 800 | // Inputs are: in0=G, in1=B, in2=R | ||
| 801 | // Y = y_r*R + y_g*G + y_b*B | ||
| 802 | // = y_g*in0 + y_b*in1 + y_r*in2 | ||
| 803 | 5 | m_uy_G = _mm256_set1_epi32((static_cast<uint16_t>(m.y_g) << 16) | static_cast<uint16_t>(m.y_b)); | |
| 804 | 5 | m_vr_G = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_y_or_g) << 16) | static_cast<uint16_t>(m.y_r)); | |
| 805 | } | ||
| 806 | } | ||
| 807 | |||
| 808 | 52 | const int rowsize = width * sizeof(pixel_t); | |
| 809 | 52 | const int rowsize_aligned = AlignNumber(rowsize, FRAME_ALIGN); // 64 | |
| 810 |
46/320void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 171 → 125 taken 12 times.
✓ Branch 171 → 172 taken 4 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 171 → 125 not taken.
✗ Branch 171 → 172 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 171 → 125 not taken.
✗ Branch 171 → 172 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 171 → 125 not taken.
✗ Branch 171 → 172 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 180 → 125 not taken.
✗ Branch 180 → 181 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 149 → 96 not taken.
✗ Branch 149 → 150 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 180 → 125 not taken.
✗ Branch 180 → 181 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 150 → 97 not taken.
✗ Branch 150 → 151 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 180 → 125 not taken.
✗ Branch 180 → 181 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned char, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 150 → 97 taken 36 times.
✓ Branch 150 → 151 taken 8 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 180 → 125 not taken.
✗ Branch 180 → 181 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 150 → 97 not taken.
✗ Branch 150 → 151 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 180 → 125 not taken.
✗ Branch 180 → 181 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 180 → 125 not taken.
✗ Branch 180 → 181 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 150 → 97 not taken.
✗ Branch 150 → 151 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 180 → 125 taken 3 times.
✓ Branch 180 → 181 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 145 → 98 not taken.
✗ Branch 145 → 146 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 146 → 99 taken 11 times.
✓ Branch 146 → 147 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 146 → 99 not taken.
✗ Branch 146 → 147 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 146 → 99 not taken.
✗ Branch 146 → 147 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 146 → 99 not taken.
✗ Branch 146 → 147 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 143 → 96 not taken.
✗ Branch 143 → 144 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 97 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 97 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 144 → 97 taken 10 times.
✓ Branch 144 → 145 taken 2 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 97 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 187 → 125 taken 11 times.
✓ Branch 187 → 188 taken 4 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 187 → 125 not taken.
✗ Branch 187 → 188 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 187 → 125 not taken.
✗ Branch 187 → 188 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 187 → 125 not taken.
✗ Branch 187 → 188 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 224 → 125 not taken.
✗ Branch 224 → 225 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 149 → 96 not taken.
✗ Branch 149 → 150 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 224 → 125 not taken.
✗ Branch 224 → 225 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 150 → 97 not taken.
✗ Branch 150 → 151 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 224 → 125 not taken.
✗ Branch 224 → 225 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned char, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 150 → 97 taken 23 times.
✓ Branch 150 → 151 taken 5 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 224 → 125 not taken.
✗ Branch 224 → 225 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 150 → 97 not taken.
✗ Branch 150 → 151 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 224 → 125 not taken.
✗ Branch 224 → 225 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 224 → 125 taken 6 times.
✓ Branch 224 → 225 taken 2 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 150 → 97 not taken.
✗ Branch 150 → 151 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 224 → 125 not taken.
✗ Branch 224 → 225 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 145 → 98 not taken.
✗ Branch 145 → 146 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 218 → 125 taken 13 times.
✓ Branch 218 → 219 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 143 → 96 not taken.
✗ Branch 143 → 144 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 97 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 97 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 144 → 97 taken 5 times.
✓ Branch 144 → 145 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 97 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 218 → 125 not taken.
✗ Branch 218 → 219 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 171 → 125 taken 3 times.
✓ Branch 171 → 172 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 171 → 125 not taken.
✗ Branch 171 → 172 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 171 → 125 not taken.
✗ Branch 171 → 172 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 171 → 125 not taken.
✗ Branch 171 → 172 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 180 → 125 not taken.
✗ Branch 180 → 181 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 149 → 96 not taken.
✗ Branch 149 → 150 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 180 → 125 not taken.
✗ Branch 180 → 181 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 150 → 97 not taken.
✗ Branch 150 → 151 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 180 → 125 not taken.
✗ Branch 180 → 181 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned char, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 150 → 97 taken 3 times.
✓ Branch 150 → 151 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 180 → 125 not taken.
✗ Branch 180 → 181 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 150 → 97 not taken.
✗ Branch 150 → 151 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 180 → 125 not taken.
✗ Branch 180 → 181 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 180 → 125 not taken.
✗ Branch 180 → 181 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 150 → 97 not taken.
✗ Branch 150 → 151 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 180 → 125 not taken.
✗ Branch 180 → 181 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 145 → 98 not taken.
✗ Branch 145 → 146 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 146 → 99 taken 6 times.
✓ Branch 146 → 147 taken 2 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 146 → 99 not taken.
✗ Branch 146 → 147 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 146 → 99 not taken.
✗ Branch 146 → 147 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 146 → 99 not taken.
✗ Branch 146 → 147 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 143 → 96 not taken.
✗ Branch 143 → 144 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 97 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 97 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 97 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 97 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 174 → 125 not taken.
✗ Branch 174 → 175 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 157 → 97 taken 9 times.
✓ Branch 157 → 158 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 157 → 97 not taken.
✗ Branch 157 → 158 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 157 → 97 not taken.
✗ Branch 157 → 158 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 157 → 97 not taken.
✗ Branch 157 → 158 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 194 → 97 not taken.
✗ Branch 194 → 195 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 139 → 88 not taken.
✗ Branch 139 → 140 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 194 → 97 not taken.
✗ Branch 194 → 195 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 140 → 89 not taken.
✗ Branch 140 → 141 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 194 → 97 not taken.
✗ Branch 194 → 195 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned char, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 140 → 89 taken 6 times.
✓ Branch 140 → 141 taken 2 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 194 → 97 taken 3 times.
✓ Branch 194 → 195 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 140 → 89 not taken.
✗ Branch 140 → 141 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 194 → 97 not taken.
✗ Branch 194 → 195 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 194 → 97 taken 3 times.
✓ Branch 194 → 195 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 140 → 89 not taken.
✗ Branch 140 → 141 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 194 → 97 taken 3 times.
✓ Branch 194 → 195 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 131 → 86 not taken.
✗ Branch 131 → 132 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 188 → 97 taken 3 times.
✓ Branch 188 → 189 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 188 → 97 taken 6 times.
✓ Branch 188 → 189 taken 2 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 133 → 88 not taken.
✗ Branch 133 → 134 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 134 → 89 taken 6 times.
✓ Branch 134 → 135 taken 2 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 134 → 89 not taken.
✗ Branch 134 → 135 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 134 → 89 taken 3 times.
✓ Branch 134 → 135 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 188 → 97 taken 3 times.
✓ Branch 188 → 189 taken 1 time.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 134 → 89 not taken.
✗ Branch 134 → 135 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 188 → 97 not taken.
✗ Branch 188 → 189 not taken.
|
239 | for (int yy = 0; yy < height; yy++) { |
| 811 | // 32 pixels per loop: 32 * 8 bit = 32 bytes; 32 * 16 bit = 64 bytes | ||
| 812 | // Note: extra care needed for 32-bit float input or output, since 32xfloat is over | ||
| 813 | // Avisynth+ guaranteed scanline alignment (64 bytes) | ||
| 814 | // Ideally, we have to separate the processing into 32 pixel then 16 pixel chunks. | ||
| 815 | // See ConvertBits to float AVX2 version for reference. | ||
| 816 | // Actually, we only check a pre-calculated limit inside the loop, before the storage. (FIXME) | ||
| 817 | // But I guess, when processing so many pixels at once, it's not that big penalty. | ||
| 818 | // However duplicating the loop body seen below for the two float-problematic cases, that _is_ penalty :) | ||
| 819 | |||
| 820 |
46/320void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 169 → 126 taken 12 times.
✓ Branch 169 → 170 taken 12 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 169 → 126 not taken.
✗ Branch 169 → 170 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 169 → 126 not taken.
✗ Branch 169 → 170 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 169 → 126 not taken.
✗ Branch 169 → 170 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 178 → 126 not taken.
✗ Branch 178 → 179 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 147 → 97 not taken.
✗ Branch 147 → 148 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 178 → 126 not taken.
✗ Branch 178 → 179 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 148 → 98 not taken.
✗ Branch 148 → 149 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 178 → 126 not taken.
✗ Branch 178 → 179 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned char, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 148 → 98 taken 36 times.
✓ Branch 148 → 149 taken 36 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 178 → 126 not taken.
✗ Branch 178 → 179 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 148 → 98 not taken.
✗ Branch 148 → 149 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 178 → 126 not taken.
✗ Branch 178 → 179 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 178 → 126 not taken.
✗ Branch 178 → 179 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 148 → 98 not taken.
✗ Branch 148 → 149 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned char, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 178 → 126 taken 3 times.
✓ Branch 178 → 179 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 143 → 99 not taken.
✗ Branch 143 → 144 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 144 → 100 taken 11 times.
✓ Branch 144 → 145 taken 11 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 100 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 100 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 100 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, false, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 141 → 97 not taken.
✗ Branch 141 → 142 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 142 → 98 not taken.
✗ Branch 142 → 143 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 142 → 98 not taken.
✗ Branch 142 → 143 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 142 → 98 taken 10 times.
✓ Branch 142 → 143 taken 10 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 142 → 98 not taken.
✗ Branch 142 → 143 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, unsigned short, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 185 → 126 taken 11 times.
✓ Branch 185 → 186 taken 11 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 185 → 126 not taken.
✗ Branch 185 → 186 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 185 → 126 not taken.
✗ Branch 185 → 186 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 185 → 126 not taken.
✗ Branch 185 → 186 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 222 → 126 not taken.
✗ Branch 222 → 223 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 147 → 97 not taken.
✗ Branch 147 → 148 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 222 → 126 not taken.
✗ Branch 222 → 223 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 148 → 98 not taken.
✗ Branch 148 → 149 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 222 → 126 not taken.
✗ Branch 222 → 223 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned char, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 148 → 98 taken 28 times.
✓ Branch 148 → 149 taken 23 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 222 → 126 not taken.
✗ Branch 222 → 223 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 148 → 98 not taken.
✗ Branch 148 → 149 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 222 → 126 not taken.
✗ Branch 222 → 223 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 222 → 126 taken 6 times.
✓ Branch 222 → 223 taken 6 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 148 → 98 not taken.
✗ Branch 148 → 149 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned char, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 222 → 126 not taken.
✗ Branch 222 → 223 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 143 → 99 not taken.
✗ Branch 143 → 144 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 216 → 126 taken 13 times.
✓ Branch 216 → 217 taken 13 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, false, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 141 → 97 not taken.
✗ Branch 141 → 142 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 142 → 98 not taken.
✗ Branch 142 → 143 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 142 → 98 not taken.
✗ Branch 142 → 143 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 142 → 98 taken 5 times.
✓ Branch 142 → 143 taken 5 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 142 → 98 not taken.
✗ Branch 142 → 143 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, unsigned short, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 216 → 126 not taken.
✗ Branch 216 → 217 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 169 → 126 taken 3 times.
✓ Branch 169 → 170 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 169 → 126 not taken.
✗ Branch 169 → 170 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 169 → 126 not taken.
✗ Branch 169 → 170 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 169 → 126 not taken.
✗ Branch 169 → 170 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 178 → 126 not taken.
✗ Branch 178 → 179 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 147 → 97 not taken.
✗ Branch 147 → 148 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 178 → 126 not taken.
✗ Branch 178 → 179 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 148 → 98 not taken.
✗ Branch 148 → 149 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 178 → 126 not taken.
✗ Branch 178 → 179 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned char, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 148 → 98 taken 3 times.
✓ Branch 148 → 149 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 178 → 126 not taken.
✗ Branch 178 → 179 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 148 → 98 not taken.
✗ Branch 148 → 149 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 178 → 126 not taken.
✗ Branch 178 → 179 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 178 → 126 not taken.
✗ Branch 178 → 179 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 148 → 98 not taken.
✗ Branch 148 → 149 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned char, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 178 → 126 not taken.
✗ Branch 178 → 179 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 143 → 99 not taken.
✗ Branch 143 → 144 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 144 → 100 taken 6 times.
✓ Branch 144 → 145 taken 6 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 100 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 100 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 144 → 100 not taken.
✗ Branch 144 → 145 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, false, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 141 → 97 not taken.
✗ Branch 141 → 142 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 142 → 98 not taken.
✗ Branch 142 → 143 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 142 → 98 not taken.
✗ Branch 142 → 143 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 142 → 98 not taken.
✗ Branch 142 → 143 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 142 → 98 not taken.
✗ Branch 142 → 143 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, unsigned short, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 172 → 126 not taken.
✗ Branch 172 → 173 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 155 → 98 taken 9 times.
✓ Branch 155 → 156 taken 9 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 155 → 98 not taken.
✗ Branch 155 → 156 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 155 → 98 not taken.
✗ Branch 155 → 156 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 155 → 98 not taken.
✗ Branch 155 → 156 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 192 → 98 not taken.
✗ Branch 192 → 193 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 137 → 89 not taken.
✗ Branch 137 → 138 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 192 → 98 not taken.
✗ Branch 192 → 193 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 138 → 90 not taken.
✗ Branch 138 → 139 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 192 → 98 not taken.
✗ Branch 192 → 193 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned char, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 138 → 90 taken 6 times.
✓ Branch 138 → 139 taken 6 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 192 → 98 taken 3 times.
✓ Branch 192 → 193 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 138 → 90 not taken.
✗ Branch 138 → 139 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 192 → 98 not taken.
✗ Branch 192 → 193 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 192 → 98 taken 3 times.
✓ Branch 192 → 193 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 138 → 90 not taken.
✗ Branch 138 → 139 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned char, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 192 → 98 taken 3 times.
✓ Branch 192 → 193 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 129 → 87 not taken.
✗ Branch 129 → 130 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 186 → 98 taken 3 times.
✓ Branch 186 → 187 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 186 → 98 taken 6 times.
✓ Branch 186 → 187 taken 6 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, false, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, float, (YuvRgbConversionType)2>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 131 → 89 not taken.
✗ Branch 131 → 132 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 132 → 90 taken 6 times.
✓ Branch 132 → 133 taken 6 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, false, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned char, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 132 → 90 not taken.
✗ Branch 132 → 133 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned char, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned short, (YuvRgbConversionType)0>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 132 → 90 taken 3 times.
✓ Branch 132 → 133 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 186 → 98 taken 3 times.
✓ Branch 186 → 187 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned short, (YuvRgbConversionType)3>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 132 → 90 not taken.
✗ Branch 132 → 133 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, unsigned short, true, true, unsigned short, (YuvRgbConversionType)4>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 186 → 98 not taken.
✗ Branch 186 → 187 not taken.
|
379 | for (int x = 0; x < rowsize; x += 32 * sizeof(pixel_t)) { |
| 821 | |||
| 822 | // ConversionDirection::YUV_TO_RGB: y, u, v | ||
| 823 | // ConversionDirection::RGB_TO_YUV: g, b, r | ||
| 824 | |||
| 825 | // Regardless of the YUV/RGB source, we ise in0_1, in1_1, in2_1 for the first 16 pixels, and in0_2, in1_2, in2_2 for the second 16 pixels | ||
| 826 | // Layout for 0-1-2: Y-U-V or G-B-R | ||
| 827 | |||
| 828 | // integer input pixels | ||
| 829 | __m256i in0_1, in1_1, in2_1; | ||
| 830 | __m256i in0_2, in1_2, in2_2; | ||
| 831 | // float workflow | ||
| 832 | __m256 in0_1_f_lo, in0_1_f_hi, in0_2_f_lo, in0_2_f_hi; | ||
| 833 | __m256 in1_1_f_lo, in1_1_f_hi, in1_2_f_lo, in1_2_f_hi; | ||
| 834 | __m256 in2_1_f_lo, in2_1_f_hi, in2_2_f_lo, in2_2_f_hi; | ||
| 835 | |||
| 836 | // Avisynth FRAME_ALIGN == 64, so when final_is_float, we cannot process 32 pixels at once at the end of the line | ||
| 837 | // Can I write all 32 pixels (blockA+B+C+D)? | ||
| 838 | // yes: write all 4 blocks (blockA, B, C, D) | ||
| 839 | // no : Write only first 2 blocks (blockA, B), 16 floats are guaranteed safe due to 64-byte alignment | ||
| 840 | bool safe_last_16float_64bytes; | ||
| 841 | if constexpr (final_is_float || sizeof(pixel_t) == 4) | ||
| 842 | 35 | safe_last_16float_64bytes = (x + 32 * (int)sizeof(pixel_t)) <= rowsize_aligned; | |
| 843 | else | ||
| 844 | 157 | safe_last_16float_64bytes = false; | |
| 845 | |||
| 846 | // Note on widening strategy (Y, U, V) for the float internal path, where series of widenings are required: | ||
| 847 | // | ||
| 848 | // We use unpacklo/hi_epi16 for widening Y, U and V from (uint8 to) (u)int16 to int32, | ||
| 849 | // rather than _mm256_extracti128_si256 + (cvtepu8_epi16) + cvtepi16_epi32/cvtepu16_epi32. | ||
| 850 | // For U and V, an additional srai_epi16 generates the sign fill word needed | ||
| 851 | // for correct sign extension of the centered (negative-capable) chroma values. | ||
| 852 | // | ||
| 853 | // Although the extract+cvt approach would produce a sequential lane layout | ||
| 854 | // that avoids the permute2f128 shuffles before the final float store, it is | ||
| 855 | // measurably slower (Possibly port contention). | ||
| 856 | |||
| 857 | // Load pixels, for the integer path, we pivot for exact 16 bit Y later | ||
| 858 | if constexpr (sizeof(pixel_t) == 1) { | ||
| 859 | // Load 32 bytes (32 pixels), unpack to two 16-bit registers | ||
| 860 | 91 | __m256i in0_raw = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[0] + x)); // 0..7 8..15 16..23 24..31 Y or G | |
| 861 | 182 | __m256i in1_raw = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[1] + x)); // U or B | |
| 862 | 164 | __m256i in2_raw = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[2] + x)); // V or R | |
| 863 | |||
| 864 | if constexpr (sizeof(pixel_t_dst) == 2) { | ||
| 865 | // 8->16 bit: pre-shuffle to avoid permutes at the end | ||
| 866 | 15 | in0_raw = _mm256_permute4x64_epi64(in0_raw, 0xD8); // (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6) | |
| 867 | // 0..7, 16..23, 8..15, 24..31 | ||
| 868 | 15 | in1_raw = _mm256_permute4x64_epi64(in1_raw, 0xD8); | |
| 869 | 15 | in2_raw = _mm256_permute4x64_epi64(in2_raw, 0xD8); | |
| 870 | } | ||
| 871 | 182 | in0_1 = _mm256_unpacklo_epi8(in0_raw, zero); in0_2 = _mm256_unpackhi_epi8(in0_raw, zero); | |
| 872 | // in0_1: 0..7, 8..15, in0_2: 16..23, 24..31 | ||
| 873 | 182 | in1_1 = _mm256_unpacklo_epi8(in1_raw, zero); in1_2 = _mm256_unpackhi_epi8(in1_raw, zero); | |
| 874 | 182 | in2_1 = _mm256_unpacklo_epi8(in2_raw, zero); in2_2 = _mm256_unpackhi_epi8(in2_raw, zero); | |
| 875 | } | ||
| 876 | else if constexpr (sizeof(pixel_t) == 2) { | ||
| 877 | // Load 64 bytes (32 pixels) | ||
| 878 | 66 | in0_1 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[0] + x)); | |
| 879 | 66 | in1_1 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[1] + x)); | |
| 880 | 66 | in2_1 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[2] + x)); | |
| 881 | 66 | in0_2 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[0] + x + 32)); | |
| 882 | 66 | in1_2 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[1] + x + 32)); | |
| 883 | 107 | in2_2 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[2] + x + 32)); | |
| 884 | } | ||
| 885 | else { // if constexpr (sizeof(pixel_t) == 4) { | ||
| 886 | // this also implies full float workflow | ||
| 887 | // Load 128 bytes (32 pixels) // safety! we are well beyond Avisynth's 64 byte alignment | ||
| 888 | 35 | in0_1_f_lo = _mm256_load_ps(reinterpret_cast<const float*>(srcp[0] + x)); | |
| 889 | 35 | in0_1_f_hi = _mm256_load_ps(reinterpret_cast<const float*>(srcp[0] + x + 32)); | |
| 890 | 35 | in1_1_f_lo = _mm256_load_ps(reinterpret_cast<const float*>(srcp[1] + x)); | |
| 891 | 35 | in1_1_f_hi = _mm256_load_ps(reinterpret_cast<const float*>(srcp[1] + x + 32)); | |
| 892 | 35 | in2_1_f_lo = _mm256_load_ps(reinterpret_cast<const float*>(srcp[2] + x)); | |
| 893 | 35 | in2_1_f_hi = _mm256_load_ps(reinterpret_cast<const float*>(srcp[2] + x + 32)); | |
| 894 |
6/32void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 138 → 139 taken 5 times.
✓ Branch 138 → 152 taken 7 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 138 → 139 not taken.
✗ Branch 138 → 152 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 138 → 139 not taken.
✗ Branch 138 → 152 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)0, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 138 → 139 not taken.
✗ Branch 138 → 152 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 138 → 139 taken 5 times.
✓ Branch 138 → 152 taken 6 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 138 → 139 not taken.
✗ Branch 138 → 152 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 138 → 139 not taken.
✗ Branch 138 → 152 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)1, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 138 → 139 not taken.
✗ Branch 138 → 152 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 138 → 139 not taken.
✓ Branch 138 → 152 taken 3 times.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 138 → 139 not taken.
✗ Branch 138 → 152 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 138 → 139 not taken.
✗ Branch 138 → 152 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)2, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 138 → 139 not taken.
✗ Branch 138 → 152 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, false, float, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✓ Branch 110 → 111 taken 9 times.
✗ Branch 110 → 124 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, false, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 110 → 111 not taken.
✗ Branch 110 → 124 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, true, unsigned char, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 110 → 111 not taken.
✗ Branch 110 → 124 not taken.
void convert_yuv_to_planarrgb_avx2_internal<(ConversionDirection)4, float, false, true, unsigned short, (YuvRgbConversionType)1>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int):
✗ Branch 110 → 111 not taken.
✗ Branch 110 → 124 not taken.
|
35 | if (safe_last_16float_64bytes) { |
| 895 | 19 | in0_2_f_lo = _mm256_load_ps(reinterpret_cast<const float*>(srcp[0] + x + 64)); | |
| 896 | 19 | in0_2_f_hi = _mm256_load_ps(reinterpret_cast<const float*>(srcp[0] + x + 96)); | |
| 897 | 19 | in1_2_f_lo = _mm256_load_ps(reinterpret_cast<const float*>(srcp[1] + x + 64)); | |
| 898 | 19 | in1_2_f_hi = _mm256_load_ps(reinterpret_cast<const float*>(srcp[1] + x + 96)); | |
| 899 | 19 | in2_2_f_lo = _mm256_load_ps(reinterpret_cast<const float*>(srcp[2] + x + 64)); | |
| 900 | 38 | in2_2_f_hi = _mm256_load_ps(reinterpret_cast<const float*>(srcp[2] + x + 96)); | |
| 901 | } | ||
| 902 | else { | ||
| 903 | // fill them with something to silence the warning, they won't be stored, either. | ||
| 904 | 16 | in0_2_f_lo = in0_2_f_hi = in1_2_f_lo = in1_2_f_hi = in2_2_f_lo = in2_2_f_hi = _mm256_setzero_ps(); | |
| 905 | } | ||
| 906 | } | ||
| 907 | |||
| 908 | if constexpr (float_matrix_workflow) { | ||
| 909 | // complete float workflow, even for integer targets, do matrixes in float math. | ||
| 910 | // Also for maximum accuracy. | ||
| 911 | |||
| 912 | // convert integer pixels to float, only for non-float input | ||
| 913 | if constexpr (sizeof(pixel_t) == 4) { | ||
| 914 | // even float input can be "limited" in Avisynth, correct with offset_in as well | ||
| 915 | // YUV chroma is zero centered, no offset correction needed | ||
| 916 | if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) { | ||
| 917 | // YUV Source | ||
| 918 | // Y | ||
| 919 | 15 | in0_1_f_lo = _mm256_add_ps(in0_1_f_lo, offset_in_f); | |
| 920 | 15 | in0_1_f_hi = _mm256_add_ps(in0_1_f_hi, offset_in_f); | |
| 921 | 15 | in0_2_f_lo = _mm256_add_ps(in0_2_f_lo, offset_in_f); | |
| 922 | 15 | in0_2_f_hi = _mm256_add_ps(in0_2_f_hi, offset_in_f); | |
| 923 | } | ||
| 924 | else { | ||
| 925 | // RGB source: all channels need offset_in adjustments if studio RGB RGB_TO_RGB, RGB_TO_YUV, RGB_TO_Y | ||
| 926 | 20 | in0_1_f_lo = _mm256_add_ps(in0_1_f_lo, offset_in_f); | |
| 927 | 20 | in0_1_f_hi = _mm256_add_ps(in0_1_f_hi, offset_in_f); | |
| 928 | 20 | in0_2_f_lo = _mm256_add_ps(in0_2_f_lo, offset_in_f); | |
| 929 | 20 | in0_2_f_hi = _mm256_add_ps(in0_2_f_hi, offset_in_f); | |
| 930 | 20 | in1_1_f_lo = _mm256_add_ps(in1_1_f_lo, offset_in_f); | |
| 931 | 20 | in1_1_f_hi = _mm256_add_ps(in1_1_f_hi, offset_in_f); | |
| 932 | 20 | in1_2_f_lo = _mm256_add_ps(in1_2_f_lo, offset_in_f); | |
| 933 | 20 | in1_2_f_hi = _mm256_add_ps(in1_2_f_hi, offset_in_f); | |
| 934 | 20 | in2_1_f_lo = _mm256_add_ps(in2_1_f_lo, offset_in_f); | |
| 935 | 20 | in2_1_f_hi = _mm256_add_ps(in2_1_f_hi, offset_in_f); | |
| 936 | 20 | in2_2_f_lo = _mm256_add_ps(in2_2_f_lo, offset_in_f); | |
| 937 | 20 | in2_2_f_hi = _mm256_add_ps(in2_2_f_hi, offset_in_f); | |
| 938 | } | ||
| 939 | |||
| 940 | } | ||
| 941 | else { | ||
| 942 | // integer input | ||
| 943 | |||
| 944 | // Order: move to int32, and only then adjust offset_in. | ||
| 945 | // Superblacks would yield negative values that can only be sign-extend to int32 | ||
| 946 | // with excessive operations, see the U and V workaround. | ||
| 947 | |||
| 948 | // We've already put the input offset_in into each int32. We use add, offset_in is stored as negative. | ||
| 949 | |||
| 950 | // int32->float | ||
| 951 | |||
| 952 | if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) { | ||
| 953 | // YUV Source | ||
| 954 | // Y | ||
| 955 | 9 | in0_1_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in0_1, zero), offset_in)); | |
| 956 | 9 | in0_1_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in0_1, zero), offset_in)); | |
| 957 | 9 | in0_2_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in0_2, zero), offset_in)); | |
| 958 | 9 | in0_2_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in0_2, zero), offset_in)); | |
| 959 | |||
| 960 | // UV to sign extend | ||
| 961 | // Though from SSE4.1 we could use _mm_cvtepi16_epi32 directly but it makes packus lane | ||
| 962 | // crossing correction difficult (and slow). Mayne from avx512 _mm512_cvtepi16_ps (only signed 16 exists)? | ||
| 963 | |||
| 964 | // No lane keeping cvtepi16_epi32 here either. | ||
| 965 | // U,V, make signed, then int16->int32 | ||
| 966 | |||
| 967 | // sign-extend int16 chroma to int32, then convert to float | ||
| 968 | // using unpacklo/hi to preserve lane layout compatible with downstream packus | ||
| 969 | 27 | auto chroma_to_float = [&](__m256i c, __m256& f_lo, __m256& f_hi) { | |
| 970 | 24 | c = _mm256_sub_epi16(c, half); | |
| 971 | 12 | __m256i sign = _mm256_srai_epi16(c, 15); // 0xFFFF if negative, 0x0000 if positive | |
| 972 | 24 | f_lo = _mm256_cvtepi32_ps(_mm256_unpacklo_epi16(c, sign)); | |
| 973 | 12 | f_hi = _mm256_cvtepi32_ps(_mm256_unpackhi_epi16(c, sign)); | |
| 974 | }; | ||
| 975 | |||
| 976 | 3 | chroma_to_float(in1_1, in1_1_f_lo, in1_1_f_hi); // U1 | |
| 977 | 3 | chroma_to_float(in2_1, in2_1_f_lo, in2_1_f_hi); // V1 | |
| 978 | 3 | chroma_to_float(in1_2, in1_2_f_lo, in1_2_f_hi); // U2 | |
| 979 | 3 | chroma_to_float(in2_2, in2_2_f_lo, in2_2_f_hi); // V2 | |
| 980 | } | ||
| 981 | else { | ||
| 982 | // RGB source: only offset_in adjustment, no centering needed | ||
| 983 | // Green | ||
| 984 | 120 | in0_1_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in0_1, zero), offset_in)); | |
| 985 | 120 | in0_1_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in0_1, zero), offset_in)); | |
| 986 | 120 | in0_2_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in0_2, zero), offset_in)); | |
| 987 | 120 | in0_2_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in0_2, zero), offset_in)); | |
| 988 | // Blue | ||
| 989 | 120 | in1_1_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in1_1, zero), offset_in)); | |
| 990 | 120 | in1_1_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in1_1, zero), offset_in)); | |
| 991 | 120 | in1_2_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in1_2, zero), offset_in)); | |
| 992 | 120 | in1_2_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in1_2, zero), offset_in)); | |
| 993 | // Red | ||
| 994 | 120 | in2_1_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in2_1, zero), offset_in)); | |
| 995 | 120 | in2_1_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in2_1, zero), offset_in)); | |
| 996 | 120 | in2_2_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in2_2, zero), offset_in)); | |
| 997 | 120 | in2_2_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in2_2, zero), offset_in)); | |
| 998 | } | ||
| 999 | } // end of integer to float conversion and offset_in adjustment | ||
| 1000 | |||
| 1001 | // COMMON matrix multiply code - works for all 4 directions! | ||
| 1002 | |||
| 1003 | 390 | auto matrix_multiply = [&]( | |
| 1004 | __m256 in0_lo, __m256 in0_hi, | ||
| 1005 | __m256 in1_lo, __m256 in1_hi, | ||
| 1006 | __m256 in2_lo, __m256 in2_hi, | ||
| 1007 | __m256& out0_lo, __m256& out0_hi, | ||
| 1008 | __m256& out1_lo, __m256& out1_hi, | ||
| 1009 | __m256& out2_lo, __m256& out2_hi) | ||
| 1010 | { | ||
| 1011 | XP_LAMBDA_CAPTURE_FIX(coeff_out0_in0); | ||
| 1012 | XP_LAMBDA_CAPTURE_FIX(coeff_out0_in1); | ||
| 1013 | XP_LAMBDA_CAPTURE_FIX(coeff_out0_in2); | ||
| 1014 | XP_LAMBDA_CAPTURE_FIX(coeff_out1_in0); | ||
| 1015 | XP_LAMBDA_CAPTURE_FIX(coeff_out1_in1); | ||
| 1016 | XP_LAMBDA_CAPTURE_FIX(coeff_out1_in2); | ||
| 1017 | XP_LAMBDA_CAPTURE_FIX(coeff_out2_in0); | ||
| 1018 | XP_LAMBDA_CAPTURE_FIX(coeff_out2_in1); | ||
| 1019 | XP_LAMBDA_CAPTURE_FIX(coeff_out2_in2); | ||
| 1020 | XP_LAMBDA_CAPTURE_FIX(m_offset_out_y_or_g_f); | ||
| 1021 | XP_LAMBDA_CAPTURE_FIX(m_offset_out_u_or_b_f); | ||
| 1022 | XP_LAMBDA_CAPTURE_FIX(m_offset_out_v_or_r_f); | ||
| 1023 | |||
| 1024 | 468 | out0_lo = _mm256_fmadd_ps(coeff_out0_in2, in2_lo, _mm256_fmadd_ps(coeff_out0_in1, in1_lo, _mm256_fmadd_ps(coeff_out0_in0, in0_lo, m_offset_out_y_or_g_f))); | |
| 1025 | 468 | out0_hi = _mm256_fmadd_ps(coeff_out0_in2, in2_hi, _mm256_fmadd_ps(coeff_out0_in1, in1_hi, _mm256_fmadd_ps(coeff_out0_in0, in0_hi, m_offset_out_y_or_g_f))); | |
| 1026 | |||
| 1027 | if constexpr (direction != ConversionDirection::RGB_TO_Y) { | ||
| 1028 | |||
| 1029 | 288 | out1_lo = _mm256_fmadd_ps(coeff_out1_in2, in2_lo, _mm256_fmadd_ps(coeff_out1_in1, in1_lo, _mm256_fmadd_ps(coeff_out1_in0, in0_lo, m_offset_out_u_or_b_f))); | |
| 1030 | 288 | out1_hi = _mm256_fmadd_ps(coeff_out1_in2, in2_hi, _mm256_fmadd_ps(coeff_out1_in1, in1_hi, _mm256_fmadd_ps(coeff_out1_in0, in0_hi, m_offset_out_u_or_b_f))); | |
| 1031 | |||
| 1032 | 288 | out2_lo = _mm256_fmadd_ps(coeff_out2_in2, in2_lo, _mm256_fmadd_ps(coeff_out2_in1, in1_lo, _mm256_fmadd_ps(coeff_out2_in0, in0_lo, m_offset_out_v_or_r_f))); | |
| 1033 | 288 | out2_hi = _mm256_fmadd_ps(coeff_out2_in2, in2_hi, _mm256_fmadd_ps(coeff_out2_in1, in1_hi, _mm256_fmadd_ps(coeff_out2_in0, in0_hi, m_offset_out_v_or_r_f))); | |
| 1034 | } | ||
| 1035 | }; | ||
| 1036 | |||
| 1037 | // output variables | ||
| 1038 | __m256 out0_1_f_lo, out0_1_f_hi, out1_1_f_lo, out1_1_f_hi, out2_1_f_lo, out2_1_f_hi; | ||
| 1039 | __m256 out0_2_f_lo, out0_2_f_hi, out1_2_f_lo, out1_2_f_hi, out2_2_f_lo, out2_2_f_hi; | ||
| 1040 | |||
| 1041 | // SET#1: First 16 pixels | ||
| 1042 | 78 | matrix_multiply( | |
| 1043 | in0_1_f_lo, in0_1_f_hi, in1_1_f_lo, in1_1_f_hi, in2_1_f_lo, in2_1_f_hi, // in0 in1 in2 | ||
| 1044 | out0_1_f_lo, out0_1_f_hi, out1_1_f_lo, out1_1_f_hi, out2_1_f_lo, out2_1_f_hi // out0 out1 out2: Pixels 0..7 in lo, 8..15 in hi | ||
| 1045 | ); | ||
| 1046 | |||
| 1047 | // SET#2: Next 16 pixels | ||
| 1048 | 78 | matrix_multiply( | |
| 1049 | in0_2_f_lo, in0_2_f_hi, in1_2_f_lo, in1_2_f_hi, in2_2_f_lo, in2_2_f_hi, // in0 in1 in2 | ||
| 1050 | out0_2_f_lo, out0_2_f_hi, out1_2_f_lo, out1_2_f_hi, out2_2_f_lo, out2_2_f_hi // out0 out1 out2: Pixels 16..23 in lo, 24..31 in hi | ||
| 1051 | ); | ||
| 1052 | |||
| 1053 | 339 | auto process_from_float_plane_avx2 = [&](BYTE* plane_ptr, __m256 lo_1, __m256 hi_1, __m256 lo_2, __m256 hi_2) { | |
| 1054 | XP_LAMBDA_CAPTURE_FIX(zero); | ||
| 1055 | XP_LAMBDA_CAPTURE_FIX(limit); | ||
| 1056 | |||
| 1057 | #ifdef XP_TLS | ||
| 1058 | if (final_is_float) { | ||
| 1059 | #else | ||
| 1060 | if constexpr (final_is_float) { | ||
| 1061 | #endif | ||
| 1062 | // float inside path, + 32 bit float output | ||
| 1063 | 87 | const int pix_idx = x / sizeof(pixel_t); | |
| 1064 | 87 | float* f_dst = reinterpret_cast<float*>(plane_ptr) + pix_idx; | |
| 1065 | |||
| 1066 | // Define the blocks (8 pixels each) correctly by healing the lanes | ||
| 1067 | // Remember: this is still quicker that using lane-preserving cvt's earlier. | ||
| 1068 | __m256 blockA, blockB, blockC, blockD; | ||
| 1069 | |||
| 1070 | if constexpr (sizeof(pixel_t) == 1) { | ||
| 1071 | // 8-bit: The lanes were swapped across res1 and res2 | ||
| 1072 | ✗ | blockA = _mm256_permute2f128_ps(lo_1, hi_1, 0x20); // Pixels 0-7 | |
| 1073 | ✗ | blockB = _mm256_permute2f128_ps(lo_2, hi_2, 0x20); // Pixels 8-15 | |
| 1074 | ✗ | blockC = _mm256_permute2f128_ps(lo_1, hi_1, 0x31); // Pixels 16-23 | |
| 1075 | ✗ | blockD = _mm256_permute2f128_ps(lo_2, hi_2, 0x31); // Pixels 24-31 | |
| 1076 | } | ||
| 1077 | else if constexpr (sizeof(pixel_t) == 2) { | ||
| 1078 | // 16-bit: res1 is 0-15, res2 is 16-31 | ||
| 1079 | ✗ | blockA = _mm256_permute2f128_ps(lo_1, hi_1, 0x20); // Pixels 0-7 | |
| 1080 | ✗ | blockB = _mm256_permute2f128_ps(lo_1, hi_1, 0x31); // Pixels 8-15 | |
| 1081 | ✗ | blockC = _mm256_permute2f128_ps(lo_2, hi_2, 0x20); // Pixels 16-23 | |
| 1082 | ✗ | blockD = _mm256_permute2f128_ps(lo_2, hi_2, 0x31); // Pixels 24-31 | |
| 1083 | } | ||
| 1084 | else { | ||
| 1085 | // 32-bit: no lane swap needed, but we still need to define the blocks for the tail processing | ||
| 1086 | 87 | blockA = lo_1; // Pixels 0-7 | |
| 1087 | 87 | blockB = hi_1; // Pixels 8-15 | |
| 1088 | 87 | blockC = lo_2; // Pixels 16-23 | |
| 1089 | 87 | blockD = hi_2; // Pixels 24-31 | |
| 1090 | } | ||
| 1091 | |||
| 1092 | _mm256_store_ps(f_dst, blockA); | ||
| 1093 | 87 | _mm256_store_ps(f_dst + 8, blockB); | |
| 1094 | |||
| 1095 | // Safety check: only store the first half of the 32-pixel block if row width allows | ||
| 1096 |
2/2✓ Branch 4 → 5 taken 39 times.
✓ Branch 4 → 8 taken 48 times.
|
87 | if (safe_last_16float_64bytes) { |
| 1097 | 39 | _mm256_store_ps(f_dst + 16, blockC); | |
| 1098 | 39 | _mm256_store_ps(f_dst + 24, blockD); | |
| 1099 | } | ||
| 1100 | } | ||
| 1101 | else { | ||
| 1102 | // Float workflow + integer output with rounding and clamping | ||
| 1103 | // r,g,b = static_cast<int>(r,g,b_f + 0.5f); | ||
| 1104 | // back to int32 domain | ||
| 1105 | 87 | __m256 float_rounder = _mm256_set1_ps(0.5f); | |
| 1106 | 174 | __m256i res1_lo = _mm256_cvttps_epi32(_mm256_add_ps(lo_1, float_rounder)); | |
| 1107 | 174 | __m256i res1_hi = _mm256_cvttps_epi32(_mm256_add_ps(hi_1, float_rounder)); | |
| 1108 | 174 | __m256i res2_lo = _mm256_cvttps_epi32(_mm256_add_ps(lo_2, float_rounder)); | |
| 1109 | 87 | __m256i res2_hi = _mm256_cvttps_epi32(_mm256_add_ps(hi_2, float_rounder)); | |
| 1110 | |||
| 1111 | 87 | const int pix_idx = x * sizeof(pixel_t_dst) / sizeof(pixel_t); | |
| 1112 | |||
| 1113 | 87 | __m256i p1 = _mm256_packus_epi32(res1_lo, res1_hi); | |
| 1114 | 9 | __m256i p2 = _mm256_packus_epi32(res2_lo, res2_hi); | |
| 1115 | |||
| 1116 | if constexpr (sizeof(pixel_t_dst) == 1) { | ||
| 1117 | // X->8 bits | ||
| 1118 | ✗ | __m256i final8 = _mm256_packus_epi16(p1, p2); | |
| 1119 | if constexpr (sizeof(pixel_t) == 4) { | ||
| 1120 | // 32->8 bits | ||
| 1121 | /* | ||
| 1122 | res1_lo: int32 [ 0 1 2 3 | 4 5 6 7] | ||
| 1123 | res1_hi: int32 [ 8 9 10 11 | 12 13 14 15] | ||
| 1124 | res2_lo: int32 [16 17 18 19 | 20 21 22 23] | ||
| 1125 | res2_hi: int32 [24 25 26 27 | 28 29 30 31] | ||
| 1126 | - after packus_epi32: | ||
| 1127 | p1 = [0..3, 8..11 | 4..7, 12..15] | ||
| 1128 | p2 = [16..19, 24..27 | 20..23, 28..31] | ||
| 1129 | - after packus_epi16 p1, p2: (more lane crossing) | ||
| 1130 | p8 = [0..3, 8..11, 16..19, 24..27 | 4..7, 12..15, 20..23, 28..31] | ||
| 1131 | |||
| 1132 | I need final8: 32 bytes [0,1,2..31] | ||
| 1133 | */ | ||
| 1134 | ✗ | __m256i p1 = _mm256_packus_epi32(res1_lo, res1_hi); | |
| 1135 | ✗ | __m256i p2 = _mm256_packus_epi32(res2_lo, res2_hi); | |
| 1136 | ✗ | __m256i p8 = _mm256_packus_epi16(p1, p2); | |
| 1137 | // p8 = [0..3, 8..11, 16..19, 24..27 | 4..7, 12..15, 20..23, 28..31] | ||
| 1138 | // as 8x int32: [A, B, C, D, E, F, G, H] where we need [A,E,B,F,C,G,D,H] | ||
| 1139 | ✗ | const __m256i idx = _mm256_set_epi32(7, 3, 6, 2, 5, 1, 4, 0); | |
| 1140 | ✗ | final8 = _mm256_permutevar8x32_epi32(p8, idx); | |
| 1141 | } | ||
| 1142 | else if constexpr (sizeof(pixel_t) == 2) { | ||
| 1143 | // 16->8 bits | ||
| 1144 | 6 | final8 = _mm256_permute4x64_epi64(final8, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6)); | |
| 1145 | } | ||
| 1146 | else { | ||
| 1147 | // 8->8 bits, no change needed | ||
| 1148 | } | ||
| 1149 | 9 | _mm256_store_si256(reinterpret_cast<__m256i*>(plane_ptr + pix_idx), final8); | |
| 1150 | } | ||
| 1151 | else if constexpr (sizeof(pixel_t_dst) == 2) { | ||
| 1152 | // x->16 bits | ||
| 1153 | if constexpr (lessthan16bit_target) { | ||
| 1154 | 36 | p1 = _mm256_min_epi16(p1, limit); | |
| 1155 | 36 | p2 = _mm256_min_epi16(p2, limit); | |
| 1156 | } | ||
| 1157 | if constexpr (sizeof(pixel_t) == 1) { | ||
| 1158 | // 8->16 bits: | ||
| 1159 | /* If we'd not pre-shuffled the input for 8->16 bit, we would need to do this shuffle at the end to heal the lanes: | ||
| 1160 | // p1: 0-7 16-23; p2: 8-15 24-31 | ||
| 1161 | // two shuffles per R G B plane would be needed, so 6 total, Pre-shuffling Y U V is only 3 | ||
| 1162 | __m256i temp_p1 = _mm256_permute2x128_si256(p1, p2, 0x20); // 0-7, 8-15 | ||
| 1163 | __m256i temp_p2 = _mm256_permute2x128_si256(p1, p2, 0x31); // 16-23, 24-31 | ||
| 1164 | p1 = temp_p1; | ||
| 1165 | p2 = temp_p2; | ||
| 1166 | */ | ||
| 1167 | } | ||
| 1168 | else if constexpr (sizeof(pixel_t) == 4) { | ||
| 1169 | // 32->16 bits | ||
| 1170 | ✗ | p1 = _mm256_permute4x64_epi64(p1, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6)); // 0xD8 | |
| 1171 | ✗ | p2 = _mm256_permute4x64_epi64(p2, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6)); // 0xD8 | |
| 1172 | } | ||
| 1173 | |||
| 1174 | 78 | _mm256_store_si256(reinterpret_cast<__m256i*>(plane_ptr + pix_idx), p1); | |
| 1175 | 78 | _mm256_store_si256(reinterpret_cast<__m256i*>(plane_ptr + pix_idx + 32), p2); | |
| 1176 | } | ||
| 1177 | } | ||
| 1178 | }; | ||
| 1179 | |||
| 1180 | 78 | process_from_float_plane_avx2(dstp[0], out0_1_f_lo, out0_1_f_hi, out0_2_f_lo, out0_2_f_hi); | |
| 1181 | if constexpr (direction != ConversionDirection::RGB_TO_Y) { | ||
| 1182 | 48 | process_from_float_plane_avx2(dstp[1], out1_1_f_lo, out1_1_f_hi, out1_2_f_lo, out1_2_f_hi); | |
| 1183 | 48 | process_from_float_plane_avx2(dstp[2], out2_1_f_lo, out2_1_f_hi, out2_2_f_lo, out2_2_f_hi); | |
| 1184 | } | ||
| 1185 | // end of float_matrix_workflow | ||
| 1186 | } | ||
| 1187 | else { | ||
| 1188 | // start of integer matrix arithmetic path, both for integer and float target | ||
| 1189 | if constexpr (lessthan16bit) { | ||
| 1190 | // offset_in is added, stored as negative | ||
| 1191 | if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_RGB || direction == ConversionDirection::RGB_TO_Y) { | ||
| 1192 | // RGB sources: same input offset for G, B and R | ||
| 1193 | 96 | in0_1 = _mm256_adds_epi16(in0_1, offset_in); in0_2 = _mm256_adds_epi16(in0_2, offset_in); // G1 G2 | |
| 1194 | 96 | in1_1 = _mm256_adds_epi16(in1_1, offset_in); in1_2 = _mm256_adds_epi16(in1_2, offset_in); // B1 B2 | |
| 1195 | 96 | in2_1 = _mm256_adds_epi16(in2_1, offset_in); in2_2 = _mm256_adds_epi16(in2_2, offset_in); // R1 R2 | |
| 1196 | } | ||
| 1197 | else { | ||
| 1198 | // YUV sources: only luma. add, because offset_in is negative | ||
| 1199 | 98 | in0_1 = _mm256_adds_epi16(in0_1, offset_in); in0_2 = _mm256_adds_epi16(in0_2, offset_in); // Y1 Y2 | |
| 1200 | } | ||
| 1201 | } | ||
| 1202 | else { | ||
| 1203 | // make unsigned to signed by flipping MSB | ||
| 1204 | if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_RGB || direction == ConversionDirection::RGB_TO_Y) { | ||
| 1205 | // RGB sources: same pivoting offset for G, B and R | ||
| 1206 | // pivot the pixel, adjust the offset_in separately, if any, later | ||
| 1207 | ✗ | in0_1 = _mm256_xor_si256(in0_1, sign_flip_mask); in0_2 = _mm256_xor_si256(in0_2, sign_flip_mask); // G1 G2 | |
| 1208 | ✗ | in1_1 = _mm256_xor_si256(in1_1, sign_flip_mask); in1_2 = _mm256_xor_si256(in1_2, sign_flip_mask); // B1 B2 | |
| 1209 | ✗ | in2_1 = _mm256_xor_si256(in2_1, sign_flip_mask); in2_2 = _mm256_xor_si256(in2_2, sign_flip_mask); // R1 R2 | |
| 1210 | } | ||
| 1211 | else { | ||
| 1212 | // YUV sources: only pivot luma, chroma will be pivoted and centered together in the next step | ||
| 1213 | 34 | in0_1 = _mm256_xor_si256(in0_1, sign_flip_mask); in0_2 = _mm256_xor_si256(in0_2, sign_flip_mask); // Y1 Y2 | |
| 1214 | } | ||
| 1215 | } | ||
| 1216 | |||
| 1217 | // YUV source: move to signed UV | ||
| 1218 | if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) { | ||
| 1219 | 132 | in1_1 = _mm256_sub_epi16(in1_1, half); in1_2 = _mm256_sub_epi16(in1_2, half); // U1 U2 | |
| 1220 | 132 | in2_1 = _mm256_sub_epi16(in2_1, half); in2_2 = _mm256_sub_epi16(in2_2, half); // V1 V2 | |
| 1221 | } | ||
| 1222 | |||
| 1223 | // pre-unpack MADD pairs | ||
| 1224 | // These are common for all R, G, B planes | ||
| 1225 | // Pair 1: [U0 Y0 U1 Y1 ... | U8 Y8 U9 Y9 ...] | ||
| 1226 | 114 | __m256i uy1_lo = _mm256_unpacklo_epi16(in1_1, in0_1); | |
| 1227 | 114 | __m256i uy1_hi = _mm256_unpackhi_epi16(in1_1, in0_1); | |
| 1228 | 114 | __m256i uy2_lo = _mm256_unpacklo_epi16(in1_2, in0_2); | |
| 1229 | 114 | __m256i uy2_hi = _mm256_unpackhi_epi16(in1_2, in0_2); | |
| 1230 | |||
| 1231 | // Pair 2: [V0 Rnd V1 Rnd ... | V8 Rnd V9 Rnd ...] | ||
| 1232 | 114 | __m256i vr1_lo = _mm256_unpacklo_epi16(in2_1, m256i_round_scale); | |
| 1233 | 114 | __m256i vr1_hi = _mm256_unpackhi_epi16(in2_1, m256i_round_scale); | |
| 1234 | 114 | __m256i vr2_lo = _mm256_unpacklo_epi16(in2_2, m256i_round_scale); | |
| 1235 | 114 | __m256i vr2_hi = _mm256_unpackhi_epi16(in2_2, m256i_round_scale); | |
| 1236 | |||
| 1237 | // for 16 bit, the rgb_offset is merged into the post patch adjustment | ||
| 1238 | // 13 bit fixed point arithmetic rounder 0.5 is 4096. In general: INT_ARITH_SHIFT | ||
| 1239 | // Need1: (m.y_b m.u_b ) (m.y_b m.u_b) (m.y_b m.u_b) (m.y_b m.u_b) 8x16 bit | ||
| 1240 | // ( y3 u3 ) ( y2 u2 ) ( y1 u1 ) ( y0 u0 ) 8x16 bit | ||
| 1241 | // res1= (y_b*y3 + u_b*u3) ... 4x32 bit | ||
| 1242 | // Need2: (m.v_b round') (m.y_b round') (m.y_b round') (m.y_b round') | ||
| 1243 | // ( v3 4096 ) ( v2 4096 ) ( v1 4096 ) ( v0 4096 ) | ||
| 1244 | // res2= (yv_b*v3 + round' ) ... round' = round + rgb_offset | ||
| 1245 | |||
| 1246 | // Processing lambda - checked and benchmarked to be inlined nicely -avoids code bloat | ||
| 1247 | |||
| 1248 | // For v141_xp compatibility: forces the compiler to capture a const variable | ||
| 1249 | // that would otherwise be optimized out of nested lambda scopes. | ||
| 1250 | |||
| 1251 | // integer matrix arithmetic path, followed by integer-integer shift-scaling or 32-bit float conversion. | ||
| 1252 | 738 | auto process_plane = [&](BYTE* plane_ptr, __m256i m_uy, __m256i m_vr, __m256i v_patch, auto apply_float_offset_out) { | |
| 1253 | XP_LAMBDA_CAPTURE_FIX(limit); | ||
| 1254 | XP_LAMBDA_CAPTURE_FIX(safe_last_16float_64bytes); | ||
| 1255 | // Note: v_patch is already set to the right 32 or 64 bits width based on final_is_float and lessthan16bit | ||
| 1256 | 1560 | auto madd_scale = [&](__m256i uy, __m256i vr) { | |
| 1257 | XP_LAMBDA_CAPTURE_FIX(v_patch); | ||
| 1258 | XP_LAMBDA_CAPTURE_FIX(target_shift); | ||
| 1259 | 3744 | __m256i sum = _mm256_add_epi32(_mm256_madd_epi16(m_uy, uy), _mm256_madd_epi16(m_vr, vr)); | |
| 1260 | // 16-bit adjustment (signed patch, offset_in, output rgb offset_in) | ||
| 1261 | |||
| 1262 | #ifdef XP_TLS | ||
| 1263 | if (!final_is_float) | ||
| 1264 | #else | ||
| 1265 | if constexpr (!final_is_float) | ||
| 1266 | #endif | ||
| 1267 | { | ||
| 1268 | __m256i sum_lo, sum_hi; | ||
| 1269 | #ifdef XP_TLS | ||
| 1270 | if (!would_need_64bit_v_patch) | ||
| 1271 | #else | ||
| 1272 | if constexpr (!would_need_64bit_v_patch) | ||
| 1273 | #endif | ||
| 1274 | { | ||
| 1275 | 2472 | sum = _mm256_add_epi32(sum, v_patch); | |
| 1276 | } | ||
| 1277 | else { | ||
| 1278 | // use two 64 bit sums | ||
| 1279 | // avx2 extract low/high 128 bits, add, then insert back | ||
| 1280 | sum_lo = _mm256_cvtepi32_epi64(_mm256_castsi256_si128(sum)); | ||
| 1281 | sum_lo = _mm256_add_epi64(sum_lo, v_patch); | ||
| 1282 | sum_hi = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(sum, 1)); | ||
| 1283 | sum_hi = _mm256_add_epi64(sum_hi, v_patch); | ||
| 1284 | } | ||
| 1285 | // target_shift is INT_ARITH_SHIFT - modified with bit-conversion diff, bit fixed point shift | ||
| 1286 | #ifdef XP_TLS | ||
| 1287 | if (!would_need_64bit_v_patch) { | ||
| 1288 | #else | ||
| 1289 | if constexpr (!would_need_64bit_v_patch) { | ||
| 1290 | #endif | ||
| 1291 | 24 | sum = _mm256_srai_epi32(sum, target_shift); | |
| 1292 | } | ||
| 1293 | else { | ||
| 1294 | // _mm256_srai_epi64 is AVX512+VL only | ||
| 1295 | sum_lo = mm256_srai_epi64_simul(sum_lo, target_shift); | ||
| 1296 | sum_hi = mm256_srai_epi64_simul(sum_hi, target_shift); | ||
| 1297 | } | ||
| 1298 | #ifdef XP_TLS | ||
| 1299 | if (would_need_64bit_v_patch) { | ||
| 1300 | #else | ||
| 1301 | if constexpr (would_need_64bit_v_patch) { | ||
| 1302 | #endif | ||
| 1303 | // pack back to 32 bit: no _mm256_cvtepi64_epi32 in AVX2 | ||
| 1304 | __m256i pack_lo = _mm256_shuffle_epi32(sum_lo, _MM_SHUFFLE(3, 2, 2, 0)); | ||
| 1305 | __m256i pack_hi = _mm256_shuffle_epi32(sum_hi, _MM_SHUFFLE(3, 2, 2, 0)); | ||
| 1306 | __m256i mixed = _mm256_unpacklo_epi64(pack_lo, pack_hi); | ||
| 1307 | // [0, 1, 4, 5 | 2, 3, 6, 7] => [0, 1, 2, 3 | 4, 5, 6, 7] | ||
| 1308 | sum = _mm256_permute4x64_epi64(mixed, _MM_SHUFFLE(3, 1, 2, 0)); | ||
| 1309 | } | ||
| 1310 | } | ||
| 1311 | else { | ||
| 1312 | // no 64-bit needed, no overflow danger in pivot, since no U and V integer offset which is the cause of overflow. | ||
| 1313 | ✗ | sum = _mm256_add_epi32(sum, v_patch); | |
| 1314 | } | ||
| 1315 | 1248 | return sum; | |
| 1316 | }; | ||
| 1317 | |||
| 1318 | 312 | __m256i res1_lo = madd_scale(uy1_lo, vr1_lo); // Pixels 0-3, 8-11 | |
| 1319 | 312 | __m256i res1_hi = madd_scale(uy1_hi, vr1_hi); // Pixels 4-7, 12-15 | |
| 1320 | 312 | __m256i res2_lo = madd_scale(uy2_lo, vr2_lo); // Pixels 16-19, 24-27 | |
| 1321 | 312 | __m256i res2_hi = madd_scale(uy2_hi, vr2_hi); // Pixels 20-23, 28-31 | |
| 1322 | |||
| 1323 | #ifdef XP_TLS | ||
| 1324 | if (final_is_float) { | ||
| 1325 | #else | ||
| 1326 | if constexpr (final_is_float) { | ||
| 1327 | #endif | ||
| 1328 | // when float output is needed, convert after scaling, mimic a post-ConvertBits | ||
| 1329 | ✗ | const int pix_idx = x / sizeof(pixel_t); | |
| 1330 | ✗ | float* f_dst = reinterpret_cast<float*>(plane_ptr) + pix_idx; | |
| 1331 | |||
| 1332 | // Define the blocks (8 pixels each) correctly by healing the lanes | ||
| 1333 | ✗ | __m256i blockA = _mm256_permute2x128_si256(res1_lo, res1_hi, 0x20); // Pixels 0-7 | |
| 1334 | __m256i blockB, blockC, blockD; | ||
| 1335 | |||
| 1336 | if constexpr (sizeof(pixel_t) == 1) { | ||
| 1337 | // 8-bit: The lanes were swapped across res1 and res2 | ||
| 1338 | ✗ | blockB = _mm256_permute2x128_si256(res2_lo, res2_hi, 0x20); // Pixels 8-15 | |
| 1339 | ✗ | blockC = _mm256_permute2x128_si256(res1_lo, res1_hi, 0x31); // Pixels 16-23 | |
| 1340 | ✗ | blockD = _mm256_permute2x128_si256(res2_lo, res2_hi, 0x31); // Pixels 24-31 | |
| 1341 | } | ||
| 1342 | else { | ||
| 1343 | // 16-bit: res1 is 0-15, res2 is 16-31 | ||
| 1344 | ✗ | blockB = _mm256_permute2x128_si256(res1_lo, res1_hi, 0x31); // Pixels 8-15 | |
| 1345 | ✗ | blockC = _mm256_permute2x128_si256(res2_lo, res2_hi, 0x20); // Pixels 16-23 | |
| 1346 | ✗ | blockD = _mm256_permute2x128_si256(res2_lo, res2_hi, 0x31); // Pixels 24-31 | |
| 1347 | } | ||
| 1348 | |||
| 1349 | // Convert and Store | ||
| 1350 | ✗ | auto store_block = [&](float* ptr, __m256i b, auto apply_float_offset_out) { | |
| 1351 | ✗ | if (apply_float_offset_out) | |
| 1352 | ✗ | _mm256_store_ps(ptr, _mm256_fmadd_ps(_mm256_cvtepi32_ps(b), scale_f_avx2, out_offset_f_avx2)); | |
| 1353 | else // only mul, no add, when offset_out is 0 for non Y,R,G,B channels | ||
| 1354 | ✗ | _mm256_store_ps(ptr, _mm256_mul_ps(_mm256_cvtepi32_ps(b), scale_f_avx2)); | |
| 1355 | }; | ||
| 1356 | |||
| 1357 | ✗ | store_block(f_dst, blockA, apply_float_offset_out); | |
| 1358 | ✗ | store_block(f_dst + 8, blockB, apply_float_offset_out); | |
| 1359 | |||
| 1360 | // Safety check: only store the first half of the 32-pixel block if row width allows | ||
| 1361 | ✗ | if (safe_last_16float_64bytes) { | |
| 1362 | ✗ | store_block(f_dst + 16, blockC, apply_float_offset_out); | |
| 1363 | ✗ | store_block(f_dst + 24, blockD, apply_float_offset_out); | |
| 1364 | } | ||
| 1365 | } | ||
| 1366 | else { | ||
| 1367 | 312 | const int pix_idx = x * sizeof(pixel_t_dst) / sizeof(pixel_t); | |
| 1368 | // unlike SSE2, AVX2 has packus_epi32 | ||
| 1369 | 312 | __m256i p1 = _mm256_packus_epi32(res1_lo, res1_hi); // Auto-heals lanes, no permute needed | |
| 1370 | 207 | __m256i p2 = _mm256_packus_epi32(res2_lo, res2_hi); | |
| 1371 | |||
| 1372 | if constexpr (sizeof(pixel_t_dst) == 1) { | ||
| 1373 | // X->8 bits | ||
| 1374 | 207 | __m256i final8 = _mm256_packus_epi16(p1, p2); | |
| 1375 | if constexpr (sizeof(pixel_t) == 2) { | ||
| 1376 | // 16->8 extra shuffle | ||
| 1377 | ✗ | final8 = _mm256_permute4x64_epi64(final8, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6)); | |
| 1378 | } | ||
| 1379 | 207 | _mm256_store_si256(reinterpret_cast<__m256i*>(plane_ptr + pix_idx), final8); | |
| 1380 | } | ||
| 1381 | else { | ||
| 1382 | // X->16 bits | ||
| 1383 | if constexpr (lessthan16bit_target) { | ||
| 1384 | 48 | p1 = _mm256_min_epi16(p1, limit); | |
| 1385 | 48 | p2 = _mm256_min_epi16(p2, limit); | |
| 1386 | } | ||
| 1387 | if constexpr (sizeof(pixel_t) == 1) { | ||
| 1388 | // 8->16 bits: | ||
| 1389 | /* If we'd not pre-shuffled the input for 8->16 bit, we would need to do this shuffle at the end to heal the lanes: | ||
| 1390 | // p1: 0-7 16-23; p2: 8-15 24-31 | ||
| 1391 | // two shuffles per R G B plane would be needed, so 6 total, Pre-shuffling Y U V is only 3 | ||
| 1392 | __m256i temp_p1 = _mm256_permute2x128_si256(p1, p2, 0x20); // 0-7, 8-15 | ||
| 1393 | __m256i temp_p2 = _mm256_permute2x128_si256(p1, p2, 0x31); // 16-23, 24-31 | ||
| 1394 | p1 = temp_p1; | ||
| 1395 | p2 = temp_p2; | ||
| 1396 | */ | ||
| 1397 | } | ||
| 1398 | 105 | _mm256_store_si256(reinterpret_cast<__m256i*>(plane_ptr + pix_idx), p1); | |
| 1399 | 105 | _mm256_store_si256(reinterpret_cast<__m256i*>(plane_ptr + pix_idx + 32), p2); | |
| 1400 | } | ||
| 1401 | } | ||
| 1402 | }; | ||
| 1403 | |||
| 1404 | // Process planes, using pre-packed coefficient, and the 16 bit patch if needed | ||
| 1405 | 114 | process_plane(dstp[0], m_uy_G, m_vr_G, v_patch_G, true /* apply_float_offset_out */); | |
| 1406 | // only Y,R,G,B needs it uniformly, so for YUV, we call it with false | ||
| 1407 | // last param: apply_float_offset_out | ||
| 1408 | if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::RGB_TO_RGB) { | ||
| 1409 | 57 | process_plane(dstp[1], m_uy_B, m_vr_B, v_patch_B, true); | |
| 1410 | 57 | process_plane(dstp[2], m_uy_R, m_vr_R, v_patch_R, true); | |
| 1411 | } | ||
| 1412 | else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::YUV_TO_YUV) { | ||
| 1413 | 42 | process_plane(dstp[1], m_uy_B, m_vr_B, v_patch_B, false); | |
| 1414 | 42 | process_plane(dstp[2], m_uy_R, m_vr_R, v_patch_R, false); | |
| 1415 | } | ||
| 1416 | else if constexpr (direction != ConversionDirection::RGB_TO_Y) { | ||
| 1417 | // no other planes | ||
| 1418 | } | ||
| 1419 | } // if float_matrix_workflow else integer_matrix_arithmetic | ||
| 1420 | } // x | ||
| 1421 | 187 | srcp[0] += srcPitch[0]; | |
| 1422 | 187 | srcp[1] += srcPitch[1]; | |
| 1423 | 187 | srcp[2] += srcPitch[2]; | |
| 1424 | 187 | dstp[0] += dstPitch[0]; | |
| 1425 | if constexpr (direction != ConversionDirection::RGB_TO_Y) { | ||
| 1426 | 142 | dstp[1] += dstPitch[1]; | |
| 1427 | 142 | dstp[2] += dstPitch[2]; | |
| 1428 | } | ||
| 1429 | } // y | ||
| 1430 | 52 | } | |
| 1431 | |||
| 1432 | #undef XP_LAMBDA_CAPTURE_FIX | ||
| 1433 | |||
| 1434 | // Further separating cases inside, dispatcher remains relatively simple | ||
| 1435 | template<ConversionDirection direction, typename pixel_t_src, bool lessthan16bit> | ||
| 1436 | 52 | void convert_yuv_to_planarrgb_avx2(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, | |
| 1437 | int bits_per_pixel, int bits_per_pixel_target, bool force_float) | ||
| 1438 | { | ||
| 1439 | // Accuracy forever | ||
| 1440 |
15/24void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 11 taken 9 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 11 taken 3 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 11 taken 2 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 11 taken 5 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 11 taken 3 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 11 taken 1 time.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 11 taken 1 time.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 11 taken 2 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 11 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 11 taken 3 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 11 taken 2 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 11 taken 3 times.
|
40 | if (force_float || std::is_floating_point<pixel_t_src>::value) { |
| 1441 | // int->float conversion | ||
| 1442 | // limited/full is handled automatically through scaling and offsets | ||
| 1443 | // lessthan16bit_target is still important due to clamping | ||
| 1444 |
9/32void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, float, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 4 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, float, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 4 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 2 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, float, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, float, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 3 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 1 time.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 1 time.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 1 time.
|
18 | if (bits_per_pixel_target == 8) { |
| 1445 | 1 | convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, true, uint8_t, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target); | |
| 1446 | } | ||
| 1447 |
8/32void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, float, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 4 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, float, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 4 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 7 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, float, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 1 time.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, float, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 3 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 7 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 1 time.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 7 not taken.
|
17 | else if (bits_per_pixel_target < 16) { |
| 1448 | // lessthan16bit_target is false. Need signed pack and clamping | ||
| 1449 | 4 | convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, true, uint16_t, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target); | |
| 1450 | } | ||
| 1451 |
5/32void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, float, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 4 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, float, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 4 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, float, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 1 time.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, float, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 3 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 9 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
|
13 | else if (bits_per_pixel_target == 16) { // == 16 |
| 1452 | 1 | convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, false, uint16_t, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target); | |
| 1453 | } | ||
| 1454 | else { // 32 bit float target | ||
| 1455 | // limited/full is handled automatically through scaling and offsets | ||
| 1456 | // lessthan16bit_target doesn't matter since float output has no clamping | ||
| 1457 | 12 | convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, false, float, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target); | |
| 1458 | } | ||
| 1459 | 18 | return; | |
| 1460 | } | ||
| 1461 | |||
| 1462 | // this is needed to avoid instantiating the full integer conversion logic when not needed, | ||
| 1463 | // it can result static_asssert failure. | ||
| 1464 | if constexpr (!std::is_floating_point<pixel_t_src>::value) { | ||
| 1465 | 34 | const bool need_conversion = bits_per_pixel_target != bits_per_pixel; | |
| 1466 |
14/24void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 11 → 12 taken 8 times.
✓ Branch 11 → 14 taken 1 time.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 11 → 12 taken 3 times.
✗ Branch 11 → 14 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 11 → 12 taken 2 times.
✗ Branch 11 → 14 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 11 → 12 taken 5 times.
✗ Branch 11 → 14 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 11 → 12 taken 3 times.
✗ Branch 11 → 14 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 14 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 14 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 11 → 12 taken 2 times.
✗ Branch 11 → 14 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 14 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 11 → 12 taken 2 times.
✓ Branch 11 → 14 taken 1 time.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 14 taken 2 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 11 → 12 taken 1 time.
✓ Branch 11 → 14 taken 2 times.
|
34 | if (!need_conversion) { |
| 1467 | // no conversion, just YUV to RGB | ||
| 1468 | 28 | convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, lessthan16bit, pixel_t_src, YuvRgbConversionType::NATIVE_INT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target); | |
| 1469 | 28 | return; | |
| 1470 | } | ||
| 1471 | |||
| 1472 | 6 | const bool full_d = m.offset_rgb == 0; | |
| 1473 | |||
| 1474 |
8/48void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 29 not taken.
✓ Branch 15 → 16 taken 1 time.
✗ Branch 15 → 29 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 29 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 29 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 29 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 29 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 29 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 29 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 29 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 29 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 29 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 29 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 29 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 29 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 29 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 29 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 29 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 29 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 29 not taken.
✓ Branch 15 → 16 taken 1 time.
✗ Branch 15 → 29 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 14 → 15 taken 2 times.
✗ Branch 14 → 29 not taken.
✓ Branch 15 → 16 taken 2 times.
✗ Branch 15 → 29 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 14 → 15 taken 2 times.
✗ Branch 14 → 29 not taken.
✓ Branch 15 → 16 taken 2 times.
✗ Branch 15 → 29 not taken.
|
6 | if (bits_per_pixel_target >= 8 && bits_per_pixel <= 16) { |
| 1475 | // int->int conversion with range conversion (limited<->full), or upscale with no range conversion (full->full or limited->limited) | ||
| 1476 |
4/24void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 20 taken 1 time.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 20 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 20 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 20 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 20 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 20 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 20 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 20 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 20 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 20 taken 1 time.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 16 → 17 taken 2 times.
✗ Branch 16 → 20 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 20 taken 2 times.
|
6 | if (bits_per_pixel_target == 8) { |
| 1477 |
1/24void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 2 times.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
|
2 | if (full_d) |
| 1478 | ✗ | convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, true, uint8_t, YuvRgbConversionType::BITCONV_INT_FULL>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target); | |
| 1479 | else | ||
| 1480 | 2 | convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, true, uint8_t, YuvRgbConversionType::BITCONV_INT_LIMITED>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target); | |
| 1481 | } | ||
| 1482 |
3/24void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 24 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 24 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 24 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 24 taken 2 times.
|
4 | else if (bits_per_pixel_target < 16) { |
| 1483 | // lessthan16bit_target is false. Need signed pack and clamping | ||
| 1484 |
2/24void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 23 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 23 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
|
2 | if (full_d) |
| 1485 | 2 | convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, true, uint16_t, YuvRgbConversionType::BITCONV_INT_FULL>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target); | |
| 1486 | else | ||
| 1487 | ✗ | convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, true, uint16_t, YuvRgbConversionType::BITCONV_INT_LIMITED>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target); | |
| 1488 | } | ||
| 1489 |
1/24void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 28 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 28 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 28 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 28 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 28 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 28 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 28 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 28 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 28 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 28 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 28 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✓ Branch 24 → 25 taken 2 times.
✗ Branch 24 → 28 not taken.
|
2 | else if (bits_per_pixel_target == 16) { // == 16 |
| 1490 |
1/24void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)0, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)1, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)2, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned char, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, false>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
void convert_yuv_to_planarrgb_avx2<(ConversionDirection)4, unsigned short, true>(unsigned char* (&) [3], int (&) [3], unsigned char const* (&) [3], int const (&) [3], int, int, ConversionMatrix const&, int, int, bool):
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 2 times.
|
2 | if (full_d) |
| 1491 | ✗ | convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, false, uint16_t, YuvRgbConversionType::BITCONV_INT_FULL>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target); | |
| 1492 | else | ||
| 1493 | 2 | convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, false, uint16_t, YuvRgbConversionType::BITCONV_INT_LIMITED>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target); | |
| 1494 | } | ||
| 1495 | else { // 32 bit float target | ||
| 1496 | // int->float conversion | ||
| 1497 | // limited/full is handled automatically through scaling and offsets | ||
| 1498 | // lessthan16bit_target doesn't matter since float output has no clamping | ||
| 1499 | ✗ | convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, false, float, YuvRgbConversionType::FLOAT_OUTPUT /*n/a*/>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target); | |
| 1500 | } | ||
| 1501 | } | ||
| 1502 | } | ||
| 1503 | } | ||
| 1504 | |||
| 1505 | //instantiate | ||
| 1506 | // YUV_TO_RGB | ||
| 1507 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_RGB, uint8_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1508 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_RGB, uint16_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1509 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_RGB, uint16_t, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1510 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_RGB, float, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1511 | |||
| 1512 | // RGB_TO_YUV | ||
| 1513 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_YUV, uint8_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1514 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_YUV, uint16_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1515 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_YUV, uint16_t, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1516 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_YUV, float, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1517 | |||
| 1518 | // RGB_TO_Y | ||
| 1519 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_Y, uint8_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1520 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_Y, uint16_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1521 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_Y, uint16_t, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1522 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_Y, float, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1523 | |||
| 1524 | // YUV_TO_YUV (for future use - e.g., BT.601 → BT.709) | ||
| 1525 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_YUV, uint8_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1526 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_YUV, uint16_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1527 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_YUV, uint16_t, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1528 | template void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_YUV, float, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float); | ||
| 1529 | |||
| 1530 | DISABLE_WARNING_POP | ||
| 1531 |