Skip to content

Commit 9281c5a

Browse files
committed
Yuv color gamut conversion and transformYuv420 using Risc-V Vector
1 parent cff53d3 commit 9281c5a

File tree

5 files changed

+427
-2
lines changed

5 files changed

+427
-2
lines changed

CMakeLists.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,10 +279,10 @@ else()
279279
add_compile_options(-march=armv8-a)
280280
add_compile_options(-fno-lax-vector-conversions)
281281
elseif(ARCH STREQUAL "riscv64")
282-
add_compile_options(-march=rv64gc)
282+
add_compile_options(-march=rv64gcv)
283283
add_compile_options(-mabi=lp64d)
284284
elseif(ARCH STREQUAL "riscv32")
285-
add_compile_options(-march=rv32gc)
285+
add_compile_options(-march=rv32gcv)
286286
add_compile_options(-mabi=ilp32d)
287287
elseif(ARCH STREQUAL "loong64")
288288
add_compile_options(-march=loongarch64)
@@ -553,6 +553,14 @@ if(UHDR_ENABLE_INTRINSICS)
553553
file(GLOB UHDR_CORE_NEON_SRCS_LIST "${SOURCE_DIR}/src/dsp/arm/*.cpp")
554554
list(APPEND UHDR_CORE_SRCS_LIST ${UHDR_CORE_NEON_SRCS_LIST})
555555
endif()
556+
if(ARCH STREQUAL "riscv64")
557+
file(GLOB UHDR_CORE_RVV_SRCS_LIST "${SOURCE_DIR}/src/dsp/riscv/*.cpp")
558+
list(APPEND UHDR_CORE_SRCS_LIST ${UHDR_CORE_RVV_SRCS_LIST})
559+
endif()
560+
if(ARCH STREQUAL "riscv32")
561+
file(GLOB UHDR_CORE_RVV_SRCS_LIST "${SOURCE_DIR}/src/dsp/riscv/*.cpp")
562+
list(APPEND UHDR_CORE_SRCS_LIST ${UHDR_CORE_RVV_SRCS_LIST})
563+
endif()
556564
endif()
557565
if(UHDR_ENABLE_GLES)
558566
file(GLOB UHDR_CORE_GLES_SRCS_LIST "${SOURCE_DIR}/src/gpu/*.cpp")

lib/include/ultrahdr/gainmapmath.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,21 @@ uhdr_error_info_t convertYuv_neon(uhdr_raw_image_t* image, uhdr_color_gamut_t sr
437437
uhdr_color_gamut_t dst_encoding);
438438
#endif
439439

440+
#if (defined(UHDR_ENABLE_INTRINSICS) && defined(__riscv_v_intrinsic))
441+
442+
extern const int16_t kYuv709To601_coeffs_rvv[8];
443+
extern const int16_t kYuv709To2100_coeffs_rvv[8];
444+
extern const int16_t kYuv601To709_coeffs_rvv[8];
445+
extern const int16_t kYuv601To2100_coeffs_rvv[8];
446+
extern const int16_t kYuv2100To709_coeffs_rvv[8];
447+
extern const int16_t kYuv2100To601_coeffs_rvv[8];
448+
449+
void transformYuv420_rvv(uhdr_raw_image_t* image, const int16_t* coeffs_ptr);
450+
451+
uhdr_error_info_t convertYuv_rvv(uhdr_raw_image_t* image, uhdr_color_gamut_t src_encoding,
452+
uhdr_color_gamut_t dst_encoding);
453+
#endif
454+
440455
// Performs a color gamut transformation on an yuv image.
441456
Color yuvColorGamutConversion(Color e_gamma, const std::array<float, 9>& coeffs);
442457
void transformYuv420(uhdr_raw_image_t* image, const std::array<float, 9>& coeffs);
Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
/*
2+
* Copyright 2024 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "ultrahdr/gainmapmath.h"
18+
#include <riscv_vector.h>
19+
#include <cassert>
20+
21+
namespace ultrahdr {
22+
23+
// Scale all coefficients by 2^14 to avoid needing floating-point arithmetic. This can cause an off
24+
// by one error compared to the scalar floating-point implementation.
25+
26+
// Removing conversion coefficients 1 and 0 from the group for each standard leaves 6 coefficients.
27+
// Pack them into a single 128-bit vector as follows, zeroing the remaining elements:
28+
// {Y1, Y2, U1, U2, V1, V2, 0, 0}
29+
30+
// Yuv Bt709 -> Yuv Bt601
31+
// Y' = (1.0f * Y) + ( 0.101579f * U) + ( 0.196076f * V)
32+
// U' = (0.0f * Y) + ( 0.989854f * U) + (-0.110653f * V)
33+
// V' = (0.0f * Y) + (-0.072453f * U) + ( 0.983398f * V)
34+
__attribute__((aligned(16)))
35+
const int16_t kYuv709To601_coeffs_rvv[8] = {1664, 3213, 16218, -1813, -1187, 16112, 0, 0};
36+
37+
// Yuv Bt709 -> Yuv Bt2100
38+
// Y' = (1.0f * Y) + (-0.016969f * U) + ( 0.096312f * V)
39+
// U' = (0.0f * Y) + ( 0.995306f * U) + (-0.051192f * V)
40+
// V' = (0.0f * Y) + ( 0.011507f * U) + ( 1.002637f * V)
41+
__attribute__((aligned(16)))
42+
const int16_t kYuv709To2100_coeffs_rvv[8] = {-278, 1578, 16307, -839, 189, 16427, 0, 0};
43+
44+
// Yuv Bt601 -> Yuv Bt709
45+
// Y' = (1.0f * Y) + (-0.118188f * U) + (-0.212685f * V),
46+
// U' = (0.0f * Y) + ( 1.018640f * U) + ( 0.114618f * V),
47+
// V' = (0.0f * Y) + ( 0.075049f * U) + ( 1.025327f * V);
48+
__attribute__((aligned(16)))
49+
const int16_t kYuv601To709_coeffs_rvv[8] = {-1936, -3485, 16689, 1878, 1230, 16799, 0, 0};
50+
51+
// Yuv Bt601 -> Yuv Bt2100
52+
// Y' = (1.0f * Y) + (-0.128245f * U) + (-0.115879f * V)
53+
// U' = (0.0f * Y) + ( 1.010016f * U) + ( 0.061592f * V)
54+
// V' = (0.0f * Y) + ( 0.086969f * U) + ( 1.029350f * V)
55+
__attribute__((aligned(16)))
56+
const int16_t kYuv601To2100_coeffs_rvv[8] = {-2101, -1899, 16548, 1009, 1425, 16865, 0, 0};
57+
58+
// Yuv Bt2100 -> Yuv Bt709
59+
// Y' = (1.0f * Y) + ( 0.018149f * U) + (-0.095132f * V)
60+
// U' = (0.0f * Y) + ( 1.004123f * U) + ( 0.051267f * V)
61+
// V' = (0.0f * Y) + (-0.011524f * U) + ( 0.996782f * V)
62+
__attribute__((aligned(16)))
63+
const int16_t kYuv2100To709_coeffs_rvv[8] = {297, -1559, 16452, 840, -189, 16331, 0, 0};
64+
65+
// Yuv Bt2100 -> Yuv Bt601
66+
// Y' = (1.0f * Y) + ( 0.117887f * U) + ( 0.105521f * V)
67+
// U' = (0.0f * Y) + ( 0.995211f * U) + (-0.059549f * V)
68+
// V' = (0.0f * Y) + (-0.084085f * U) + ( 0.976518f * V)
69+
__attribute__((aligned(16)))
70+
const int16_t kYuv2100To601_coeffs_rvv[8] = {1931, 1729, 16306, -976, -1378, 15999, 0, 0};
71+
72+
static inline vuint16m8_t zip_self(vuint16m4_t a, size_t vl) {
73+
vuint32m8_t a_wide = __riscv_vzext_vf2_u32m8(a, vl / 2);
74+
vuint16m8_t a_zero = __riscv_vreinterpret_v_u32m8_u16m8(a_wide);
75+
vuint16m8_t a_zero_slide = __riscv_vslide1up_vx_u16m8(a_zero, 0, vl);
76+
vuint16m8_t a_zip = __riscv_vadd_vv_u16m8(a_zero, a_zero_slide, vl);
77+
return a_zip;
78+
}
79+
80+
static inline vint16m4_t vqrshrn_n_s32(vint32m8_t a, const int b, size_t vl) {
81+
return __riscv_vnclip_wx_i16m4(a, b, vl);
82+
}
83+
84+
static inline vuint8m4_t vget_low_u8(vuint8m8_t u) { return __riscv_vget_v_u8m8_u8m4(u, 0); }
85+
86+
static inline vuint8m4_t vget_high_u8(vuint8m8_t u, size_t vl) {
87+
return __riscv_vget_v_u8m8_u8m4(__riscv_vslidedown_vx_u8m8(u, vl / 2, vl), 0);
88+
}
89+
90+
static inline vint16m4_t vget_low_s16(vint16m8_t u) { return __riscv_vget_v_i16m8_i16m4(u, 0); }
91+
92+
static inline vint16m4_t vget_high_s16(vint16m8_t u, size_t vl) {
93+
return __riscv_vget_v_i16m8_i16m4(__riscv_vslidedown_vx_i16m8(u, vl / 2, vl), 0);
94+
}
95+
96+
static inline vuint16m4_t vget_low_u16(vuint16m8_t u) { return __riscv_vget_v_u16m8_u16m4(u, 0); }
97+
98+
static inline vuint16m4_t vget_high_u16(vuint16m8_t u, size_t vl) {
99+
return __riscv_vget_v_u16m8_u16m4(__riscv_vslidedown_vx_u16m8(u, vl / 2, vl), 0);
100+
}
101+
102+
static inline vint16m8_t vcombine_s16(vint16m4_t a, vint16m4_t b, size_t vl) {
103+
vint16m8_t a_wide = __riscv_vlmul_ext_v_i16m4_i16m8(a);
104+
vint16m8_t b_wide = __riscv_vlmul_ext_v_i16m4_i16m8(b);
105+
return __riscv_vslideup_vx_i16m8(a_wide, b_wide, vl / 2, vl);
106+
}
107+
108+
static inline vuint8m8_t vcombine_u8(vuint8m4_t a, vuint8m4_t b, size_t vl) {
109+
vuint8m8_t a_wide = __riscv_vlmul_ext_v_u8m4_u8m8(a);
110+
vuint8m8_t b_wide = __riscv_vlmul_ext_v_u8m4_u8m8(b);
111+
return __riscv_vslideup_vx_u8m8(a_wide, b_wide, vl / 2, vl);
112+
}
113+
114+
static inline vint16m8_t yConversion_rvv(vuint8m4_t y, vint16m8_t u, vint16m8_t v,
115+
const int16_t* coeffs, size_t vl) {
116+
vint32m8_t u_lo = __riscv_vwmul_vx_i32m8(vget_low_s16(u), coeffs[0], vl / 2);
117+
vint32m8_t u_hi = __riscv_vwmul_vx_i32m8(vget_high_s16(u, vl), coeffs[0], vl / 2);
118+
119+
vint32m8_t v_lo = __riscv_vwmul_vx_i32m8(vget_low_s16(v), coeffs[1], vl / 2);
120+
vint32m8_t v_hi = __riscv_vwmul_vx_i32m8(vget_high_s16(v, vl), coeffs[1], vl / 2);
121+
122+
vint32m8_t lo = __riscv_vadd_vv_i32m8(u_lo, v_lo, vl / 2);
123+
vint32m8_t hi = __riscv_vadd_vv_i32m8(u_hi, v_hi, vl / 2);
124+
125+
vint16m4_t lo_shr = vqrshrn_n_s32(lo, 14, vl / 2);
126+
vint16m4_t hi_shr = vqrshrn_n_s32(hi, 14, vl / 2);
127+
128+
vint16m8_t y_output = vcombine_s16(lo_shr, hi_shr, vl);
129+
vuint16m8_t y_u16 = __riscv_vreinterpret_v_i16m8_u16m8(y_output);
130+
vuint16m8_t y_ret = __riscv_vwaddu_wv_u16m8(y_u16, y, vl);
131+
return __riscv_vreinterpret_v_u16m8_i16m8(y_ret);
132+
}
133+
134+
static inline vint16m8_t uConversion_rvv(vint16m8_t u, vint16m8_t v, const int16_t* coeffs,
135+
size_t vl) {
136+
vint32m8_t u_lo = __riscv_vwmul_vx_i32m8(vget_low_s16(u), coeffs[2], vl / 2);
137+
vint32m8_t u_hi = __riscv_vwmul_vx_i32m8(vget_high_s16(u, vl), coeffs[2], vl / 2);
138+
139+
vint32m8_t v_lo = __riscv_vwmul_vx_i32m8(vget_low_s16(v), coeffs[3], vl / 2);
140+
vint32m8_t v_hi = __riscv_vwmul_vx_i32m8(vget_high_s16(v, vl), coeffs[3], vl / 2);
141+
142+
vint32m8_t lo = __riscv_vadd_vv_i32m8(u_lo, v_lo, vl / 2);
143+
vint32m8_t hi = __riscv_vadd_vv_i32m8(u_hi, v_hi, vl / 2);
144+
145+
vint16m4_t lo_shr = vqrshrn_n_s32(lo, 14, vl / 2);
146+
vint16m4_t hi_shr = vqrshrn_n_s32(hi, 14, vl / 2);
147+
148+
vint16m8_t u_output = vcombine_s16(lo_shr, hi_shr, vl);
149+
return u_output;
150+
}
151+
152+
static inline vint16m8_t vConversion_rvv(vint16m8_t u, vint16m8_t v, const int16_t* coeffs,
153+
size_t vl) {
154+
vint32m8_t u_lo = __riscv_vwmul_vx_i32m8(vget_low_s16(u), coeffs[4], vl / 2);
155+
vint32m8_t u_hi = __riscv_vwmul_vx_i32m8(vget_high_s16(u, vl), coeffs[4], vl / 2);
156+
157+
vint32m8_t v_lo = __riscv_vwmul_vx_i32m8(vget_low_s16(v), coeffs[5], vl / 2);
158+
vint32m8_t v_hi = __riscv_vwmul_vx_i32m8(vget_high_s16(v, vl), coeffs[5], vl / 2);
159+
160+
vint32m8_t lo = __riscv_vadd_vv_i32m8(u_lo, v_lo, vl / 2);
161+
vint32m8_t hi = __riscv_vadd_vv_i32m8(u_hi, v_hi, vl / 2);
162+
163+
vint16m4_t lo_shr = vqrshrn_n_s32(lo, 14, vl / 2);
164+
vint16m4_t hi_shr = vqrshrn_n_s32(hi, 14, vl / 2);
165+
166+
vint16m8_t v_output = vcombine_s16(lo_shr, hi_shr, vl);
167+
return v_output;
168+
}
169+
170+
static inline vuint8m4_t vqmovun_s16(vint16m8_t a, size_t vl) {
171+
vuint16m8_t a_non_neg = __riscv_vreinterpret_v_i16m8_u16m8(__riscv_vmax_vx_i16m8(a, 0, vl));
172+
return __riscv_vnclipu_wx_u8m4(a_non_neg, 0, vl);
173+
}
174+
175+
void transformYuv420_rvv(uhdr_raw_image_t* image, const int16_t* coeffs_ptr) {
176+
assert(image->w % 16 == 0);
177+
uint8_t* y0_ptr = static_cast<uint8_t*>(image->planes[UHDR_PLANE_Y]);
178+
uint8_t* y1_ptr = y0_ptr + image->stride[UHDR_PLANE_Y];
179+
uint8_t* u_ptr = static_cast<uint8_t*>(image->planes[UHDR_PLANE_U]);
180+
uint8_t* v_ptr = static_cast<uint8_t*>(image->planes[UHDR_PLANE_V]);
181+
size_t vl;
182+
size_t h = 0;
183+
do {
184+
size_t w = 0;
185+
do {
186+
vl = __riscv_vsetvl_e8m8((image->w) - w);
187+
assert((vl % 4) == 0 && vl > 4);
188+
189+
vuint8m8_t y0 = __riscv_vle8_v_u8m8(y0_ptr + w * 2, vl);
190+
vuint8m8_t y1 = __riscv_vle8_v_u8m8(y1_ptr + w * 2, vl);
191+
192+
vuint8m4_t u8 = __riscv_vle8_v_u8m4(u_ptr + w, vl / 2);
193+
vuint8m4_t v8 = __riscv_vle8_v_u8m4(v_ptr + w, vl / 2);
194+
195+
vuint16m8_t u16_wide = __riscv_vwsubu_vx_u16m8(u8, 128, vl / 2);
196+
vuint16m8_t v16_wide = __riscv_vwsubu_vx_u16m8(v8, 128, vl / 2);
197+
198+
vuint16m8_t uu_wide_lo = zip_self(__riscv_vget_v_u16m8_u16m4(u16_wide, 0), vl / 2);
199+
vuint16m8_t uu_wide_hi = zip_self(vget_high_u16(u16_wide, vl / 2), vl / 2);
200+
vuint16m8_t uv_wide_lo = zip_self(__riscv_vget_v_u16m8_u16m4(v16_wide, 0), vl / 2);
201+
vuint16m8_t uv_wide_hi = zip_self(vget_high_u16(v16_wide, vl / 2), vl / 2);
202+
203+
vint16m8_t u_wide_lo = __riscv_vreinterpret_v_u16m8_i16m8(uu_wide_lo);
204+
vint16m8_t v_wide_lo = __riscv_vreinterpret_v_u16m8_i16m8(uv_wide_lo);
205+
vint16m8_t u_wide_hi = __riscv_vreinterpret_v_u16m8_i16m8(uu_wide_hi);
206+
vint16m8_t v_wide_hi = __riscv_vreinterpret_v_u16m8_i16m8(uv_wide_hi);
207+
208+
vint16m8_t y0_lo = yConversion_rvv(vget_low_u8(y0), u_wide_lo, v_wide_lo, coeffs_ptr, vl / 2);
209+
vint16m8_t y1_lo = yConversion_rvv(vget_low_u8(y1), u_wide_lo, v_wide_lo, coeffs_ptr, vl / 2);
210+
vint16m8_t y0_hi =
211+
yConversion_rvv(vget_high_u8(y0, vl / 2), u_wide_hi, v_wide_hi, coeffs_ptr, vl / 2);
212+
vint16m8_t y1_hi =
213+
yConversion_rvv(vget_high_u8(y1, vl / 2), u_wide_hi, v_wide_hi, coeffs_ptr, vl / 2);
214+
215+
vint16m8_t u_wide_s16 = __riscv_vreinterpret_v_u16m8_i16m8(u16_wide);
216+
vint16m8_t v_wide_s16 = __riscv_vreinterpret_v_u16m8_i16m8(v16_wide);
217+
vint16m8_t new_u = uConversion_rvv(u_wide_s16, v_wide_s16, coeffs_ptr, vl / 2);
218+
vint16m8_t new_v = vConversion_rvv(u_wide_s16, v_wide_s16, coeffs_ptr, vl / 2);
219+
220+
vuint8m8_t y0_output =
221+
vcombine_u8(vqmovun_s16(y0_lo, vl / 2), vqmovun_s16(y0_hi, vl / 2), vl);
222+
vuint8m8_t y1_output =
223+
vcombine_u8(vqmovun_s16(y1_lo, vl / 2), vqmovun_s16(y1_hi, vl / 2), vl);
224+
vuint8m4_t u_output = vqmovun_s16(__riscv_vadd_vx_i16m8(new_u, 128, vl / 2), vl / 2);
225+
vuint8m4_t v_output = vqmovun_s16(__riscv_vadd_vx_i16m8(new_v, 128, vl / 2), vl / 2);
226+
227+
__riscv_vse8_v_u8m8(y0_ptr + w * 2, y0_output, vl);
228+
__riscv_vse8_v_u8m8(y1_ptr + w * 2, y1_output, vl);
229+
__riscv_vse8_v_u8m4(u_ptr + w, u_output, vl / 2);
230+
__riscv_vse8_v_u8m4(v_ptr + w, v_output, vl / 2);
231+
232+
w += (vl / 2);
233+
} while (w < image->w / 2);
234+
y0_ptr += image->stride[UHDR_PLANE_Y] * 2;
235+
y1_ptr += image->stride[UHDR_PLANE_Y] * 2;
236+
u_ptr += image->stride[UHDR_PLANE_U];
237+
v_ptr += image->stride[UHDR_PLANE_V];
238+
} while (++h < image->h / 2);
239+
}
240+
241+
uhdr_error_info_t convertYuv_rvv(uhdr_raw_image_t* image, uhdr_color_gamut_t src_encoding,
242+
uhdr_color_gamut_t dst_encoding) {
243+
uhdr_error_info_t status = g_no_error;
244+
const int16_t* coeffs = nullptr;
245+
246+
switch (src_encoding) {
247+
case UHDR_CG_BT_709:
248+
switch (dst_encoding) {
249+
case UHDR_CG_BT_709:
250+
return status;
251+
case UHDR_CG_DISPLAY_P3:
252+
coeffs = kYuv709To601_coeffs_rvv;
253+
break;
254+
case UHDR_CG_BT_2100:
255+
coeffs = kYuv709To2100_coeffs_rvv;
256+
break;
257+
default:
258+
status.error_code = UHDR_CODEC_INVALID_PARAM;
259+
status.has_detail = 1;
260+
snprintf(status.detail, sizeof status.detail, "Unrecognized dest color gamut %d",
261+
dst_encoding);
262+
return status;
263+
}
264+
break;
265+
case UHDR_CG_DISPLAY_P3:
266+
switch (dst_encoding) {
267+
case UHDR_CG_BT_709:
268+
coeffs = kYuv601To709_coeffs_rvv;
269+
break;
270+
case UHDR_CG_DISPLAY_P3:
271+
return status;
272+
case UHDR_CG_BT_2100:
273+
coeffs = kYuv601To2100_coeffs_rvv;
274+
break;
275+
default:
276+
status.error_code = UHDR_CODEC_INVALID_PARAM;
277+
status.has_detail = 1;
278+
snprintf(status.detail, sizeof status.detail, "Unrecognized dest color gamut %d",
279+
dst_encoding);
280+
return status;
281+
}
282+
break;
283+
case UHDR_CG_BT_2100:
284+
switch (dst_encoding) {
285+
case UHDR_CG_BT_709:
286+
coeffs = kYuv2100To709_coeffs_rvv;
287+
break;
288+
case UHDR_CG_DISPLAY_P3:
289+
coeffs = kYuv2100To601_coeffs_rvv;
290+
break;
291+
case UHDR_CG_BT_2100:
292+
return status;
293+
default:
294+
status.error_code = UHDR_CODEC_INVALID_PARAM;
295+
status.has_detail = 1;
296+
snprintf(status.detail, sizeof status.detail, "Unrecognized dest color gamut %d",
297+
dst_encoding);
298+
return status;
299+
}
300+
break;
301+
default:
302+
status.error_code = UHDR_CODEC_INVALID_PARAM;
303+
status.has_detail = 1;
304+
snprintf(status.detail, sizeof status.detail, "Unrecognized src color gamut %d",
305+
src_encoding);
306+
return status;
307+
}
308+
309+
if (image->fmt == UHDR_IMG_FMT_12bppYCbCr420) {
310+
transformYuv420_rvv(image, coeffs);
311+
} else {
312+
status.error_code = UHDR_CODEC_UNSUPPORTED_FEATURE;
313+
status.has_detail = 1;
314+
snprintf(status.detail, sizeof status.detail,
315+
"No implementation available for performing gamut conversion for color format %d",
316+
image->fmt);
317+
return status;
318+
}
319+
320+
return status;
321+
}
322+
} // namespace ultrahdr

lib/src/jpegr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ uhdr_error_info_t JpegR::encodeJPEGR(uhdr_raw_image_t* hdr_intent, uhdr_raw_imag
264264
// convert to bt601 YUV encoding for JPEG encode
265265
#if (defined(UHDR_ENABLE_INTRINSICS) && (defined(__ARM_NEON__) || defined(__ARM_NEON)))
266266
UHDR_ERR_CHECK(convertYuv_neon(sdr_intent_yuv, sdr_intent_yuv->cg, UHDR_CG_DISPLAY_P3));
267+
#elif (defined(UHDR_ENABLE_INTRINSICS) && defined(__riscv_v_intrinsic))
268+
UHDR_ERR_CHECK(convertYuv_rvv(sdr_intent_yuv, sdr_intent_yuv->cg, UHDR_CG_DISPLAY_P3));
267269
#else
268270
UHDR_ERR_CHECK(convertYuv(sdr_intent_yuv, sdr_intent_yuv->cg, UHDR_CG_DISPLAY_P3));
269271
#endif

0 commit comments

Comments
 (0)