1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2015 -2017 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include "libavutil/mips/generic_macros_msa.h" 22cabdff1aSopenharmony_ci#include "libavcodec/mips/hevcdsp_mips.h" 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_cistatic void hevc_loopfilter_luma_hor_msa(uint8_t *src, int32_t stride, 25cabdff1aSopenharmony_ci int32_t beta, int32_t *tc, 26cabdff1aSopenharmony_ci uint8_t *p_is_pcm, uint8_t *q_is_pcm) 27cabdff1aSopenharmony_ci{ 28cabdff1aSopenharmony_ci uint8_t *p3 = src - (stride << 2); 29cabdff1aSopenharmony_ci uint8_t *p2 = src - ((stride << 1) + stride); 30cabdff1aSopenharmony_ci uint8_t *p1 = src - (stride << 1); 31cabdff1aSopenharmony_ci uint8_t *p0 = src - stride; 32cabdff1aSopenharmony_ci uint8_t *q0 = src; 33cabdff1aSopenharmony_ci uint8_t *q1 = src + stride; 34cabdff1aSopenharmony_ci uint8_t *q2 = src + (stride << 1); 35cabdff1aSopenharmony_ci uint8_t *q3 = src + (stride << 1) + stride; 36cabdff1aSopenharmony_ci uint8_t flag0, flag1; 37cabdff1aSopenharmony_ci int32_t dp00, dq00, dp30, dq30, d00, d30; 38cabdff1aSopenharmony_ci int32_t d0030, d0434; 39cabdff1aSopenharmony_ci int32_t dp04, dq04, dp34, dq34, d04, d34; 40cabdff1aSopenharmony_ci int32_t tc0, p_is_pcm0, q_is_pcm0, beta30, beta20, tc250; 41cabdff1aSopenharmony_ci int32_t tc4, p_is_pcm4, q_is_pcm4, tc254, tmp; 42cabdff1aSopenharmony_ci uint64_t dst_val0, dst_val1; 43cabdff1aSopenharmony_ci v16u8 dst0, dst1, dst2, dst3, dst4, dst5; 44cabdff1aSopenharmony_ci v2i64 cmp0, cmp1, cmp2, p_is_pcm_vec, q_is_pcm_vec; 45cabdff1aSopenharmony_ci v2i64 cmp3; 46cabdff1aSopenharmony_ci v8u16 temp0, temp1; 47cabdff1aSopenharmony_ci v8i16 temp2; 48cabdff1aSopenharmony_ci v8i16 tc_pos, tc_neg; 49cabdff1aSopenharmony_ci v8i16 diff0, diff1, delta0, delta1, delta2, abs_delta0; 50cabdff1aSopenharmony_ci v16i8 zero = { 0 }; 51cabdff1aSopenharmony_ci v8u16 p3_src, p2_src, p1_src, p0_src, q0_src, q1_src, q2_src, q3_src; 52cabdff1aSopenharmony_ci 53cabdff1aSopenharmony_ci dp00 = abs(p2[0] - (p1[0] << 1) + p0[0]); 54cabdff1aSopenharmony_ci dq00 = abs(q2[0] - (q1[0] << 1) + q0[0]); 55cabdff1aSopenharmony_ci dp30 = abs(p2[3] - (p1[3] << 1) + p0[3]); 56cabdff1aSopenharmony_ci dq30 = abs(q2[3] - (q1[3] << 1) + q0[3]); 57cabdff1aSopenharmony_ci d00 = dp00 + dq00; 58cabdff1aSopenharmony_ci d30 = dp30 + dq30; 59cabdff1aSopenharmony_ci dp04 = abs(p2[4] - (p1[4] << 1) + p0[4]); 60cabdff1aSopenharmony_ci dq04 = abs(q2[4] - (q1[4] << 1) + q0[4]); 61cabdff1aSopenharmony_ci dp34 = abs(p2[7] - (p1[7] << 1) + p0[7]); 62cabdff1aSopenharmony_ci dq34 = abs(q2[7] - (q1[7] << 1) + q0[7]); 63cabdff1aSopenharmony_ci d04 = dp04 + dq04; 64cabdff1aSopenharmony_ci d34 = dp34 + dq34; 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_ci p_is_pcm0 = p_is_pcm[0]; 67cabdff1aSopenharmony_ci p_is_pcm4 = p_is_pcm[1]; 68cabdff1aSopenharmony_ci q_is_pcm0 = q_is_pcm[0]; 69cabdff1aSopenharmony_ci q_is_pcm4 = q_is_pcm[1]; 70cabdff1aSopenharmony_ci 71cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(p_is_pcm0); 72cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(p_is_pcm4); 73cabdff1aSopenharmony_ci p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); 74cabdff1aSopenharmony_ci p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0); 75cabdff1aSopenharmony_ci 76cabdff1aSopenharmony_ci d0030 = (d00 + d30) >= beta; 77cabdff1aSopenharmony_ci d0434 = (d04 + d34) >= beta; 78cabdff1aSopenharmony_ci 79cabdff1aSopenharmony_ci cmp0 = (v2i64) __msa_fill_w(d0030); 80cabdff1aSopenharmony_ci cmp1 = (v2i64) __msa_fill_w(d0434); 81cabdff1aSopenharmony_ci cmp3 = (v2i64) __msa_ilvev_w((v4i32) cmp1, (v4i32) cmp0); 82cabdff1aSopenharmony_ci cmp3 = (v2i64) __msa_ceqi_w((v4i32) cmp3, 0); 83cabdff1aSopenharmony_ci 84cabdff1aSopenharmony_ci if ((!p_is_pcm0 || !p_is_pcm4 || !q_is_pcm0 || !q_is_pcm4) && 85cabdff1aSopenharmony_ci (!d0030 || !d0434)) { 86cabdff1aSopenharmony_ci p3_src = LD_UH(p3); 87cabdff1aSopenharmony_ci p2_src = LD_UH(p2); 88cabdff1aSopenharmony_ci p1_src = LD_UH(p1); 89cabdff1aSopenharmony_ci p0_src = LD_UH(p0); 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(q_is_pcm0); 92cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(q_is_pcm4); 93cabdff1aSopenharmony_ci q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); 94cabdff1aSopenharmony_ci q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0); 95cabdff1aSopenharmony_ci 96cabdff1aSopenharmony_ci tc0 = tc[0]; 97cabdff1aSopenharmony_ci beta30 = beta >> 3; 98cabdff1aSopenharmony_ci beta20 = beta >> 2; 99cabdff1aSopenharmony_ci tc250 = ((tc0 * 5 + 1) >> 1); 100cabdff1aSopenharmony_ci tc4 = tc[1]; 101cabdff1aSopenharmony_ci tc254 = ((tc4 * 5 + 1) >> 1); 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci cmp0 = (v2i64) __msa_fill_h(tc0); 104cabdff1aSopenharmony_ci cmp1 = (v2i64) __msa_fill_h(tc4); 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_ci ILVR_B4_UH(zero, p3_src, zero, p2_src, zero, p1_src, zero, p0_src, 107cabdff1aSopenharmony_ci p3_src, p2_src, p1_src, p0_src); 108cabdff1aSopenharmony_ci q0_src = LD_UH(q0); 109cabdff1aSopenharmony_ci q1_src = LD_UH(q1); 110cabdff1aSopenharmony_ci q2_src = LD_UH(q2); 111cabdff1aSopenharmony_ci q3_src = LD_UH(q3); 112cabdff1aSopenharmony_ci 113cabdff1aSopenharmony_ci flag0 = abs(p3[0] - p0[0]) + abs(q3[0] - q0[0]) < beta30 && 114cabdff1aSopenharmony_ci abs(p0[0] - q0[0]) < tc250; 115cabdff1aSopenharmony_ci flag0 = flag0 && (abs(p3[3] - p0[3]) + abs(q3[3] - q0[3]) < beta30 && 116cabdff1aSopenharmony_ci abs(p0[3] - q0[3]) < tc250 && (d00 << 1) < beta20 && 117cabdff1aSopenharmony_ci (d30 << 1) < beta20); 118cabdff1aSopenharmony_ci 119cabdff1aSopenharmony_ci tc_pos = (v8i16) __msa_ilvev_d(cmp1, cmp0); 120cabdff1aSopenharmony_ci ILVR_B4_UH(zero, q0_src, zero, q1_src, zero, q2_src, zero, q3_src, 121cabdff1aSopenharmony_ci q0_src, q1_src, q2_src, q3_src); 122cabdff1aSopenharmony_ci flag1 = abs(p3[4] - p0[4]) + abs(q3[4] - q0[4]) < beta30 && 123cabdff1aSopenharmony_ci abs(p0[4] - q0[4]) < tc254; 124cabdff1aSopenharmony_ci flag1 = flag1 && (abs(p3[7] - p0[7]) + abs(q3[7] - q0[7]) < beta30 && 125cabdff1aSopenharmony_ci abs(p0[7] - q0[7]) < tc254 && (d04 << 1) < beta20 && 126cabdff1aSopenharmony_ci (d34 << 1) < beta20); 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci cmp0 = (v2i64) __msa_fill_w(flag0); 129cabdff1aSopenharmony_ci cmp1 = (v2i64) __msa_fill_w(flag1); 130cabdff1aSopenharmony_ci cmp2 = (v2i64) __msa_ilvev_w((v4i32) cmp1, (v4i32) cmp0); 131cabdff1aSopenharmony_ci cmp2 = (v2i64) __msa_ceqi_w((v4i32) cmp2, 0); 132cabdff1aSopenharmony_ci 133cabdff1aSopenharmony_ci if (flag0 && flag1) { /* strong only */ 134cabdff1aSopenharmony_ci /* strong filter */ 135cabdff1aSopenharmony_ci tc_pos <<= 1; 136cabdff1aSopenharmony_ci tc_neg = -tc_pos; 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ci /* p part */ 139cabdff1aSopenharmony_ci temp0 = (p1_src + p0_src + q0_src); 140cabdff1aSopenharmony_ci temp1 = ((p3_src + p2_src) << 1) + p2_src + temp0; 141cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 142cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - p2_src); 143cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 144cabdff1aSopenharmony_ci dst0 = (v16u8) (temp2 + (v8i16) p2_src); 145cabdff1aSopenharmony_ci 146cabdff1aSopenharmony_ci temp1 = temp0 + p2_src; 147cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2); 148cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - p1_src); 149cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 150cabdff1aSopenharmony_ci dst1 = (v16u8) (temp2 + (v8i16) p1_src); 151cabdff1aSopenharmony_ci 152cabdff1aSopenharmony_ci temp1 = (temp0 << 1) + p2_src + q1_src; 153cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 154cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - p0_src); 155cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 156cabdff1aSopenharmony_ci dst2 = (v16u8) (temp2 + (v8i16) p0_src); 157cabdff1aSopenharmony_ci 158cabdff1aSopenharmony_ci dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) p_is_pcm_vec); 159cabdff1aSopenharmony_ci dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) p_is_pcm_vec); 160cabdff1aSopenharmony_ci dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) p_is_pcm_vec); 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci /* q part */ 163cabdff1aSopenharmony_ci temp0 = (q1_src + p0_src + q0_src); 164cabdff1aSopenharmony_ci 165cabdff1aSopenharmony_ci temp1 = ((q3_src + q2_src) << 1) + q2_src + temp0; 166cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 167cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - q2_src); 168cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 169cabdff1aSopenharmony_ci dst5 = (v16u8) (temp2 + (v8i16) q2_src); 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci temp1 = temp0 + q2_src; 172cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2); 173cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - q1_src); 174cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 175cabdff1aSopenharmony_ci dst4 = (v16u8) (temp2 + (v8i16) q1_src); 176cabdff1aSopenharmony_ci 177cabdff1aSopenharmony_ci temp1 = (temp0 << 1) + p1_src + q2_src; 178cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 179cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - q0_src); 180cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 181cabdff1aSopenharmony_ci dst3 = (v16u8) (temp2 + (v8i16) q0_src); 182cabdff1aSopenharmony_ci 183cabdff1aSopenharmony_ci dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) q_is_pcm_vec); 184cabdff1aSopenharmony_ci dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) q_is_pcm_vec); 185cabdff1aSopenharmony_ci dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) q_is_pcm_vec); 186cabdff1aSopenharmony_ci 187cabdff1aSopenharmony_ci /* pack results to 8 bit */ 188cabdff1aSopenharmony_ci PCKEV_B2_UB(dst1, dst0, dst3, dst2, dst0, dst1); 189cabdff1aSopenharmony_ci dst2 = (v16u8) __msa_pckev_b((v16i8) dst5, (v16i8) dst4); 190cabdff1aSopenharmony_ci 191cabdff1aSopenharmony_ci /* pack src to 8 bit */ 192cabdff1aSopenharmony_ci PCKEV_B2_UB(p1_src, p2_src, q0_src, p0_src, dst3, dst4); 193cabdff1aSopenharmony_ci dst5 = (v16u8) __msa_pckev_b((v16i8) q2_src, (v16i8) q1_src); 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_ci dst0 = __msa_bmz_v(dst0, dst3, (v16u8) cmp3); 196cabdff1aSopenharmony_ci dst1 = __msa_bmz_v(dst1, dst4, (v16u8) cmp3); 197cabdff1aSopenharmony_ci dst2 = __msa_bmz_v(dst2, dst5, (v16u8) cmp3); 198cabdff1aSopenharmony_ci 199cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_d((v2i64) dst2, 0); 200cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_d((v2i64) dst2, 1); 201cabdff1aSopenharmony_ci 202cabdff1aSopenharmony_ci ST_D4(dst0, dst1, 0, 1, 0, 1, p2, stride); 203cabdff1aSopenharmony_ci SD(dst_val0, p2 + 4 * stride); 204cabdff1aSopenharmony_ci SD(dst_val1, p2 + 5 * stride); 205cabdff1aSopenharmony_ci /* strong filter ends */ 206cabdff1aSopenharmony_ci } else if (flag0 == flag1) { /* weak only */ 207cabdff1aSopenharmony_ci /* weak filter */ 208cabdff1aSopenharmony_ci tc_neg = -tc_pos; 209cabdff1aSopenharmony_ci 210cabdff1aSopenharmony_ci diff0 = (v8i16) (q0_src - p0_src); 211cabdff1aSopenharmony_ci diff1 = (v8i16) (q1_src - p1_src); 212cabdff1aSopenharmony_ci diff0 = (diff0 << 3) + diff0; 213cabdff1aSopenharmony_ci diff1 = (diff1 << 1) + diff1; 214cabdff1aSopenharmony_ci delta0 = diff0 - diff1; 215cabdff1aSopenharmony_ci delta0 = __msa_srari_h(delta0, 4); 216cabdff1aSopenharmony_ci 217cabdff1aSopenharmony_ci temp1 = (v8u16) ((tc_pos << 3) + (tc_pos << 1)); 218cabdff1aSopenharmony_ci abs_delta0 = __msa_add_a_h(delta0, (v8i16) zero); 219cabdff1aSopenharmony_ci abs_delta0 = (v8u16) abs_delta0 < temp1; 220cabdff1aSopenharmony_ci 221cabdff1aSopenharmony_ci CLIP_SH(delta0, tc_neg, tc_pos); 222cabdff1aSopenharmony_ci 223cabdff1aSopenharmony_ci temp2 = (v8i16) (delta0 + p0_src); 224cabdff1aSopenharmony_ci CLIP_SH_0_255(temp2); 225cabdff1aSopenharmony_ci temp0 = (v8u16) __msa_bmz_v((v16u8) temp2, (v16u8) p0_src, 226cabdff1aSopenharmony_ci (v16u8) p_is_pcm_vec); 227cabdff1aSopenharmony_ci 228cabdff1aSopenharmony_ci temp2 = (v8i16) (q0_src - delta0); 229cabdff1aSopenharmony_ci CLIP_SH_0_255(temp2); 230cabdff1aSopenharmony_ci temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, 231cabdff1aSopenharmony_ci (v16u8) q_is_pcm_vec); 232cabdff1aSopenharmony_ci 233cabdff1aSopenharmony_ci p_is_pcm_vec = ~p_is_pcm_vec; 234cabdff1aSopenharmony_ci q_is_pcm_vec = ~q_is_pcm_vec; 235cabdff1aSopenharmony_ci tmp = (beta + (beta >> 1)) >> 3; 236cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(dp00 + dp30 < tmp); 237cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(dp04 + dp34 < tmp); 238cabdff1aSopenharmony_ci cmp0 = __msa_ilvev_d(cmp1, cmp0); 239cabdff1aSopenharmony_ci cmp0 = __msa_ceqi_d(cmp0, 0); 240cabdff1aSopenharmony_ci p_is_pcm_vec = p_is_pcm_vec | cmp0; 241cabdff1aSopenharmony_ci 242cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(dq00 + dq30 < tmp); 243cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(dq04 + dq34 < tmp); 244cabdff1aSopenharmony_ci cmp0 = __msa_ilvev_d(cmp1, cmp0); 245cabdff1aSopenharmony_ci cmp0 = __msa_ceqi_d(cmp0, 0); 246cabdff1aSopenharmony_ci q_is_pcm_vec = q_is_pcm_vec | cmp0; 247cabdff1aSopenharmony_ci 248cabdff1aSopenharmony_ci tc_pos >>= 1; 249cabdff1aSopenharmony_ci tc_neg = -tc_pos; 250cabdff1aSopenharmony_ci 251cabdff1aSopenharmony_ci delta1 = (v8i16) __msa_aver_u_h(p2_src, p0_src); 252cabdff1aSopenharmony_ci delta1 -= (v8i16) p1_src; 253cabdff1aSopenharmony_ci delta1 += delta0; 254cabdff1aSopenharmony_ci delta1 >>= 1; 255cabdff1aSopenharmony_ci CLIP_SH(delta1, tc_neg, tc_pos); 256cabdff1aSopenharmony_ci delta1 = (v8i16) p1_src + (v8i16) delta1; 257cabdff1aSopenharmony_ci CLIP_SH_0_255(delta1); 258cabdff1aSopenharmony_ci delta1 = (v8i16) __msa_bmnz_v((v16u8) delta1, (v16u8) p1_src, 259cabdff1aSopenharmony_ci (v16u8) p_is_pcm_vec); 260cabdff1aSopenharmony_ci 261cabdff1aSopenharmony_ci delta2 = (v8i16) __msa_aver_u_h(q0_src, q2_src); 262cabdff1aSopenharmony_ci delta2 = delta2 - (v8i16) q1_src; 263cabdff1aSopenharmony_ci delta2 = delta2 - delta0; 264cabdff1aSopenharmony_ci delta2 = delta2 >> 1; 265cabdff1aSopenharmony_ci CLIP_SH(delta2, tc_neg, tc_pos); 266cabdff1aSopenharmony_ci delta2 = (v8i16) q1_src + (v8i16) delta2; 267cabdff1aSopenharmony_ci CLIP_SH_0_255(delta2); 268cabdff1aSopenharmony_ci delta2 = (v8i16) __msa_bmnz_v((v16u8) delta2, (v16u8) q1_src, 269cabdff1aSopenharmony_ci (v16u8) q_is_pcm_vec); 270cabdff1aSopenharmony_ci 271cabdff1aSopenharmony_ci dst1 = (v16u8) __msa_bmz_v((v16u8) delta1, (v16u8) p1_src, 272cabdff1aSopenharmony_ci (v16u8) abs_delta0); 273cabdff1aSopenharmony_ci dst2 = (v16u8) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src, 274cabdff1aSopenharmony_ci (v16u8) abs_delta0); 275cabdff1aSopenharmony_ci dst3 = (v16u8) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, 276cabdff1aSopenharmony_ci (v16u8) abs_delta0); 277cabdff1aSopenharmony_ci dst4 = (v16u8) __msa_bmz_v((v16u8) delta2, (v16u8) q1_src, 278cabdff1aSopenharmony_ci (v16u8) abs_delta0); 279cabdff1aSopenharmony_ci /* pack results to 8 bit */ 280cabdff1aSopenharmony_ci PCKEV_B2_UB(dst2, dst1, dst4, dst3, dst0, dst1); 281cabdff1aSopenharmony_ci 282cabdff1aSopenharmony_ci /* pack src to 8 bit */ 283cabdff1aSopenharmony_ci PCKEV_B2_UB(p0_src, p1_src, q1_src, q0_src, dst2, dst3); 284cabdff1aSopenharmony_ci 285cabdff1aSopenharmony_ci dst0 = __msa_bmz_v(dst0, dst2, (v16u8) cmp3); 286cabdff1aSopenharmony_ci dst1 = __msa_bmz_v(dst1, dst3, (v16u8) cmp3); 287cabdff1aSopenharmony_ci 288cabdff1aSopenharmony_ci p2 += stride; 289cabdff1aSopenharmony_ci ST_D4(dst0, dst1, 0, 1, 0, 1, p2, stride); 290cabdff1aSopenharmony_ci /* weak filter ends */ 291cabdff1aSopenharmony_ci } else { /* strong + weak */ 292cabdff1aSopenharmony_ci /* strong filter */ 293cabdff1aSopenharmony_ci tc_pos <<= 1; 294cabdff1aSopenharmony_ci tc_neg = -tc_pos; 295cabdff1aSopenharmony_ci 296cabdff1aSopenharmony_ci /* p part */ 297cabdff1aSopenharmony_ci temp0 = (p1_src + p0_src + q0_src); 298cabdff1aSopenharmony_ci temp1 = ((p3_src + p2_src) << 1) + p2_src + temp0; 299cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 300cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - p2_src); 301cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 302cabdff1aSopenharmony_ci dst0 = (v16u8) (temp2 + (v8i16) p2_src); 303cabdff1aSopenharmony_ci 304cabdff1aSopenharmony_ci temp1 = temp0 + p2_src; 305cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2); 306cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - p1_src); 307cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 308cabdff1aSopenharmony_ci dst1 = (v16u8) (temp2 + (v8i16) p1_src); 309cabdff1aSopenharmony_ci 310cabdff1aSopenharmony_ci temp1 = (temp0 << 1) + p2_src + q1_src; 311cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 312cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - p0_src); 313cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 314cabdff1aSopenharmony_ci dst2 = (v16u8) (temp2 + (v8i16) p0_src); 315cabdff1aSopenharmony_ci 316cabdff1aSopenharmony_ci dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) p_is_pcm_vec); 317cabdff1aSopenharmony_ci dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) p_is_pcm_vec); 318cabdff1aSopenharmony_ci dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) p_is_pcm_vec); 319cabdff1aSopenharmony_ci 320cabdff1aSopenharmony_ci /* q part */ 321cabdff1aSopenharmony_ci temp0 = (q1_src + p0_src + q0_src); 322cabdff1aSopenharmony_ci 323cabdff1aSopenharmony_ci temp1 = ((q3_src + q2_src) << 1) + q2_src + temp0; 324cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 325cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - q2_src); 326cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 327cabdff1aSopenharmony_ci dst5 = (v16u8) (temp2 + (v8i16) q2_src); 328cabdff1aSopenharmony_ci 329cabdff1aSopenharmony_ci temp1 = temp0 + q2_src; 330cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2); 331cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - q1_src); 332cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 333cabdff1aSopenharmony_ci dst4 = (v16u8) (temp2 + (v8i16) q1_src); 334cabdff1aSopenharmony_ci 335cabdff1aSopenharmony_ci temp1 = (temp0 << 1) + p1_src + q2_src; 336cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 337cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - q0_src); 338cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 339cabdff1aSopenharmony_ci dst3 = (v16u8) (temp2 + (v8i16) q0_src); 340cabdff1aSopenharmony_ci 341cabdff1aSopenharmony_ci dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) q_is_pcm_vec); 342cabdff1aSopenharmony_ci dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) q_is_pcm_vec); 343cabdff1aSopenharmony_ci dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) q_is_pcm_vec); 344cabdff1aSopenharmony_ci 345cabdff1aSopenharmony_ci /* pack strong results to 8 bit */ 346cabdff1aSopenharmony_ci PCKEV_B2_UB(dst1, dst0, dst3, dst2, dst0, dst1); 347cabdff1aSopenharmony_ci dst2 = (v16u8) __msa_pckev_b((v16i8) dst5, (v16i8) dst4); 348cabdff1aSopenharmony_ci /* strong filter ends */ 349cabdff1aSopenharmony_ci 350cabdff1aSopenharmony_ci /* weak filter */ 351cabdff1aSopenharmony_ci tc_pos >>= 1; 352cabdff1aSopenharmony_ci tc_neg = -tc_pos; 353cabdff1aSopenharmony_ci 354cabdff1aSopenharmony_ci diff0 = (v8i16) (q0_src - p0_src); 355cabdff1aSopenharmony_ci diff1 = (v8i16) (q1_src - p1_src); 356cabdff1aSopenharmony_ci diff0 = (diff0 << 3) + diff0; 357cabdff1aSopenharmony_ci diff1 = (diff1 << 1) + diff1; 358cabdff1aSopenharmony_ci delta0 = diff0 - diff1; 359cabdff1aSopenharmony_ci delta0 = __msa_srari_h(delta0, 4); 360cabdff1aSopenharmony_ci 361cabdff1aSopenharmony_ci temp1 = (v8u16) ((tc_pos << 3) + (tc_pos << 1)); 362cabdff1aSopenharmony_ci abs_delta0 = __msa_add_a_h(delta0, (v8i16) zero); 363cabdff1aSopenharmony_ci abs_delta0 = (v8u16) abs_delta0 < temp1; 364cabdff1aSopenharmony_ci 365cabdff1aSopenharmony_ci CLIP_SH(delta0, tc_neg, tc_pos); 366cabdff1aSopenharmony_ci 367cabdff1aSopenharmony_ci temp2 = (v8i16) (delta0 + p0_src); 368cabdff1aSopenharmony_ci CLIP_SH_0_255(temp2); 369cabdff1aSopenharmony_ci temp0 = (v8u16) __msa_bmz_v((v16u8) temp2, (v16u8) p0_src, 370cabdff1aSopenharmony_ci (v16u8) p_is_pcm_vec); 371cabdff1aSopenharmony_ci 372cabdff1aSopenharmony_ci temp2 = (v8i16) (q0_src - delta0); 373cabdff1aSopenharmony_ci CLIP_SH_0_255(temp2); 374cabdff1aSopenharmony_ci temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, 375cabdff1aSopenharmony_ci (v16u8) q_is_pcm_vec); 376cabdff1aSopenharmony_ci 377cabdff1aSopenharmony_ci p_is_pcm_vec = ~p_is_pcm_vec; 378cabdff1aSopenharmony_ci q_is_pcm_vec = ~q_is_pcm_vec; 379cabdff1aSopenharmony_ci tmp = (beta + (beta >> 1)) >> 3; 380cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(dp00 + dp30 < tmp); 381cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(dp04 + dp34 < tmp); 382cabdff1aSopenharmony_ci cmp0 = __msa_ilvev_d(cmp1, cmp0); 383cabdff1aSopenharmony_ci p_is_pcm_vec = p_is_pcm_vec | __msa_ceqi_d(cmp0, 0); 384cabdff1aSopenharmony_ci 385cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(dq00 + dq30 < tmp); 386cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(dq04 + dq34 < tmp); 387cabdff1aSopenharmony_ci cmp0 = __msa_ilvev_d(cmp1, cmp0); 388cabdff1aSopenharmony_ci q_is_pcm_vec = q_is_pcm_vec | __msa_ceqi_d(cmp0, 0); 389cabdff1aSopenharmony_ci 390cabdff1aSopenharmony_ci tc_pos >>= 1; 391cabdff1aSopenharmony_ci tc_neg = -tc_pos; 392cabdff1aSopenharmony_ci 393cabdff1aSopenharmony_ci delta1 = (v8i16) __msa_aver_u_h(p2_src, p0_src); 394cabdff1aSopenharmony_ci delta1 -= (v8i16) p1_src; 395cabdff1aSopenharmony_ci delta1 += delta0; 396cabdff1aSopenharmony_ci delta1 >>= 1; 397cabdff1aSopenharmony_ci CLIP_SH(delta1, tc_neg, tc_pos); 398cabdff1aSopenharmony_ci delta1 = (v8i16) p1_src + (v8i16) delta1; 399cabdff1aSopenharmony_ci CLIP_SH_0_255(delta1); 400cabdff1aSopenharmony_ci delta1 = (v8i16) __msa_bmnz_v((v16u8) delta1, (v16u8) p1_src, 401cabdff1aSopenharmony_ci (v16u8) p_is_pcm_vec); 402cabdff1aSopenharmony_ci 403cabdff1aSopenharmony_ci delta2 = (v8i16) __msa_aver_u_h(q0_src, q2_src); 404cabdff1aSopenharmony_ci delta2 = delta2 - (v8i16) q1_src; 405cabdff1aSopenharmony_ci delta2 = delta2 - delta0; 406cabdff1aSopenharmony_ci delta2 = delta2 >> 1; 407cabdff1aSopenharmony_ci CLIP_SH(delta2, tc_neg, tc_pos); 408cabdff1aSopenharmony_ci delta2 = (v8i16) q1_src + (v8i16) delta2; 409cabdff1aSopenharmony_ci CLIP_SH_0_255(delta2); 410cabdff1aSopenharmony_ci delta2 = (v8i16) __msa_bmnz_v((v16u8) delta2, (v16u8) q1_src, 411cabdff1aSopenharmony_ci (v16u8) q_is_pcm_vec); 412cabdff1aSopenharmony_ci 413cabdff1aSopenharmony_ci delta1 = (v8i16) __msa_bmz_v((v16u8) delta1, (v16u8) p1_src, 414cabdff1aSopenharmony_ci (v16u8) abs_delta0); 415cabdff1aSopenharmony_ci temp0 = (v8u16) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src, 416cabdff1aSopenharmony_ci (v16u8) abs_delta0); 417cabdff1aSopenharmony_ci temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, 418cabdff1aSopenharmony_ci (v16u8) abs_delta0); 419cabdff1aSopenharmony_ci delta2 = (v8i16) __msa_bmz_v((v16u8) delta2, (v16u8) q1_src, 420cabdff1aSopenharmony_ci (v16u8) abs_delta0); 421cabdff1aSopenharmony_ci /* weak filter ends */ 422cabdff1aSopenharmony_ci 423cabdff1aSopenharmony_ci /* pack weak results to 8 bit */ 424cabdff1aSopenharmony_ci PCKEV_B2_UB(delta1, p2_src, temp2, temp0, dst3, dst4); 425cabdff1aSopenharmony_ci dst5 = (v16u8) __msa_pckev_b((v16i8) q2_src, (v16i8) delta2); 426cabdff1aSopenharmony_ci 427cabdff1aSopenharmony_ci /* select between weak or strong */ 428cabdff1aSopenharmony_ci dst0 = __msa_bmnz_v(dst0, dst3, (v16u8) cmp2); 429cabdff1aSopenharmony_ci dst1 = __msa_bmnz_v(dst1, dst4, (v16u8) cmp2); 430cabdff1aSopenharmony_ci dst2 = __msa_bmnz_v(dst2, dst5, (v16u8) cmp2); 431cabdff1aSopenharmony_ci 432cabdff1aSopenharmony_ci /* pack src to 8 bit */ 433cabdff1aSopenharmony_ci PCKEV_B2_UB(p1_src, p2_src, q0_src, p0_src, dst3, dst4); 434cabdff1aSopenharmony_ci dst5 = (v16u8) __msa_pckev_b((v16i8) q2_src, (v16i8) q1_src); 435cabdff1aSopenharmony_ci 436cabdff1aSopenharmony_ci dst0 = __msa_bmz_v(dst0, dst3, (v16u8) cmp3); 437cabdff1aSopenharmony_ci dst1 = __msa_bmz_v(dst1, dst4, (v16u8) cmp3); 438cabdff1aSopenharmony_ci dst2 = __msa_bmz_v(dst2, dst5, (v16u8) cmp3); 439cabdff1aSopenharmony_ci 440cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_d((v2i64) dst2, 0); 441cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_d((v2i64) dst2, 1); 442cabdff1aSopenharmony_ci 443cabdff1aSopenharmony_ci ST_D4(dst0, dst1, 0, 1, 0, 1, p2, stride); 444cabdff1aSopenharmony_ci SD(dst_val0, p2 + 4 * stride); 445cabdff1aSopenharmony_ci SD(dst_val1, p2 + 5 * stride); 446cabdff1aSopenharmony_ci } 447cabdff1aSopenharmony_ci } 448cabdff1aSopenharmony_ci} 449cabdff1aSopenharmony_ci 450cabdff1aSopenharmony_cistatic void hevc_loopfilter_luma_ver_msa(uint8_t *src, int32_t stride, 451cabdff1aSopenharmony_ci int32_t beta, int32_t *tc, 452cabdff1aSopenharmony_ci uint8_t *p_is_pcm, uint8_t *q_is_pcm) 453cabdff1aSopenharmony_ci{ 454cabdff1aSopenharmony_ci uint8_t *p3 = src; 455cabdff1aSopenharmony_ci uint8_t *p2 = src + 3 * stride; 456cabdff1aSopenharmony_ci uint8_t *p1 = src + (stride << 2); 457cabdff1aSopenharmony_ci uint8_t *p0 = src + 7 * stride; 458cabdff1aSopenharmony_ci uint8_t flag0, flag1; 459cabdff1aSopenharmony_ci uint16_t tmp0, tmp1; 460cabdff1aSopenharmony_ci uint32_t tmp2, tmp3; 461cabdff1aSopenharmony_ci int32_t dp00, dq00, dp30, dq30, d00, d30; 462cabdff1aSopenharmony_ci int32_t d0030, d0434; 463cabdff1aSopenharmony_ci int32_t dp04, dq04, dp34, dq34, d04, d34; 464cabdff1aSopenharmony_ci int32_t tc0, p_is_pcm0, q_is_pcm0, beta30, beta20, tc250; 465cabdff1aSopenharmony_ci int32_t tc4, p_is_pcm4, q_is_pcm4, tc254, tmp; 466cabdff1aSopenharmony_ci v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; 467cabdff1aSopenharmony_ci v2i64 cmp0, cmp1, cmp2, p_is_pcm_vec, q_is_pcm_vec; 468cabdff1aSopenharmony_ci v2i64 cmp3; 469cabdff1aSopenharmony_ci v8u16 temp0, temp1; 470cabdff1aSopenharmony_ci v8i16 temp2; 471cabdff1aSopenharmony_ci v8i16 tc_pos, tc_neg; 472cabdff1aSopenharmony_ci v8i16 diff0, diff1, delta0, delta1, delta2, abs_delta0; 473cabdff1aSopenharmony_ci v16i8 zero = { 0 }; 474cabdff1aSopenharmony_ci v8u16 p3_src, p2_src, p1_src, p0_src, q0_src, q1_src, q2_src, q3_src; 475cabdff1aSopenharmony_ci 476cabdff1aSopenharmony_ci dp00 = abs(p3[-3] - (p3[-2] << 1) + p3[-1]); 477cabdff1aSopenharmony_ci dq00 = abs(p3[2] - (p3[1] << 1) + p3[0]); 478cabdff1aSopenharmony_ci dp30 = abs(p2[-3] - (p2[-2] << 1) + p2[-1]); 479cabdff1aSopenharmony_ci dq30 = abs(p2[2] - (p2[1] << 1) + p2[0]); 480cabdff1aSopenharmony_ci d00 = dp00 + dq00; 481cabdff1aSopenharmony_ci d30 = dp30 + dq30; 482cabdff1aSopenharmony_ci p_is_pcm0 = p_is_pcm[0]; 483cabdff1aSopenharmony_ci q_is_pcm0 = q_is_pcm[0]; 484cabdff1aSopenharmony_ci 485cabdff1aSopenharmony_ci dp04 = abs(p1[-3] - (p1[-2] << 1) + p1[-1]); 486cabdff1aSopenharmony_ci dq04 = abs(p1[2] - (p1[1] << 1) + p1[0]); 487cabdff1aSopenharmony_ci dp34 = abs(p0[-3] - (p0[-2] << 1) + p0[-1]); 488cabdff1aSopenharmony_ci dq34 = abs(p0[2] - (p0[1] << 1) + p0[0]); 489cabdff1aSopenharmony_ci d04 = dp04 + dq04; 490cabdff1aSopenharmony_ci d34 = dp34 + dq34; 491cabdff1aSopenharmony_ci p_is_pcm4 = p_is_pcm[1]; 492cabdff1aSopenharmony_ci q_is_pcm4 = q_is_pcm[1]; 493cabdff1aSopenharmony_ci 494cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(p_is_pcm0); 495cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(p_is_pcm4); 496cabdff1aSopenharmony_ci p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); 497cabdff1aSopenharmony_ci p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0); 498cabdff1aSopenharmony_ci 499cabdff1aSopenharmony_ci d0030 = (d00 + d30) >= beta; 500cabdff1aSopenharmony_ci d0434 = (d04 + d34) >= beta; 501cabdff1aSopenharmony_ci 502cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(d0030); 503cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(d0434); 504cabdff1aSopenharmony_ci cmp3 = __msa_ilvev_d(cmp1, cmp0); 505cabdff1aSopenharmony_ci cmp3 = (v2i64) __msa_ceqi_d(cmp3, 0); 506cabdff1aSopenharmony_ci 507cabdff1aSopenharmony_ci if ((!p_is_pcm0 || !p_is_pcm4 || !q_is_pcm0 || !q_is_pcm4) && 508cabdff1aSopenharmony_ci (!d0030 || !d0434)) { 509cabdff1aSopenharmony_ci src -= 4; 510cabdff1aSopenharmony_ci LD_UH8(src, stride, p3_src, p2_src, p1_src, p0_src, q0_src, q1_src, 511cabdff1aSopenharmony_ci q2_src, q3_src); 512cabdff1aSopenharmony_ci 513cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(q_is_pcm0); 514cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(q_is_pcm4); 515cabdff1aSopenharmony_ci q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); 516cabdff1aSopenharmony_ci q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0); 517cabdff1aSopenharmony_ci 518cabdff1aSopenharmony_ci tc0 = tc[0]; 519cabdff1aSopenharmony_ci beta30 = beta >> 3; 520cabdff1aSopenharmony_ci beta20 = beta >> 2; 521cabdff1aSopenharmony_ci tc250 = ((tc0 * 5 + 1) >> 1); 522cabdff1aSopenharmony_ci 523cabdff1aSopenharmony_ci tc4 = tc[1]; 524cabdff1aSopenharmony_ci tc254 = ((tc4 * 5 + 1) >> 1); 525cabdff1aSopenharmony_ci cmp0 = (v2i64) __msa_fill_h(tc0 << 1); 526cabdff1aSopenharmony_ci cmp1 = (v2i64) __msa_fill_h(tc4 << 1); 527cabdff1aSopenharmony_ci tc_pos = (v8i16) __msa_ilvev_d(cmp1, cmp0); 528cabdff1aSopenharmony_ci 529cabdff1aSopenharmony_ci TRANSPOSE8x8_UB_UH(p3_src, p2_src, p1_src, p0_src, q0_src, q1_src, 530cabdff1aSopenharmony_ci q2_src, q3_src, p3_src, p2_src, p1_src, p0_src, 531cabdff1aSopenharmony_ci q0_src, q1_src, q2_src, q3_src); 532cabdff1aSopenharmony_ci 533cabdff1aSopenharmony_ci flag0 = abs(p3[-4] - p3[-1]) + abs(p3[3] - p3[0]) < beta30 && 534cabdff1aSopenharmony_ci abs(p3[-1] - p3[0]) < tc250; 535cabdff1aSopenharmony_ci flag0 = flag0 && (abs(p2[-4] - p2[-1]) + abs(p2[3] - p2[0]) < beta30 && 536cabdff1aSopenharmony_ci abs(p2[-1] - p2[0]) < tc250 && (d00 << 1) < beta20 && 537cabdff1aSopenharmony_ci (d30 << 1) < beta20); 538cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(flag0); 539cabdff1aSopenharmony_ci ILVR_B4_UH(zero, p3_src, zero, p2_src, zero, p1_src, zero, p0_src, 540cabdff1aSopenharmony_ci p3_src, p2_src, p1_src, p0_src); 541cabdff1aSopenharmony_ci 542cabdff1aSopenharmony_ci flag1 = abs(p1[-4] - p1[-1]) + abs(p1[3] - p1[0]) < beta30 && 543cabdff1aSopenharmony_ci abs(p1[-1] - p1[0]) < tc254; 544cabdff1aSopenharmony_ci flag1 = flag1 && (abs(p0[-4] - p0[-1]) + abs(p0[3] - p0[0]) < beta30 && 545cabdff1aSopenharmony_ci abs(p0[-1] - p0[0]) < tc254 && (d04 << 1) < beta20 && 546cabdff1aSopenharmony_ci (d34 << 1) < beta20); 547cabdff1aSopenharmony_ci ILVR_B4_UH(zero, q0_src, zero, q1_src, zero, q2_src, zero, q3_src, 548cabdff1aSopenharmony_ci q0_src, q1_src, q2_src, q3_src); 549cabdff1aSopenharmony_ci 550cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(flag1); 551cabdff1aSopenharmony_ci cmp2 = __msa_ilvev_d(cmp1, cmp0); 552cabdff1aSopenharmony_ci cmp2 = __msa_ceqi_d(cmp2, 0); 553cabdff1aSopenharmony_ci 554cabdff1aSopenharmony_ci if (flag0 && flag1) { /* strong only */ 555cabdff1aSopenharmony_ci /* strong filter */ 556cabdff1aSopenharmony_ci tc_neg = -tc_pos; 557cabdff1aSopenharmony_ci 558cabdff1aSopenharmony_ci /* p part */ 559cabdff1aSopenharmony_ci temp0 = (p1_src + p0_src + q0_src); 560cabdff1aSopenharmony_ci 561cabdff1aSopenharmony_ci temp1 = ((p3_src + p2_src) << 1) + p2_src + temp0; 562cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 563cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - p2_src); 564cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 565cabdff1aSopenharmony_ci dst0 = (v16u8) (temp2 + (v8i16) p2_src); 566cabdff1aSopenharmony_ci 567cabdff1aSopenharmony_ci temp1 = temp0 + p2_src; 568cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2); 569cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - p1_src); 570cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 571cabdff1aSopenharmony_ci dst1 = (v16u8) (temp2 + (v8i16) p1_src); 572cabdff1aSopenharmony_ci 573cabdff1aSopenharmony_ci temp1 = (temp0 << 1) + p2_src + q1_src; 574cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 575cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - p0_src); 576cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 577cabdff1aSopenharmony_ci dst2 = (v16u8) (temp2 + (v8i16) p0_src); 578cabdff1aSopenharmony_ci 579cabdff1aSopenharmony_ci dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) p_is_pcm_vec); 580cabdff1aSopenharmony_ci dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) p_is_pcm_vec); 581cabdff1aSopenharmony_ci dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) p_is_pcm_vec); 582cabdff1aSopenharmony_ci 583cabdff1aSopenharmony_ci /* q part */ 584cabdff1aSopenharmony_ci temp0 = (q1_src + p0_src + q0_src); 585cabdff1aSopenharmony_ci temp1 = ((q3_src + q2_src) << 1) + q2_src + temp0; 586cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 587cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - q2_src); 588cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 589cabdff1aSopenharmony_ci dst5 = (v16u8) (temp2 + (v8i16) q2_src); 590cabdff1aSopenharmony_ci 591cabdff1aSopenharmony_ci temp1 = temp0 + q2_src; 592cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2); 593cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - q1_src); 594cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 595cabdff1aSopenharmony_ci dst4 = (v16u8) (temp2 + (v8i16) q1_src); 596cabdff1aSopenharmony_ci 597cabdff1aSopenharmony_ci temp1 = (temp0 << 1) + p1_src + q2_src; 598cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 599cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - q0_src); 600cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 601cabdff1aSopenharmony_ci dst3 = (v16u8) (temp2 + (v8i16) q0_src); 602cabdff1aSopenharmony_ci 603cabdff1aSopenharmony_ci dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) q_is_pcm_vec); 604cabdff1aSopenharmony_ci dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) q_is_pcm_vec); 605cabdff1aSopenharmony_ci dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) q_is_pcm_vec); 606cabdff1aSopenharmony_ci /* strong filter ends */ 607cabdff1aSopenharmony_ci } else if (flag0 == flag1) { /* weak only */ 608cabdff1aSopenharmony_ci /* weak filter */ 609cabdff1aSopenharmony_ci tc_pos >>= 1; 610cabdff1aSopenharmony_ci tc_neg = -tc_pos; 611cabdff1aSopenharmony_ci 612cabdff1aSopenharmony_ci diff0 = (v8i16) (q0_src - p0_src); 613cabdff1aSopenharmony_ci diff1 = (v8i16) (q1_src - p1_src); 614cabdff1aSopenharmony_ci diff0 = (diff0 << 3) + diff0; 615cabdff1aSopenharmony_ci diff1 = (diff1 << 1) + diff1; 616cabdff1aSopenharmony_ci delta0 = diff0 - diff1; 617cabdff1aSopenharmony_ci delta0 = __msa_srari_h(delta0, 4); 618cabdff1aSopenharmony_ci 619cabdff1aSopenharmony_ci temp1 = (v8u16) ((tc_pos << 3) + (tc_pos << 1)); 620cabdff1aSopenharmony_ci abs_delta0 = __msa_add_a_h(delta0, (v8i16) zero); 621cabdff1aSopenharmony_ci abs_delta0 = (v8u16) abs_delta0 < temp1; 622cabdff1aSopenharmony_ci 623cabdff1aSopenharmony_ci CLIP_SH(delta0, tc_neg, tc_pos); 624cabdff1aSopenharmony_ci temp2 = (v8i16) (delta0 + p0_src); 625cabdff1aSopenharmony_ci CLIP_SH_0_255(temp2); 626cabdff1aSopenharmony_ci temp0 = (v8u16) __msa_bmz_v((v16u8) temp2, (v16u8) p0_src, 627cabdff1aSopenharmony_ci (v16u8) p_is_pcm_vec); 628cabdff1aSopenharmony_ci 629cabdff1aSopenharmony_ci temp2 = (v8i16) (q0_src - delta0); 630cabdff1aSopenharmony_ci CLIP_SH_0_255(temp2); 631cabdff1aSopenharmony_ci temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, 632cabdff1aSopenharmony_ci (v16u8) q_is_pcm_vec); 633cabdff1aSopenharmony_ci 634cabdff1aSopenharmony_ci tmp = ((beta + (beta >> 1)) >> 3); 635cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(!p_is_pcm0 && ((dp00 + dp30) < tmp)); 636cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(!p_is_pcm4 && ((dp04 + dp34) < tmp)); 637cabdff1aSopenharmony_ci p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); 638cabdff1aSopenharmony_ci p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0); 639cabdff1aSopenharmony_ci 640cabdff1aSopenharmony_ci cmp0 = (v2i64) __msa_fill_h((!q_is_pcm0) && (dq00 + dq30 < tmp)); 641cabdff1aSopenharmony_ci cmp1 = (v2i64) __msa_fill_h((!q_is_pcm4) && (dq04 + dq34 < tmp)); 642cabdff1aSopenharmony_ci q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); 643cabdff1aSopenharmony_ci q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0); 644cabdff1aSopenharmony_ci 645cabdff1aSopenharmony_ci tc_pos >>= 1; 646cabdff1aSopenharmony_ci tc_neg = -tc_pos; 647cabdff1aSopenharmony_ci 648cabdff1aSopenharmony_ci delta1 = (v8i16) __msa_aver_u_h(p2_src, p0_src); 649cabdff1aSopenharmony_ci delta1 -= (v8i16) p1_src; 650cabdff1aSopenharmony_ci delta1 += delta0; 651cabdff1aSopenharmony_ci delta1 >>= 1; 652cabdff1aSopenharmony_ci CLIP_SH(delta1, tc_neg, tc_pos); 653cabdff1aSopenharmony_ci delta1 = (v8i16) p1_src + (v8i16) delta1; 654cabdff1aSopenharmony_ci CLIP_SH_0_255(delta1); 655cabdff1aSopenharmony_ci delta1 = (v8i16) __msa_bmnz_v((v16u8) delta1, (v16u8) p1_src, 656cabdff1aSopenharmony_ci (v16u8) p_is_pcm_vec); 657cabdff1aSopenharmony_ci 658cabdff1aSopenharmony_ci delta2 = (v8i16) __msa_aver_u_h(q0_src, q2_src); 659cabdff1aSopenharmony_ci delta2 = delta2 - (v8i16) q1_src; 660cabdff1aSopenharmony_ci delta2 = delta2 - delta0; 661cabdff1aSopenharmony_ci delta2 = delta2 >> 1; 662cabdff1aSopenharmony_ci CLIP_SH(delta2, tc_neg, tc_pos); 663cabdff1aSopenharmony_ci delta2 = (v8i16) q1_src + (v8i16) delta2; 664cabdff1aSopenharmony_ci CLIP_SH_0_255(delta2); 665cabdff1aSopenharmony_ci delta2 = (v8i16) __msa_bmnz_v((v16u8) delta2, (v16u8) q1_src, 666cabdff1aSopenharmony_ci (v16u8) q_is_pcm_vec); 667cabdff1aSopenharmony_ci 668cabdff1aSopenharmony_ci dst0 = __msa_bmz_v((v16u8) delta1, (v16u8) p1_src, 669cabdff1aSopenharmony_ci (v16u8) abs_delta0); 670cabdff1aSopenharmony_ci dst1 = __msa_bmz_v((v16u8) temp0, (v16u8) p0_src, 671cabdff1aSopenharmony_ci (v16u8) abs_delta0); 672cabdff1aSopenharmony_ci dst2 = __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, 673cabdff1aSopenharmony_ci (v16u8) abs_delta0); 674cabdff1aSopenharmony_ci dst3 = __msa_bmz_v((v16u8) delta2, (v16u8) q1_src, 675cabdff1aSopenharmony_ci (v16u8) abs_delta0); 676cabdff1aSopenharmony_ci /* weak filter ends */ 677cabdff1aSopenharmony_ci 678cabdff1aSopenharmony_ci dst0 = __msa_bmz_v(dst0, (v16u8) p1_src, (v16u8) cmp3); 679cabdff1aSopenharmony_ci dst1 = __msa_bmz_v(dst1, (v16u8) p0_src, (v16u8) cmp3); 680cabdff1aSopenharmony_ci dst2 = __msa_bmz_v(dst2, (v16u8) q0_src, (v16u8) cmp3); 681cabdff1aSopenharmony_ci dst3 = __msa_bmz_v(dst3, (v16u8) q1_src, (v16u8) cmp3); 682cabdff1aSopenharmony_ci 683cabdff1aSopenharmony_ci PCKEV_B2_UB(dst2, dst0, dst3, dst1, dst0, dst1); 684cabdff1aSopenharmony_ci 685cabdff1aSopenharmony_ci /* transpose */ 686cabdff1aSopenharmony_ci ILVRL_B2_UB(dst1, dst0, dst4, dst5); 687cabdff1aSopenharmony_ci ILVRL_H2_UB(dst5, dst4, dst0, dst1); 688cabdff1aSopenharmony_ci 689cabdff1aSopenharmony_ci src += 2; 690cabdff1aSopenharmony_ci 691cabdff1aSopenharmony_ci tmp2 = __msa_copy_u_w((v4i32) dst0, 0); 692cabdff1aSopenharmony_ci tmp3 = __msa_copy_u_w((v4i32) dst0, 1); 693cabdff1aSopenharmony_ci SW(tmp2, src); 694cabdff1aSopenharmony_ci src += stride; 695cabdff1aSopenharmony_ci SW(tmp3, src); 696cabdff1aSopenharmony_ci src += stride; 697cabdff1aSopenharmony_ci 698cabdff1aSopenharmony_ci tmp2 = __msa_copy_u_w((v4i32) dst0, 2); 699cabdff1aSopenharmony_ci tmp3 = __msa_copy_u_w((v4i32) dst0, 3); 700cabdff1aSopenharmony_ci SW(tmp2, src); 701cabdff1aSopenharmony_ci src += stride; 702cabdff1aSopenharmony_ci SW(tmp3, src); 703cabdff1aSopenharmony_ci src += stride; 704cabdff1aSopenharmony_ci 705cabdff1aSopenharmony_ci tmp2 = __msa_copy_u_w((v4i32) dst1, 0); 706cabdff1aSopenharmony_ci tmp3 = __msa_copy_u_w((v4i32) dst1, 1); 707cabdff1aSopenharmony_ci SW(tmp2, src); 708cabdff1aSopenharmony_ci src += stride; 709cabdff1aSopenharmony_ci SW(tmp3, src); 710cabdff1aSopenharmony_ci src += stride; 711cabdff1aSopenharmony_ci 712cabdff1aSopenharmony_ci tmp2 = __msa_copy_u_w((v4i32) dst1, 2); 713cabdff1aSopenharmony_ci tmp3 = __msa_copy_u_w((v4i32) dst1, 3); 714cabdff1aSopenharmony_ci SW(tmp2, src); 715cabdff1aSopenharmony_ci src += stride; 716cabdff1aSopenharmony_ci SW(tmp3, src); 717cabdff1aSopenharmony_ci 718cabdff1aSopenharmony_ci return; 719cabdff1aSopenharmony_ci } else { /* strong + weak */ 720cabdff1aSopenharmony_ci /* strong filter */ 721cabdff1aSopenharmony_ci tc_neg = -tc_pos; 722cabdff1aSopenharmony_ci 723cabdff1aSopenharmony_ci /* p part */ 724cabdff1aSopenharmony_ci temp0 = (p1_src + p0_src + q0_src); 725cabdff1aSopenharmony_ci 726cabdff1aSopenharmony_ci temp1 = ((p3_src + p2_src) << 1) + p2_src + temp0; 727cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 728cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - p2_src); 729cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 730cabdff1aSopenharmony_ci dst0 = (v16u8) (temp2 + (v8i16) p2_src); 731cabdff1aSopenharmony_ci 732cabdff1aSopenharmony_ci temp1 = temp0 + p2_src; 733cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2); 734cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - p1_src); 735cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 736cabdff1aSopenharmony_ci dst1 = (v16u8) (temp2 + (v8i16) p1_src); 737cabdff1aSopenharmony_ci 738cabdff1aSopenharmony_ci temp1 = (temp0 << 1) + p2_src + q1_src; 739cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 740cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - p0_src); 741cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 742cabdff1aSopenharmony_ci dst2 = (v16u8) (temp2 + (v8i16) p0_src); 743cabdff1aSopenharmony_ci 744cabdff1aSopenharmony_ci dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) p_is_pcm_vec); 745cabdff1aSopenharmony_ci dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) p_is_pcm_vec); 746cabdff1aSopenharmony_ci dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) p_is_pcm_vec); 747cabdff1aSopenharmony_ci 748cabdff1aSopenharmony_ci /* q part */ 749cabdff1aSopenharmony_ci temp0 = (q1_src + p0_src + q0_src); 750cabdff1aSopenharmony_ci temp1 = ((q3_src + q2_src) << 1) + q2_src + temp0; 751cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 752cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - q2_src); 753cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 754cabdff1aSopenharmony_ci dst5 = (v16u8) (temp2 + (v8i16) q2_src); 755cabdff1aSopenharmony_ci 756cabdff1aSopenharmony_ci temp1 = temp0 + q2_src; 757cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2); 758cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - q1_src); 759cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 760cabdff1aSopenharmony_ci dst4 = (v16u8) (temp2 + (v8i16) q1_src); 761cabdff1aSopenharmony_ci 762cabdff1aSopenharmony_ci temp1 = (temp0 << 1) + p1_src + q2_src; 763cabdff1aSopenharmony_ci temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3); 764cabdff1aSopenharmony_ci temp2 = (v8i16) (temp1 - q0_src); 765cabdff1aSopenharmony_ci CLIP_SH(temp2, tc_neg, tc_pos); 766cabdff1aSopenharmony_ci dst3 = (v16u8) (temp2 + (v8i16) q0_src); 767cabdff1aSopenharmony_ci 768cabdff1aSopenharmony_ci dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) q_is_pcm_vec); 769cabdff1aSopenharmony_ci dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) q_is_pcm_vec); 770cabdff1aSopenharmony_ci dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) q_is_pcm_vec); 771cabdff1aSopenharmony_ci /* strong filter ends */ 772cabdff1aSopenharmony_ci 773cabdff1aSopenharmony_ci /* weak filter */ 774cabdff1aSopenharmony_ci tc_pos >>= 1; 775cabdff1aSopenharmony_ci tc_neg = -tc_pos; 776cabdff1aSopenharmony_ci 777cabdff1aSopenharmony_ci diff0 = (v8i16) (q0_src - p0_src); 778cabdff1aSopenharmony_ci diff1 = (v8i16) (q1_src - p1_src); 779cabdff1aSopenharmony_ci diff0 = (diff0 << 3) + diff0; 780cabdff1aSopenharmony_ci diff1 = (diff1 << 1) + diff1; 781cabdff1aSopenharmony_ci delta0 = diff0 - diff1; 782cabdff1aSopenharmony_ci delta0 = __msa_srari_h(delta0, 4); 783cabdff1aSopenharmony_ci 784cabdff1aSopenharmony_ci temp1 = (v8u16) ((tc_pos << 3) + (tc_pos << 1)); 785cabdff1aSopenharmony_ci abs_delta0 = __msa_add_a_h(delta0, (v8i16) zero); 786cabdff1aSopenharmony_ci abs_delta0 = (v8u16) abs_delta0 < temp1; 787cabdff1aSopenharmony_ci 788cabdff1aSopenharmony_ci CLIP_SH(delta0, tc_neg, tc_pos); 789cabdff1aSopenharmony_ci 790cabdff1aSopenharmony_ci temp2 = (v8i16) (delta0 + p0_src); 791cabdff1aSopenharmony_ci CLIP_SH_0_255(temp2); 792cabdff1aSopenharmony_ci temp0 = (v8u16) __msa_bmz_v((v16u8) temp2, (v16u8) p0_src, 793cabdff1aSopenharmony_ci (v16u8) p_is_pcm_vec); 794cabdff1aSopenharmony_ci 795cabdff1aSopenharmony_ci temp2 = (v8i16) (q0_src - delta0); 796cabdff1aSopenharmony_ci CLIP_SH_0_255(temp2); 797cabdff1aSopenharmony_ci temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, 798cabdff1aSopenharmony_ci (v16u8) q_is_pcm_vec); 799cabdff1aSopenharmony_ci 800cabdff1aSopenharmony_ci tmp = (beta + (beta >> 1)) >> 3; 801cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(!p_is_pcm0 && ((dp00 + dp30) < tmp)); 802cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(!p_is_pcm4 && ((dp04 + dp34) < tmp)); 803cabdff1aSopenharmony_ci p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); 804cabdff1aSopenharmony_ci p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0); 805cabdff1aSopenharmony_ci 806cabdff1aSopenharmony_ci cmp0 = (v2i64) __msa_fill_h((!q_is_pcm0) && (dq00 + dq30 < tmp)); 807cabdff1aSopenharmony_ci cmp1 = (v2i64) __msa_fill_h((!q_is_pcm4) && (dq04 + dq34 < tmp)); 808cabdff1aSopenharmony_ci q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); 809cabdff1aSopenharmony_ci q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0); 810cabdff1aSopenharmony_ci 811cabdff1aSopenharmony_ci tc_pos >>= 1; 812cabdff1aSopenharmony_ci tc_neg = -tc_pos; 813cabdff1aSopenharmony_ci 814cabdff1aSopenharmony_ci delta1 = (v8i16) __msa_aver_u_h(p2_src, p0_src); 815cabdff1aSopenharmony_ci delta1 -= (v8i16) p1_src; 816cabdff1aSopenharmony_ci delta1 += delta0; 817cabdff1aSopenharmony_ci delta1 >>= 1; 818cabdff1aSopenharmony_ci CLIP_SH(delta1, tc_neg, tc_pos); 819cabdff1aSopenharmony_ci delta1 = (v8i16) p1_src + (v8i16) delta1; 820cabdff1aSopenharmony_ci CLIP_SH_0_255(delta1); 821cabdff1aSopenharmony_ci delta1 = (v8i16) __msa_bmnz_v((v16u8) delta1, (v16u8) p1_src, 822cabdff1aSopenharmony_ci (v16u8) p_is_pcm_vec); 823cabdff1aSopenharmony_ci 824cabdff1aSopenharmony_ci delta2 = (v8i16) __msa_aver_u_h(q0_src, q2_src); 825cabdff1aSopenharmony_ci delta2 = delta2 - (v8i16) q1_src; 826cabdff1aSopenharmony_ci delta2 = delta2 - delta0; 827cabdff1aSopenharmony_ci delta2 = delta2 >> 1; 828cabdff1aSopenharmony_ci CLIP_SH(delta2, tc_neg, tc_pos); 829cabdff1aSopenharmony_ci delta2 = (v8i16) q1_src + (v8i16) delta2; 830cabdff1aSopenharmony_ci CLIP_SH_0_255(delta2); 831cabdff1aSopenharmony_ci delta2 = (v8i16) __msa_bmnz_v((v16u8) delta2, (v16u8) q1_src, 832cabdff1aSopenharmony_ci (v16u8) q_is_pcm_vec); 833cabdff1aSopenharmony_ci delta1 = (v8i16) __msa_bmz_v((v16u8) delta1, (v16u8) p1_src, 834cabdff1aSopenharmony_ci (v16u8) abs_delta0); 835cabdff1aSopenharmony_ci temp0 = (v8u16) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src, 836cabdff1aSopenharmony_ci (v16u8) abs_delta0); 837cabdff1aSopenharmony_ci temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src, 838cabdff1aSopenharmony_ci (v16u8) abs_delta0); 839cabdff1aSopenharmony_ci delta2 = (v8i16) __msa_bmz_v((v16u8) delta2, (v16u8) q1_src, 840cabdff1aSopenharmony_ci (v16u8) abs_delta0); 841cabdff1aSopenharmony_ci /* weak filter ends*/ 842cabdff1aSopenharmony_ci 843cabdff1aSopenharmony_ci /* select between weak or strong */ 844cabdff1aSopenharmony_ci dst2 = __msa_bmnz_v(dst2, (v16u8) temp0, (v16u8) cmp2); 845cabdff1aSopenharmony_ci dst3 = __msa_bmnz_v(dst3, (v16u8) temp2, (v16u8) cmp2); 846cabdff1aSopenharmony_ci dst1 = __msa_bmnz_v(dst1, (v16u8) delta1, (v16u8) cmp2); 847cabdff1aSopenharmony_ci dst4 = __msa_bmnz_v(dst4, (v16u8) delta2, (v16u8) cmp2); 848cabdff1aSopenharmony_ci dst0 = __msa_bmnz_v(dst0, (v16u8) p2_src, (v16u8) cmp2); 849cabdff1aSopenharmony_ci dst5 = __msa_bmnz_v(dst5, (v16u8) q2_src, (v16u8) cmp2); 850cabdff1aSopenharmony_ci } 851cabdff1aSopenharmony_ci 852cabdff1aSopenharmony_ci dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) cmp3); 853cabdff1aSopenharmony_ci dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) cmp3); 854cabdff1aSopenharmony_ci dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) cmp3); 855cabdff1aSopenharmony_ci dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) cmp3); 856cabdff1aSopenharmony_ci dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) cmp3); 857cabdff1aSopenharmony_ci dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) cmp3); 858cabdff1aSopenharmony_ci 859cabdff1aSopenharmony_ci /* pack results to 8 bit */ 860cabdff1aSopenharmony_ci PCKEV_B4_UB(dst2, dst0, dst3, dst1, dst4, dst4, dst5, dst5, dst0, dst1, 861cabdff1aSopenharmony_ci dst2, dst3); 862cabdff1aSopenharmony_ci 863cabdff1aSopenharmony_ci /* transpose */ 864cabdff1aSopenharmony_ci ILVRL_B2_UB(dst1, dst0, dst4, dst5); 865cabdff1aSopenharmony_ci ILVRL_B2_UB(dst3, dst2, dst6, dst7); 866cabdff1aSopenharmony_ci ILVRL_H2_UB(dst5, dst4, dst0, dst1); 867cabdff1aSopenharmony_ci ILVRL_H2_UB(dst7, dst6, dst2, dst3); 868cabdff1aSopenharmony_ci 869cabdff1aSopenharmony_ci src += 1; 870cabdff1aSopenharmony_ci 871cabdff1aSopenharmony_ci tmp2 = __msa_copy_u_w((v4i32) dst0, 0); 872cabdff1aSopenharmony_ci tmp3 = __msa_copy_u_w((v4i32) dst0, 1); 873cabdff1aSopenharmony_ci tmp0 = __msa_copy_u_h((v8i16) dst2, 0); 874cabdff1aSopenharmony_ci tmp1 = __msa_copy_u_h((v8i16) dst2, 2); 875cabdff1aSopenharmony_ci SW(tmp2, src); 876cabdff1aSopenharmony_ci SH(tmp0, src + 4); 877cabdff1aSopenharmony_ci src += stride; 878cabdff1aSopenharmony_ci SW(tmp3, src); 879cabdff1aSopenharmony_ci SH(tmp1, src + 4); 880cabdff1aSopenharmony_ci src += stride; 881cabdff1aSopenharmony_ci 882cabdff1aSopenharmony_ci tmp2 = __msa_copy_u_w((v4i32) dst0, 2); 883cabdff1aSopenharmony_ci tmp3 = __msa_copy_u_w((v4i32) dst0, 3); 884cabdff1aSopenharmony_ci tmp0 = __msa_copy_u_h((v8i16) dst2, 4); 885cabdff1aSopenharmony_ci tmp1 = __msa_copy_u_h((v8i16) dst2, 6); 886cabdff1aSopenharmony_ci SW(tmp2, src); 887cabdff1aSopenharmony_ci SH(tmp0, src + 4); 888cabdff1aSopenharmony_ci src += stride; 889cabdff1aSopenharmony_ci SW(tmp3, src); 890cabdff1aSopenharmony_ci SH(tmp1, src + 4); 891cabdff1aSopenharmony_ci src += stride; 892cabdff1aSopenharmony_ci 893cabdff1aSopenharmony_ci tmp2 = __msa_copy_u_w((v4i32) dst1, 0); 894cabdff1aSopenharmony_ci tmp3 = __msa_copy_u_w((v4i32) dst1, 1); 895cabdff1aSopenharmony_ci tmp0 = __msa_copy_u_h((v8i16) dst3, 0); 896cabdff1aSopenharmony_ci tmp1 = __msa_copy_u_h((v8i16) dst3, 2); 897cabdff1aSopenharmony_ci SW(tmp2, src); 898cabdff1aSopenharmony_ci SH(tmp0, src + 4); 899cabdff1aSopenharmony_ci src += stride; 900cabdff1aSopenharmony_ci SW(tmp3, src); 901cabdff1aSopenharmony_ci SH(tmp1, src + 4); 902cabdff1aSopenharmony_ci src += stride; 903cabdff1aSopenharmony_ci 904cabdff1aSopenharmony_ci tmp2 = __msa_copy_u_w((v4i32) dst1, 2); 905cabdff1aSopenharmony_ci tmp3 = __msa_copy_u_w((v4i32) dst1, 3); 906cabdff1aSopenharmony_ci tmp0 = __msa_copy_u_h((v8i16) dst3, 4); 907cabdff1aSopenharmony_ci tmp1 = __msa_copy_u_h((v8i16) dst3, 6); 908cabdff1aSopenharmony_ci SW(tmp2, src); 909cabdff1aSopenharmony_ci SH(tmp0, src + 4); 910cabdff1aSopenharmony_ci src += stride; 911cabdff1aSopenharmony_ci SW(tmp3, src); 912cabdff1aSopenharmony_ci SH(tmp1, src + 4); 913cabdff1aSopenharmony_ci } 914cabdff1aSopenharmony_ci} 915cabdff1aSopenharmony_ci 916cabdff1aSopenharmony_cistatic void hevc_loopfilter_chroma_hor_msa(uint8_t *src, int32_t stride, 917cabdff1aSopenharmony_ci int32_t *tc, uint8_t *p_is_pcm, 918cabdff1aSopenharmony_ci uint8_t *q_is_pcm) 919cabdff1aSopenharmony_ci{ 920cabdff1aSopenharmony_ci uint8_t *p1_ptr = src - (stride << 1); 921cabdff1aSopenharmony_ci uint8_t *p0_ptr = src - stride; 922cabdff1aSopenharmony_ci uint8_t *q0_ptr = src; 923cabdff1aSopenharmony_ci uint8_t *q1_ptr = src + stride; 924cabdff1aSopenharmony_ci v2i64 cmp0, cmp1, p_is_pcm_vec, q_is_pcm_vec; 925cabdff1aSopenharmony_ci v8u16 p1, p0, q0, q1; 926cabdff1aSopenharmony_ci v8i16 tc_pos, tc_neg; 927cabdff1aSopenharmony_ci v16i8 zero = { 0 }; 928cabdff1aSopenharmony_ci v8i16 temp0, temp1, delta; 929cabdff1aSopenharmony_ci 930cabdff1aSopenharmony_ci if (!(tc[0] <= 0) || !(tc[1] <= 0)) { 931cabdff1aSopenharmony_ci cmp0 = (v2i64) __msa_fill_h(tc[0]); 932cabdff1aSopenharmony_ci cmp1 = (v2i64) __msa_fill_h(tc[1]); 933cabdff1aSopenharmony_ci tc_pos = (v8i16) __msa_ilvev_d(cmp1, cmp0); 934cabdff1aSopenharmony_ci tc_neg = -tc_pos; 935cabdff1aSopenharmony_ci 936cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(p_is_pcm[0]); 937cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(p_is_pcm[1]); 938cabdff1aSopenharmony_ci p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); 939cabdff1aSopenharmony_ci p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0); 940cabdff1aSopenharmony_ci 941cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(q_is_pcm[0]); 942cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(q_is_pcm[1]); 943cabdff1aSopenharmony_ci q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); 944cabdff1aSopenharmony_ci q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0); 945cabdff1aSopenharmony_ci 946cabdff1aSopenharmony_ci p1 = LD_UH(p1_ptr); 947cabdff1aSopenharmony_ci p0 = LD_UH(p0_ptr); 948cabdff1aSopenharmony_ci q0 = LD_UH(q0_ptr); 949cabdff1aSopenharmony_ci q1 = LD_UH(q1_ptr); 950cabdff1aSopenharmony_ci 951cabdff1aSopenharmony_ci ILVR_B4_UH(zero, p1, zero, p0, zero, q0, zero, q1, p1, p0, q0, q1); 952cabdff1aSopenharmony_ci 953cabdff1aSopenharmony_ci temp0 = (v8i16) (q0 - p0); 954cabdff1aSopenharmony_ci temp1 = (v8i16) (p1 - q1); 955cabdff1aSopenharmony_ci temp0 <<= 2; 956cabdff1aSopenharmony_ci temp0 += temp1; 957cabdff1aSopenharmony_ci delta = __msa_srari_h((v8i16) temp0, 3); 958cabdff1aSopenharmony_ci CLIP_SH(delta, tc_neg, tc_pos); 959cabdff1aSopenharmony_ci 960cabdff1aSopenharmony_ci temp0 = (v8i16) ((v8i16) p0 + delta); 961cabdff1aSopenharmony_ci CLIP_SH_0_255(temp0); 962cabdff1aSopenharmony_ci temp0 = (v8i16) __msa_bmz_v((v16u8) temp0, (v16u8) p0, 963cabdff1aSopenharmony_ci (v16u8) p_is_pcm_vec); 964cabdff1aSopenharmony_ci 965cabdff1aSopenharmony_ci temp1 = (v8i16) ((v8i16) q0 - delta); 966cabdff1aSopenharmony_ci CLIP_SH_0_255(temp1); 967cabdff1aSopenharmony_ci temp1 = (v8i16) __msa_bmz_v((v16u8) temp1, (v16u8) q0, 968cabdff1aSopenharmony_ci (v16u8) q_is_pcm_vec); 969cabdff1aSopenharmony_ci 970cabdff1aSopenharmony_ci tc_pos = (v8i16) __msa_clei_s_d((v2i64) tc_pos, 0); 971cabdff1aSopenharmony_ci temp0 = (v8i16) __msa_bmnz_v((v16u8) temp0, (v16u8) p0, (v16u8) tc_pos); 972cabdff1aSopenharmony_ci temp1 = (v8i16) __msa_bmnz_v((v16u8) temp1, (v16u8) q0, (v16u8) tc_pos); 973cabdff1aSopenharmony_ci 974cabdff1aSopenharmony_ci temp0 = (v8i16) __msa_pckev_b((v16i8) temp1, (v16i8) temp0); 975cabdff1aSopenharmony_ci ST_D2(temp0, 0, 1, p0_ptr, stride); 976cabdff1aSopenharmony_ci } 977cabdff1aSopenharmony_ci} 978cabdff1aSopenharmony_ci 979cabdff1aSopenharmony_cistatic void hevc_loopfilter_chroma_ver_msa(uint8_t *src, int32_t stride, 980cabdff1aSopenharmony_ci int32_t *tc, uint8_t *p_is_pcm, 981cabdff1aSopenharmony_ci uint8_t *q_is_pcm) 982cabdff1aSopenharmony_ci{ 983cabdff1aSopenharmony_ci v2i64 cmp0, cmp1, p_is_pcm_vec, q_is_pcm_vec; 984cabdff1aSopenharmony_ci v16u8 src0, src1, src2, src3, src4, src5, src6, src7; 985cabdff1aSopenharmony_ci v8u16 p1, p0, q0, q1; 986cabdff1aSopenharmony_ci v8i16 tc_pos, tc_neg; 987cabdff1aSopenharmony_ci v16i8 zero = { 0 }; 988cabdff1aSopenharmony_ci v8i16 temp0, temp1, delta; 989cabdff1aSopenharmony_ci 990cabdff1aSopenharmony_ci if (!(tc[0] <= 0) || !(tc[1] <= 0)) { 991cabdff1aSopenharmony_ci cmp0 = (v2i64) __msa_fill_h(tc[0]); 992cabdff1aSopenharmony_ci cmp1 = (v2i64) __msa_fill_h(tc[1]); 993cabdff1aSopenharmony_ci tc_pos = (v8i16) __msa_ilvev_d(cmp1, cmp0); 994cabdff1aSopenharmony_ci tc_neg = -tc_pos; 995cabdff1aSopenharmony_ci 996cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(p_is_pcm[0]); 997cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(p_is_pcm[1]); 998cabdff1aSopenharmony_ci p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); 999cabdff1aSopenharmony_ci p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0); 1000cabdff1aSopenharmony_ci 1001cabdff1aSopenharmony_ci cmp0 = __msa_fill_d(q_is_pcm[0]); 1002cabdff1aSopenharmony_ci cmp1 = __msa_fill_d(q_is_pcm[1]); 1003cabdff1aSopenharmony_ci q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0); 1004cabdff1aSopenharmony_ci q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0); 1005cabdff1aSopenharmony_ci 1006cabdff1aSopenharmony_ci src -= 2; 1007cabdff1aSopenharmony_ci LD_UB8(src, stride, src0, src1, src2, src3, src4, src5, src6, src7); 1008cabdff1aSopenharmony_ci TRANSPOSE8x4_UB_UH(src0, src1, src2, src3, src4, src5, src6, src7, 1009cabdff1aSopenharmony_ci p1, p0, q0, q1); 1010cabdff1aSopenharmony_ci ILVR_B4_UH(zero, p1, zero, p0, zero, q0, zero, q1, p1, p0, q0, q1); 1011cabdff1aSopenharmony_ci 1012cabdff1aSopenharmony_ci temp0 = (v8i16) (q0 - p0); 1013cabdff1aSopenharmony_ci temp1 = (v8i16) (p1 - q1); 1014cabdff1aSopenharmony_ci temp0 <<= 2; 1015cabdff1aSopenharmony_ci temp0 += temp1; 1016cabdff1aSopenharmony_ci delta = __msa_srari_h((v8i16) temp0, 3); 1017cabdff1aSopenharmony_ci CLIP_SH(delta, tc_neg, tc_pos); 1018cabdff1aSopenharmony_ci 1019cabdff1aSopenharmony_ci temp0 = (v8i16) ((v8i16) p0 + delta); 1020cabdff1aSopenharmony_ci CLIP_SH_0_255(temp0); 1021cabdff1aSopenharmony_ci temp0 = (v8i16) __msa_bmz_v((v16u8) temp0, (v16u8) p0, 1022cabdff1aSopenharmony_ci (v16u8) p_is_pcm_vec); 1023cabdff1aSopenharmony_ci 1024cabdff1aSopenharmony_ci temp1 = (v8i16) ((v8i16) q0 - delta); 1025cabdff1aSopenharmony_ci CLIP_SH_0_255(temp1); 1026cabdff1aSopenharmony_ci temp1 = (v8i16) __msa_bmz_v((v16u8) temp1, (v16u8) q0, 1027cabdff1aSopenharmony_ci (v16u8) q_is_pcm_vec); 1028cabdff1aSopenharmony_ci 1029cabdff1aSopenharmony_ci tc_pos = (v8i16) __msa_clei_s_d((v2i64) tc_pos, 0); 1030cabdff1aSopenharmony_ci temp0 = (v8i16) __msa_bmnz_v((v16u8) temp0, (v16u8) p0, (v16u8) tc_pos); 1031cabdff1aSopenharmony_ci temp1 = (v8i16) __msa_bmnz_v((v16u8) temp1, (v16u8) q0, (v16u8) tc_pos); 1032cabdff1aSopenharmony_ci 1033cabdff1aSopenharmony_ci temp0 = (v8i16) __msa_ilvev_b((v16i8) temp1, (v16i8) temp0); 1034cabdff1aSopenharmony_ci 1035cabdff1aSopenharmony_ci src += 1; 1036cabdff1aSopenharmony_ci ST_H8(temp0, 0, 1, 2, 3, 4, 5, 6, 7, src, stride); 1037cabdff1aSopenharmony_ci } 1038cabdff1aSopenharmony_ci} 1039cabdff1aSopenharmony_ci 1040cabdff1aSopenharmony_cistatic void hevc_sao_band_filter_4width_msa(uint8_t *dst, int32_t dst_stride, 1041cabdff1aSopenharmony_ci uint8_t *src, int32_t src_stride, 1042cabdff1aSopenharmony_ci int32_t sao_left_class, 1043cabdff1aSopenharmony_ci int16_t *sao_offset_val, 1044cabdff1aSopenharmony_ci int32_t height) 1045cabdff1aSopenharmony_ci{ 1046cabdff1aSopenharmony_ci v16u8 src0, src1, src2, src3; 1047cabdff1aSopenharmony_ci v16i8 src0_r, src1_r; 1048cabdff1aSopenharmony_ci v16i8 offset, offset_val, mask; 1049cabdff1aSopenharmony_ci v16i8 dst0, offset0, offset1; 1050cabdff1aSopenharmony_ci v16i8 zero = { 0 }; 1051cabdff1aSopenharmony_ci 1052cabdff1aSopenharmony_ci offset_val = LD_SB(sao_offset_val + 1); 1053cabdff1aSopenharmony_ci offset_val = (v16i8) __msa_pckev_d((v2i64) offset_val, (v2i64) offset_val); 1054cabdff1aSopenharmony_ci 1055cabdff1aSopenharmony_ci offset_val = __msa_pckev_b(offset_val, offset_val); 1056cabdff1aSopenharmony_ci offset1 = (v16i8) __msa_insve_w((v4i32) zero, 3, (v4i32) offset_val); 1057cabdff1aSopenharmony_ci offset0 = __msa_sld_b(offset1, zero, 28 - ((sao_left_class) & 31)); 1058cabdff1aSopenharmony_ci offset1 = __msa_sld_b(zero, offset1, 28 - ((sao_left_class) & 31)); 1059cabdff1aSopenharmony_ci 1060cabdff1aSopenharmony_ci /* load in advance. */ 1061cabdff1aSopenharmony_ci LD_UB4(src, src_stride, src0, src1, src2, src3); 1062cabdff1aSopenharmony_ci 1063cabdff1aSopenharmony_ci if (!((sao_left_class > 12) & (sao_left_class < 29))) { 1064cabdff1aSopenharmony_ci SWAP(offset0, offset1); 1065cabdff1aSopenharmony_ci } 1066cabdff1aSopenharmony_ci 1067cabdff1aSopenharmony_ci for (height -= 4; height; height -= 4) { 1068cabdff1aSopenharmony_ci src += (4 * src_stride); 1069cabdff1aSopenharmony_ci 1070cabdff1aSopenharmony_ci ILVEV_D2_SB(src0, src1, src2, src3, src0_r, src1_r); 1071cabdff1aSopenharmony_ci 1072cabdff1aSopenharmony_ci src0_r = (v16i8) __msa_pckev_w((v4i32) src1_r, (v4i32) src0_r); 1073cabdff1aSopenharmony_ci mask = __msa_srli_b(src0_r, 3); 1074cabdff1aSopenharmony_ci offset = __msa_vshf_b(mask, offset1, offset0); 1075cabdff1aSopenharmony_ci 1076cabdff1aSopenharmony_ci src0_r = (v16i8) __msa_xori_b((v16u8) src0_r, 128); 1077cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(src0_r, offset); 1078cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1079cabdff1aSopenharmony_ci 1080cabdff1aSopenharmony_ci /* load in advance. */ 1081cabdff1aSopenharmony_ci LD_UB4(src, src_stride, src0, src1, src2, src3); 1082cabdff1aSopenharmony_ci 1083cabdff1aSopenharmony_ci /* store results */ 1084cabdff1aSopenharmony_ci ST_W4(dst0, 0, 1, 2, 3, dst, dst_stride); 1085cabdff1aSopenharmony_ci dst += (4 * dst_stride); 1086cabdff1aSopenharmony_ci } 1087cabdff1aSopenharmony_ci 1088cabdff1aSopenharmony_ci ILVEV_D2_SB(src0, src1, src2, src3, src0_r, src1_r); 1089cabdff1aSopenharmony_ci 1090cabdff1aSopenharmony_ci src0_r = (v16i8) __msa_pckev_w((v4i32) src1_r, (v4i32) src0_r); 1091cabdff1aSopenharmony_ci mask = __msa_srli_b(src0_r, 3); 1092cabdff1aSopenharmony_ci offset = __msa_vshf_b(mask, offset1, offset0); 1093cabdff1aSopenharmony_ci 1094cabdff1aSopenharmony_ci src0_r = (v16i8) __msa_xori_b((v16u8) src0_r, 128); 1095cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(src0_r, offset); 1096cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1097cabdff1aSopenharmony_ci 1098cabdff1aSopenharmony_ci /* store results */ 1099cabdff1aSopenharmony_ci ST_W4(dst0, 0, 1, 2, 3, dst, dst_stride); 1100cabdff1aSopenharmony_ci} 1101cabdff1aSopenharmony_ci 1102cabdff1aSopenharmony_cistatic void hevc_sao_band_filter_8width_msa(uint8_t *dst, int32_t dst_stride, 1103cabdff1aSopenharmony_ci uint8_t *src, int32_t src_stride, 1104cabdff1aSopenharmony_ci int32_t sao_left_class, 1105cabdff1aSopenharmony_ci int16_t *sao_offset_val, 1106cabdff1aSopenharmony_ci int32_t height) 1107cabdff1aSopenharmony_ci{ 1108cabdff1aSopenharmony_ci v16u8 src0, src1, src2, src3; 1109cabdff1aSopenharmony_ci v16i8 src0_r, src1_r, mask0, mask1; 1110cabdff1aSopenharmony_ci v16i8 offset_mask0, offset_mask1, offset_val; 1111cabdff1aSopenharmony_ci v16i8 offset0, offset1, dst0, dst1; 1112cabdff1aSopenharmony_ci v16i8 zero = { 0 }; 1113cabdff1aSopenharmony_ci 1114cabdff1aSopenharmony_ci offset_val = LD_SB(sao_offset_val + 1); 1115cabdff1aSopenharmony_ci offset_val = (v16i8) __msa_pckev_d((v2i64) offset_val, (v2i64) offset_val); 1116cabdff1aSopenharmony_ci offset_val = __msa_pckev_b(offset_val, offset_val); 1117cabdff1aSopenharmony_ci offset1 = (v16i8) __msa_insve_w((v4i32) zero, 3, (v4i32) offset_val); 1118cabdff1aSopenharmony_ci offset0 = __msa_sld_b(offset1, zero, 28 - ((sao_left_class) & 31)); 1119cabdff1aSopenharmony_ci offset1 = __msa_sld_b(zero, offset1, 28 - ((sao_left_class) & 31)); 1120cabdff1aSopenharmony_ci 1121cabdff1aSopenharmony_ci /* load in advance. */ 1122cabdff1aSopenharmony_ci LD_UB4(src, src_stride, src0, src1, src2, src3); 1123cabdff1aSopenharmony_ci 1124cabdff1aSopenharmony_ci if (!((sao_left_class > 12) & (sao_left_class < 29))) { 1125cabdff1aSopenharmony_ci SWAP(offset0, offset1); 1126cabdff1aSopenharmony_ci } 1127cabdff1aSopenharmony_ci 1128cabdff1aSopenharmony_ci for (height -= 4; height; height -= 4) { 1129cabdff1aSopenharmony_ci src += src_stride << 2; 1130cabdff1aSopenharmony_ci 1131cabdff1aSopenharmony_ci ILVR_D2_SB(src1, src0, src3, src2, src0_r, src1_r); 1132cabdff1aSopenharmony_ci 1133cabdff1aSopenharmony_ci mask0 = __msa_srli_b(src0_r, 3); 1134cabdff1aSopenharmony_ci mask1 = __msa_srli_b(src1_r, 3); 1135cabdff1aSopenharmony_ci 1136cabdff1aSopenharmony_ci offset_mask0 = __msa_vshf_b(mask0, offset1, offset0); 1137cabdff1aSopenharmony_ci offset_mask1 = __msa_vshf_b(mask1, offset1, offset0); 1138cabdff1aSopenharmony_ci 1139cabdff1aSopenharmony_ci /* load in advance. */ 1140cabdff1aSopenharmony_ci LD_UB4(src, src_stride, src0, src1, src2, src3); 1141cabdff1aSopenharmony_ci 1142cabdff1aSopenharmony_ci XORI_B2_128_SB(src0_r, src1_r); 1143cabdff1aSopenharmony_ci 1144cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(src0_r, offset_mask0); 1145cabdff1aSopenharmony_ci dst1 = __msa_adds_s_b(src1_r, offset_mask1); 1146cabdff1aSopenharmony_ci 1147cabdff1aSopenharmony_ci XORI_B2_128_SB(dst0, dst1); 1148cabdff1aSopenharmony_ci 1149cabdff1aSopenharmony_ci /* store results */ 1150cabdff1aSopenharmony_ci ST_D4(dst0, dst1, 0, 1, 0, 1, dst, dst_stride); 1151cabdff1aSopenharmony_ci dst += dst_stride << 2; 1152cabdff1aSopenharmony_ci } 1153cabdff1aSopenharmony_ci 1154cabdff1aSopenharmony_ci ILVR_D2_SB(src1, src0, src3, src2, src0_r, src1_r); 1155cabdff1aSopenharmony_ci 1156cabdff1aSopenharmony_ci mask0 = __msa_srli_b(src0_r, 3); 1157cabdff1aSopenharmony_ci mask1 = __msa_srli_b(src1_r, 3); 1158cabdff1aSopenharmony_ci 1159cabdff1aSopenharmony_ci offset_mask0 = __msa_vshf_b(mask0, offset1, offset0); 1160cabdff1aSopenharmony_ci offset_mask1 = __msa_vshf_b(mask1, offset1, offset0); 1161cabdff1aSopenharmony_ci 1162cabdff1aSopenharmony_ci XORI_B2_128_SB(src0_r, src1_r); 1163cabdff1aSopenharmony_ci 1164cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(src0_r, offset_mask0); 1165cabdff1aSopenharmony_ci dst1 = __msa_adds_s_b(src1_r, offset_mask1); 1166cabdff1aSopenharmony_ci 1167cabdff1aSopenharmony_ci XORI_B2_128_SB(dst0, dst1); 1168cabdff1aSopenharmony_ci 1169cabdff1aSopenharmony_ci /* store results */ 1170cabdff1aSopenharmony_ci ST_D4(dst0, dst1, 0, 1, 0, 1, dst, dst_stride); 1171cabdff1aSopenharmony_ci} 1172cabdff1aSopenharmony_ci 1173cabdff1aSopenharmony_cistatic void hevc_sao_band_filter_16multiple_msa(uint8_t *dst, 1174cabdff1aSopenharmony_ci int32_t dst_stride, 1175cabdff1aSopenharmony_ci uint8_t *src, 1176cabdff1aSopenharmony_ci int32_t src_stride, 1177cabdff1aSopenharmony_ci int32_t sao_left_class, 1178cabdff1aSopenharmony_ci int16_t *sao_offset_val, 1179cabdff1aSopenharmony_ci int32_t width, int32_t height) 1180cabdff1aSopenharmony_ci{ 1181cabdff1aSopenharmony_ci int32_t w_cnt; 1182cabdff1aSopenharmony_ci v16u8 src0, src1, src2, src3; 1183cabdff1aSopenharmony_ci v16i8 out0, out1, out2, out3; 1184cabdff1aSopenharmony_ci v16i8 mask0, mask1, mask2, mask3; 1185cabdff1aSopenharmony_ci v16i8 tmp0, tmp1, tmp2, tmp3, offset_val; 1186cabdff1aSopenharmony_ci v16i8 offset0, offset1; 1187cabdff1aSopenharmony_ci v16i8 zero = { 0 }; 1188cabdff1aSopenharmony_ci 1189cabdff1aSopenharmony_ci offset_val = LD_SB(sao_offset_val + 1); 1190cabdff1aSopenharmony_ci offset_val = (v16i8) __msa_pckev_d((v2i64) offset_val, (v2i64) offset_val); 1191cabdff1aSopenharmony_ci offset_val = __msa_pckev_b(offset_val, offset_val); 1192cabdff1aSopenharmony_ci offset1 = (v16i8) __msa_insve_w((v4i32) zero, 3, (v4i32) offset_val); 1193cabdff1aSopenharmony_ci offset0 = __msa_sld_b(offset1, zero, 28 - ((sao_left_class) & 31)); 1194cabdff1aSopenharmony_ci offset1 = __msa_sld_b(zero, offset1, 28 - ((sao_left_class) & 31)); 1195cabdff1aSopenharmony_ci 1196cabdff1aSopenharmony_ci if (!((sao_left_class > 12) & (sao_left_class < 29))) { 1197cabdff1aSopenharmony_ci SWAP(offset0, offset1); 1198cabdff1aSopenharmony_ci } 1199cabdff1aSopenharmony_ci 1200cabdff1aSopenharmony_ci while (height > 0) { 1201cabdff1aSopenharmony_ci /* load in advance */ 1202cabdff1aSopenharmony_ci LD_UB4(src, src_stride, src0, src1, src2, src3); 1203cabdff1aSopenharmony_ci 1204cabdff1aSopenharmony_ci for (w_cnt = 16; w_cnt < width; w_cnt += 16) { 1205cabdff1aSopenharmony_ci mask0 = __msa_srli_b((v16i8) src0, 3); 1206cabdff1aSopenharmony_ci mask1 = __msa_srli_b((v16i8) src1, 3); 1207cabdff1aSopenharmony_ci mask2 = __msa_srli_b((v16i8) src2, 3); 1208cabdff1aSopenharmony_ci mask3 = __msa_srli_b((v16i8) src3, 3); 1209cabdff1aSopenharmony_ci 1210cabdff1aSopenharmony_ci VSHF_B2_SB(offset0, offset1, offset0, offset1, mask0, mask1, 1211cabdff1aSopenharmony_ci tmp0, tmp1); 1212cabdff1aSopenharmony_ci VSHF_B2_SB(offset0, offset1, offset0, offset1, mask2, mask3, 1213cabdff1aSopenharmony_ci tmp2, tmp3); 1214cabdff1aSopenharmony_ci XORI_B4_128_UB(src0, src1, src2, src3); 1215cabdff1aSopenharmony_ci 1216cabdff1aSopenharmony_ci out0 = __msa_adds_s_b((v16i8) src0, tmp0); 1217cabdff1aSopenharmony_ci out1 = __msa_adds_s_b((v16i8) src1, tmp1); 1218cabdff1aSopenharmony_ci out2 = __msa_adds_s_b((v16i8) src2, tmp2); 1219cabdff1aSopenharmony_ci out3 = __msa_adds_s_b((v16i8) src3, tmp3); 1220cabdff1aSopenharmony_ci 1221cabdff1aSopenharmony_ci /* load for next iteration */ 1222cabdff1aSopenharmony_ci LD_UB4(src + w_cnt, src_stride, src0, src1, src2, src3); 1223cabdff1aSopenharmony_ci 1224cabdff1aSopenharmony_ci XORI_B4_128_SB(out0, out1, out2, out3); 1225cabdff1aSopenharmony_ci 1226cabdff1aSopenharmony_ci ST_SB4(out0, out1, out2, out3, dst + w_cnt - 16, dst_stride); 1227cabdff1aSopenharmony_ci } 1228cabdff1aSopenharmony_ci 1229cabdff1aSopenharmony_ci mask0 = __msa_srli_b((v16i8) src0, 3); 1230cabdff1aSopenharmony_ci mask1 = __msa_srli_b((v16i8) src1, 3); 1231cabdff1aSopenharmony_ci mask2 = __msa_srli_b((v16i8) src2, 3); 1232cabdff1aSopenharmony_ci mask3 = __msa_srli_b((v16i8) src3, 3); 1233cabdff1aSopenharmony_ci 1234cabdff1aSopenharmony_ci VSHF_B2_SB(offset0, offset1, offset0, offset1, mask0, mask1, tmp0, 1235cabdff1aSopenharmony_ci tmp1); 1236cabdff1aSopenharmony_ci VSHF_B2_SB(offset0, offset1, offset0, offset1, mask2, mask3, tmp2, 1237cabdff1aSopenharmony_ci tmp3); 1238cabdff1aSopenharmony_ci XORI_B4_128_UB(src0, src1, src2, src3); 1239cabdff1aSopenharmony_ci 1240cabdff1aSopenharmony_ci out0 = __msa_adds_s_b((v16i8) src0, tmp0); 1241cabdff1aSopenharmony_ci out1 = __msa_adds_s_b((v16i8) src1, tmp1); 1242cabdff1aSopenharmony_ci out2 = __msa_adds_s_b((v16i8) src2, tmp2); 1243cabdff1aSopenharmony_ci out3 = __msa_adds_s_b((v16i8) src3, tmp3); 1244cabdff1aSopenharmony_ci 1245cabdff1aSopenharmony_ci XORI_B4_128_SB(out0, out1, out2, out3); 1246cabdff1aSopenharmony_ci 1247cabdff1aSopenharmony_ci ST_SB4(out0, out1, out2, out3, dst + w_cnt - 16, dst_stride); 1248cabdff1aSopenharmony_ci 1249cabdff1aSopenharmony_ci src += src_stride << 2; 1250cabdff1aSopenharmony_ci dst += dst_stride << 2; 1251cabdff1aSopenharmony_ci height -= 4; 1252cabdff1aSopenharmony_ci } 1253cabdff1aSopenharmony_ci} 1254cabdff1aSopenharmony_ci 1255cabdff1aSopenharmony_cistatic void hevc_sao_edge_filter_0degree_4width_msa(uint8_t *dst, 1256cabdff1aSopenharmony_ci int32_t dst_stride, 1257cabdff1aSopenharmony_ci uint8_t *src, 1258cabdff1aSopenharmony_ci int32_t src_stride, 1259cabdff1aSopenharmony_ci int16_t *sao_offset_val, 1260cabdff1aSopenharmony_ci int32_t height) 1261cabdff1aSopenharmony_ci{ 1262cabdff1aSopenharmony_ci uint32_t dst_val0, dst_val1; 1263cabdff1aSopenharmony_ci v16u8 cmp_minus10, diff_minus10, diff_minus11, src_minus10, src_minus11; 1264cabdff1aSopenharmony_ci v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1265cabdff1aSopenharmony_ci v16i8 sao_offset = LD_SB(sao_offset_val); 1266cabdff1aSopenharmony_ci v16i8 src_plus10, offset, src0, dst0; 1267cabdff1aSopenharmony_ci v16u8 const1 = (v16u8) __msa_ldi_b(1); 1268cabdff1aSopenharmony_ci v16i8 zero = { 0 }; 1269cabdff1aSopenharmony_ci 1270cabdff1aSopenharmony_ci sao_offset = __msa_pckev_b(sao_offset, sao_offset); 1271cabdff1aSopenharmony_ci src -= 1; 1272cabdff1aSopenharmony_ci 1273cabdff1aSopenharmony_ci /* load in advance */ 1274cabdff1aSopenharmony_ci LD_UB2(src, src_stride, src_minus10, src_minus11); 1275cabdff1aSopenharmony_ci 1276cabdff1aSopenharmony_ci for (height -= 2; height; height -= 2) { 1277cabdff1aSopenharmony_ci src += (2 * src_stride); 1278cabdff1aSopenharmony_ci 1279cabdff1aSopenharmony_ci src_minus10 = (v16u8) __msa_pckev_d((v2i64) src_minus11, 1280cabdff1aSopenharmony_ci (v2i64) src_minus10); 1281cabdff1aSopenharmony_ci 1282cabdff1aSopenharmony_ci src0 = (v16i8) __msa_sldi_b(zero, (v16i8) src_minus10, 1); 1283cabdff1aSopenharmony_ci src_plus10 = (v16i8) __msa_sldi_b(zero, (v16i8) src_minus10, 2); 1284cabdff1aSopenharmony_ci 1285cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src0 == src_minus10); 1286cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 1287cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src0); 1288cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 1289cabdff1aSopenharmony_ci 1290cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src0 == (v16u8) src_plus10); 1291cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus10, cmp_minus10); 1292cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_plus10 < (v16u8) src0); 1293cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus10); 1294cabdff1aSopenharmony_ci 1295cabdff1aSopenharmony_ci offset = (v16i8) diff_minus10 + (v16i8) diff_minus11 + 2; 1296cabdff1aSopenharmony_ci 1297cabdff1aSopenharmony_ci /* load in advance */ 1298cabdff1aSopenharmony_ci LD_UB2(src, src_stride, src_minus10, src_minus11); 1299cabdff1aSopenharmony_ci 1300cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, 1301cabdff1aSopenharmony_ci offset, offset); 1302cabdff1aSopenharmony_ci 1303cabdff1aSopenharmony_ci src0 = (v16i8) __msa_xori_b((v16u8) src0, 128); 1304cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(src0, offset); 1305cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1306cabdff1aSopenharmony_ci 1307cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); 1308cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); 1309cabdff1aSopenharmony_ci SW(dst_val0, dst); 1310cabdff1aSopenharmony_ci dst += dst_stride; 1311cabdff1aSopenharmony_ci SW(dst_val1, dst); 1312cabdff1aSopenharmony_ci dst += dst_stride; 1313cabdff1aSopenharmony_ci } 1314cabdff1aSopenharmony_ci 1315cabdff1aSopenharmony_ci src_minus10 = (v16u8) __msa_pckev_d((v2i64) src_minus11, 1316cabdff1aSopenharmony_ci (v2i64) src_minus10); 1317cabdff1aSopenharmony_ci 1318cabdff1aSopenharmony_ci src0 = (v16i8) __msa_sldi_b(zero, (v16i8) src_minus10, 1); 1319cabdff1aSopenharmony_ci src_plus10 = (v16i8) __msa_sldi_b(zero, (v16i8) src_minus10, 2); 1320cabdff1aSopenharmony_ci 1321cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src0 == src_minus10); 1322cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 1323cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src0); 1324cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 1325cabdff1aSopenharmony_ci 1326cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src0 == (v16u8) src_plus10); 1327cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus10, cmp_minus10); 1328cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_plus10 < (v16u8) src0); 1329cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus10); 1330cabdff1aSopenharmony_ci 1331cabdff1aSopenharmony_ci offset = (v16i8) diff_minus10 + (v16i8) diff_minus11 + 2; 1332cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, 1333cabdff1aSopenharmony_ci offset, offset); 1334cabdff1aSopenharmony_ci 1335cabdff1aSopenharmony_ci src0 = (v16i8) __msa_xori_b((v16u8) src0, 128); 1336cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(src0, offset); 1337cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1338cabdff1aSopenharmony_ci 1339cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); 1340cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); 1341cabdff1aSopenharmony_ci 1342cabdff1aSopenharmony_ci SW(dst_val0, dst); 1343cabdff1aSopenharmony_ci dst += dst_stride; 1344cabdff1aSopenharmony_ci SW(dst_val1, dst); 1345cabdff1aSopenharmony_ci} 1346cabdff1aSopenharmony_ci 1347cabdff1aSopenharmony_cistatic void hevc_sao_edge_filter_0degree_8width_msa(uint8_t *dst, 1348cabdff1aSopenharmony_ci int32_t dst_stride, 1349cabdff1aSopenharmony_ci uint8_t *src, 1350cabdff1aSopenharmony_ci int32_t src_stride, 1351cabdff1aSopenharmony_ci int16_t *sao_offset_val, 1352cabdff1aSopenharmony_ci int32_t height) 1353cabdff1aSopenharmony_ci{ 1354cabdff1aSopenharmony_ci uint64_t dst_val0, dst_val1; 1355cabdff1aSopenharmony_ci v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1356cabdff1aSopenharmony_ci v16u8 const1 = (v16u8) __msa_ldi_b(1); 1357cabdff1aSopenharmony_ci v16u8 cmp_minus10, diff_minus10, diff_minus11; 1358cabdff1aSopenharmony_ci v16u8 src0, src1, dst0, src_minus10, src_minus11, src_plus10, src_plus11; 1359cabdff1aSopenharmony_ci v16i8 offset, sao_offset = LD_SB(sao_offset_val); 1360cabdff1aSopenharmony_ci v16i8 zeros = { 0 }; 1361cabdff1aSopenharmony_ci 1362cabdff1aSopenharmony_ci sao_offset = __msa_pckev_b(sao_offset, sao_offset); 1363cabdff1aSopenharmony_ci src -= 1; 1364cabdff1aSopenharmony_ci 1365cabdff1aSopenharmony_ci /* load in advance */ 1366cabdff1aSopenharmony_ci LD_UB2(src, src_stride, src_minus10, src_minus11); 1367cabdff1aSopenharmony_ci 1368cabdff1aSopenharmony_ci for (height -= 2; height; height -= 2) { 1369cabdff1aSopenharmony_ci src += (src_stride << 1); 1370cabdff1aSopenharmony_ci 1371cabdff1aSopenharmony_ci SLDI_B2_UB(zeros, src_minus10, zeros, src_minus11, 1, src0, src1); 1372cabdff1aSopenharmony_ci SLDI_B2_UB(zeros, src_minus10, zeros, src_minus11, 2, src_plus10, src_plus11); 1373cabdff1aSopenharmony_ci 1374cabdff1aSopenharmony_ci PCKEV_D2_UB(src_minus11, src_minus10, src_plus11, src_plus10, 1375cabdff1aSopenharmony_ci src_minus10, src_plus10); 1376cabdff1aSopenharmony_ci src0 = (v16u8) __msa_pckev_d((v2i64) src1, (v2i64) src0); 1377cabdff1aSopenharmony_ci 1378cabdff1aSopenharmony_ci cmp_minus10 = (src0 == src_minus10); 1379cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 1380cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < src0); 1381cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 1382cabdff1aSopenharmony_ci 1383cabdff1aSopenharmony_ci cmp_minus10 = (src0 == src_plus10); 1384cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus10, cmp_minus10); 1385cabdff1aSopenharmony_ci cmp_minus10 = (src_plus10 < src0); 1386cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus10); 1387cabdff1aSopenharmony_ci 1388cabdff1aSopenharmony_ci offset = (v16i8) diff_minus10 + (v16i8) diff_minus11 + 2; 1389cabdff1aSopenharmony_ci 1390cabdff1aSopenharmony_ci /* load in advance */ 1391cabdff1aSopenharmony_ci LD_UB2(src, src_stride, src_minus10, src_minus11); 1392cabdff1aSopenharmony_ci 1393cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, 1394cabdff1aSopenharmony_ci offset, offset); 1395cabdff1aSopenharmony_ci 1396cabdff1aSopenharmony_ci src0 = __msa_xori_b(src0, 128); 1397cabdff1aSopenharmony_ci dst0 = (v16u8) __msa_adds_s_b((v16i8) src0, offset); 1398cabdff1aSopenharmony_ci dst0 = __msa_xori_b(dst0, 128); 1399cabdff1aSopenharmony_ci 1400cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); 1401cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); 1402cabdff1aSopenharmony_ci SD(dst_val0, dst); 1403cabdff1aSopenharmony_ci dst += dst_stride; 1404cabdff1aSopenharmony_ci SD(dst_val1, dst); 1405cabdff1aSopenharmony_ci dst += dst_stride; 1406cabdff1aSopenharmony_ci } 1407cabdff1aSopenharmony_ci 1408cabdff1aSopenharmony_ci SLDI_B2_UB(zeros, src_minus10, zeros, src_minus11, 1, src0, src1); 1409cabdff1aSopenharmony_ci SLDI_B2_UB(zeros, src_minus10, zeros, src_minus11, 2, src_plus10, src_plus11); 1410cabdff1aSopenharmony_ci 1411cabdff1aSopenharmony_ci PCKEV_D2_UB(src_minus11, src_minus10, src_plus11, src_plus10, src_minus10, 1412cabdff1aSopenharmony_ci src_plus10); 1413cabdff1aSopenharmony_ci src0 = (v16u8) __msa_pckev_d((v2i64) src1, (v2i64) src0); 1414cabdff1aSopenharmony_ci 1415cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src0 == src_minus10); 1416cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 1417cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src0); 1418cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 1419cabdff1aSopenharmony_ci 1420cabdff1aSopenharmony_ci cmp_minus10 = (src0 == src_plus10); 1421cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus10, cmp_minus10); 1422cabdff1aSopenharmony_ci cmp_minus10 = (src_plus10 < src0); 1423cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus10); 1424cabdff1aSopenharmony_ci 1425cabdff1aSopenharmony_ci offset = (v16i8) diff_minus10 + (v16i8) diff_minus11 + 2; 1426cabdff1aSopenharmony_ci 1427cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, 1428cabdff1aSopenharmony_ci offset, offset); 1429cabdff1aSopenharmony_ci 1430cabdff1aSopenharmony_ci src0 = __msa_xori_b(src0, 128); 1431cabdff1aSopenharmony_ci dst0 = (v16u8) __msa_adds_s_b((v16i8) src0, offset); 1432cabdff1aSopenharmony_ci dst0 = __msa_xori_b(dst0, 128); 1433cabdff1aSopenharmony_ci 1434cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); 1435cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); 1436cabdff1aSopenharmony_ci SD(dst_val0, dst); 1437cabdff1aSopenharmony_ci dst += dst_stride; 1438cabdff1aSopenharmony_ci SD(dst_val1, dst); 1439cabdff1aSopenharmony_ci} 1440cabdff1aSopenharmony_ci 1441cabdff1aSopenharmony_cistatic void hevc_sao_edge_filter_0degree_16multiple_msa(uint8_t *dst, 1442cabdff1aSopenharmony_ci int32_t dst_stride, 1443cabdff1aSopenharmony_ci uint8_t *src, 1444cabdff1aSopenharmony_ci int32_t src_stride, 1445cabdff1aSopenharmony_ci int16_t *sao_offset_val, 1446cabdff1aSopenharmony_ci int32_t width, 1447cabdff1aSopenharmony_ci int32_t height) 1448cabdff1aSopenharmony_ci{ 1449cabdff1aSopenharmony_ci uint8_t *dst_ptr, *src_minus1; 1450cabdff1aSopenharmony_ci int32_t v_cnt; 1451cabdff1aSopenharmony_ci v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1452cabdff1aSopenharmony_ci v16u8 const1 = (v16u8) __msa_ldi_b(1); 1453cabdff1aSopenharmony_ci v16i8 sao_offset; 1454cabdff1aSopenharmony_ci v16u8 cmp_minus10, cmp_plus10, diff_minus10, diff_plus10, cmp_minus11; 1455cabdff1aSopenharmony_ci v16u8 cmp_plus11, diff_minus11, diff_plus11, cmp_minus12, cmp_plus12; 1456cabdff1aSopenharmony_ci v16u8 diff_minus12, diff_plus12, cmp_minus13, cmp_plus13, diff_minus13; 1457cabdff1aSopenharmony_ci v16u8 diff_plus13; 1458cabdff1aSopenharmony_ci v16u8 src10, src11, src12, src13, dst0, dst1, dst2, dst3; 1459cabdff1aSopenharmony_ci v16u8 src_minus10, src_minus11, src_minus12, src_minus13; 1460cabdff1aSopenharmony_ci v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3; 1461cabdff1aSopenharmony_ci v16i8 src_zero0, src_zero1, src_zero2, src_zero3; 1462cabdff1aSopenharmony_ci v16i8 src_plus10, src_plus11, src_plus12, src_plus13; 1463cabdff1aSopenharmony_ci 1464cabdff1aSopenharmony_ci sao_offset = LD_SB(sao_offset_val); 1465cabdff1aSopenharmony_ci sao_offset = __msa_pckev_b(sao_offset, sao_offset); 1466cabdff1aSopenharmony_ci 1467cabdff1aSopenharmony_ci for (; height; height -= 4) { 1468cabdff1aSopenharmony_ci src_minus1 = src - 1; 1469cabdff1aSopenharmony_ci LD_UB4(src_minus1, src_stride, 1470cabdff1aSopenharmony_ci src_minus10, src_minus11, src_minus12, src_minus13); 1471cabdff1aSopenharmony_ci 1472cabdff1aSopenharmony_ci for (v_cnt = 0; v_cnt < width; v_cnt += 16) { 1473cabdff1aSopenharmony_ci src_minus1 += 16; 1474cabdff1aSopenharmony_ci dst_ptr = dst + v_cnt; 1475cabdff1aSopenharmony_ci LD_UB4(src_minus1, src_stride, src10, src11, src12, src13); 1476cabdff1aSopenharmony_ci 1477cabdff1aSopenharmony_ci SLDI_B4_SB(src10, src_minus10, src11, src_minus11, 1478cabdff1aSopenharmony_ci src12, src_minus12, src13, src_minus13, 1, 1479cabdff1aSopenharmony_ci src_zero0, src_zero1, src_zero2, src_zero3); 1480cabdff1aSopenharmony_ci SLDI_B4_SB(src10, src_minus10, src11, src_minus11, 1481cabdff1aSopenharmony_ci src12, src_minus12, src13, src_minus13, 2, 1482cabdff1aSopenharmony_ci src_plus10, src_plus11, src_plus12, src_plus13); 1483cabdff1aSopenharmony_ci 1484cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 1485cabdff1aSopenharmony_ci cmp_plus10 = ((v16u8) src_zero0 == (v16u8) src_plus10); 1486cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 1487cabdff1aSopenharmony_ci cmp_plus11 = ((v16u8) src_zero1 == (v16u8) src_plus11); 1488cabdff1aSopenharmony_ci cmp_minus12 = ((v16u8) src_zero2 == src_minus12); 1489cabdff1aSopenharmony_ci cmp_plus12 = ((v16u8) src_zero2 == (v16u8) src_plus12); 1490cabdff1aSopenharmony_ci cmp_minus13 = ((v16u8) src_zero3 == src_minus13); 1491cabdff1aSopenharmony_ci cmp_plus13 = ((v16u8) src_zero3 == (v16u8) src_plus13); 1492cabdff1aSopenharmony_ci 1493cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 1494cabdff1aSopenharmony_ci diff_plus10 = __msa_nor_v(cmp_plus10, cmp_plus10); 1495cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 1496cabdff1aSopenharmony_ci diff_plus11 = __msa_nor_v(cmp_plus11, cmp_plus11); 1497cabdff1aSopenharmony_ci diff_minus12 = __msa_nor_v(cmp_minus12, cmp_minus12); 1498cabdff1aSopenharmony_ci diff_plus12 = __msa_nor_v(cmp_plus12, cmp_plus12); 1499cabdff1aSopenharmony_ci diff_minus13 = __msa_nor_v(cmp_minus13, cmp_minus13); 1500cabdff1aSopenharmony_ci diff_plus13 = __msa_nor_v(cmp_plus13, cmp_plus13); 1501cabdff1aSopenharmony_ci 1502cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 1503cabdff1aSopenharmony_ci cmp_plus10 = ((v16u8) src_plus10 < (v16u8) src_zero0); 1504cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 1505cabdff1aSopenharmony_ci cmp_plus11 = ((v16u8) src_plus11 < (v16u8) src_zero1); 1506cabdff1aSopenharmony_ci cmp_minus12 = (src_minus12 < (v16u8) src_zero2); 1507cabdff1aSopenharmony_ci cmp_plus12 = ((v16u8) src_plus12 < (v16u8) src_zero2); 1508cabdff1aSopenharmony_ci cmp_minus13 = (src_minus13 < (v16u8) src_zero3); 1509cabdff1aSopenharmony_ci cmp_plus13 = ((v16u8) src_plus13 < (v16u8) src_zero3); 1510cabdff1aSopenharmony_ci 1511cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 1512cabdff1aSopenharmony_ci diff_plus10 = __msa_bmnz_v(diff_plus10, const1, cmp_plus10); 1513cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 1514cabdff1aSopenharmony_ci diff_plus11 = __msa_bmnz_v(diff_plus11, const1, cmp_plus11); 1515cabdff1aSopenharmony_ci diff_minus12 = __msa_bmnz_v(diff_minus12, const1, cmp_minus12); 1516cabdff1aSopenharmony_ci diff_plus12 = __msa_bmnz_v(diff_plus12, const1, cmp_plus12); 1517cabdff1aSopenharmony_ci diff_minus13 = __msa_bmnz_v(diff_minus13, const1, cmp_minus13); 1518cabdff1aSopenharmony_ci diff_plus13 = __msa_bmnz_v(diff_plus13, const1, cmp_plus13); 1519cabdff1aSopenharmony_ci 1520cabdff1aSopenharmony_ci offset_mask0 = 2 + (v16i8) diff_minus10 + (v16i8) diff_plus10; 1521cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0, 1522cabdff1aSopenharmony_ci offset_mask0, offset_mask0, offset_mask0); 1523cabdff1aSopenharmony_ci offset_mask1 = 2 + (v16i8) diff_minus11 + (v16i8) diff_plus11; 1524cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1, 1525cabdff1aSopenharmony_ci offset_mask1, offset_mask1, offset_mask1); 1526cabdff1aSopenharmony_ci offset_mask2 = 2 + (v16i8) diff_minus12 + (v16i8) diff_plus12; 1527cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask2, 1528cabdff1aSopenharmony_ci offset_mask2, offset_mask2, offset_mask2); 1529cabdff1aSopenharmony_ci offset_mask3 = 2 + (v16i8) diff_minus13 + (v16i8) diff_plus13; 1530cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask3, 1531cabdff1aSopenharmony_ci offset_mask3, offset_mask3, offset_mask3); 1532cabdff1aSopenharmony_ci 1533cabdff1aSopenharmony_ci XORI_B4_128_SB(src_zero0, src_zero1, src_zero2, src_zero3); 1534cabdff1aSopenharmony_ci 1535cabdff1aSopenharmony_ci dst0 = (v16u8) __msa_adds_s_b((v16i8) src_zero0, offset_mask0); 1536cabdff1aSopenharmony_ci dst1 = (v16u8) __msa_adds_s_b((v16i8) src_zero1, offset_mask1); 1537cabdff1aSopenharmony_ci dst2 = (v16u8) __msa_adds_s_b((v16i8) src_zero2, offset_mask2); 1538cabdff1aSopenharmony_ci dst3 = (v16u8) __msa_adds_s_b((v16i8) src_zero3, offset_mask3); 1539cabdff1aSopenharmony_ci 1540cabdff1aSopenharmony_ci XORI_B4_128_UB(dst0, dst1, dst2, dst3); 1541cabdff1aSopenharmony_ci 1542cabdff1aSopenharmony_ci src_minus10 = src10; 1543cabdff1aSopenharmony_ci ST_UB(dst0, dst_ptr); 1544cabdff1aSopenharmony_ci src_minus11 = src11; 1545cabdff1aSopenharmony_ci ST_UB(dst1, dst_ptr + dst_stride); 1546cabdff1aSopenharmony_ci src_minus12 = src12; 1547cabdff1aSopenharmony_ci ST_UB(dst2, dst_ptr + (dst_stride << 1)); 1548cabdff1aSopenharmony_ci src_minus13 = src13; 1549cabdff1aSopenharmony_ci ST_UB(dst3, dst_ptr + (dst_stride * 3)); 1550cabdff1aSopenharmony_ci } 1551cabdff1aSopenharmony_ci 1552cabdff1aSopenharmony_ci src += (src_stride << 2); 1553cabdff1aSopenharmony_ci dst += (dst_stride << 2); 1554cabdff1aSopenharmony_ci } 1555cabdff1aSopenharmony_ci} 1556cabdff1aSopenharmony_ci 1557cabdff1aSopenharmony_cistatic void hevc_sao_edge_filter_90degree_4width_msa(uint8_t *dst, 1558cabdff1aSopenharmony_ci int32_t dst_stride, 1559cabdff1aSopenharmony_ci uint8_t *src, 1560cabdff1aSopenharmony_ci int32_t src_stride, 1561cabdff1aSopenharmony_ci int16_t *sao_offset_val, 1562cabdff1aSopenharmony_ci int32_t height) 1563cabdff1aSopenharmony_ci{ 1564cabdff1aSopenharmony_ci uint32_t dst_val0, dst_val1; 1565cabdff1aSopenharmony_ci v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1566cabdff1aSopenharmony_ci v16u8 const1 = (v16u8) __msa_ldi_b(1); 1567cabdff1aSopenharmony_ci v16i8 dst0; 1568cabdff1aSopenharmony_ci v16i8 sao_offset = LD_SB(sao_offset_val); 1569cabdff1aSopenharmony_ci v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11; 1570cabdff1aSopenharmony_ci v16u8 src_minus10, src_minus11, src10, src11; 1571cabdff1aSopenharmony_ci v16i8 src_zero0, src_zero1; 1572cabdff1aSopenharmony_ci v16i8 offset; 1573cabdff1aSopenharmony_ci v8i16 offset_mask0, offset_mask1; 1574cabdff1aSopenharmony_ci 1575cabdff1aSopenharmony_ci sao_offset = __msa_pckev_b(sao_offset, sao_offset); 1576cabdff1aSopenharmony_ci 1577cabdff1aSopenharmony_ci /* load in advance */ 1578cabdff1aSopenharmony_ci LD_UB2(src - src_stride, src_stride, src_minus10, src_minus11); 1579cabdff1aSopenharmony_ci LD_UB2(src + src_stride, src_stride, src10, src11); 1580cabdff1aSopenharmony_ci 1581cabdff1aSopenharmony_ci for (height -= 2; height; height -= 2) { 1582cabdff1aSopenharmony_ci src += (src_stride << 1); 1583cabdff1aSopenharmony_ci 1584cabdff1aSopenharmony_ci src_minus10 = (v16u8) __msa_ilvr_b((v16i8) src10, (v16i8) src_minus10); 1585cabdff1aSopenharmony_ci src_zero0 = __msa_ilvr_b((v16i8) src_minus11, (v16i8) src_minus11); 1586cabdff1aSopenharmony_ci src_minus11 = (v16u8) __msa_ilvr_b((v16i8) src11, (v16i8) src_minus11); 1587cabdff1aSopenharmony_ci src_zero1 = __msa_ilvr_b((v16i8) src10, (v16i8) src10); 1588cabdff1aSopenharmony_ci 1589cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 1590cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 1591cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 1592cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 1593cabdff1aSopenharmony_ci 1594cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 1595cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 1596cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 1597cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 1598cabdff1aSopenharmony_ci 1599cabdff1aSopenharmony_ci offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); 1600cabdff1aSopenharmony_ci offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); 1601cabdff1aSopenharmony_ci 1602cabdff1aSopenharmony_ci offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); 1603cabdff1aSopenharmony_ci dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); 1604cabdff1aSopenharmony_ci 1605cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, 1606cabdff1aSopenharmony_ci offset, offset); 1607cabdff1aSopenharmony_ci 1608cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1609cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(dst0, offset); 1610cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1611cabdff1aSopenharmony_ci 1612cabdff1aSopenharmony_ci src_minus10 = src10; 1613cabdff1aSopenharmony_ci src_minus11 = src11; 1614cabdff1aSopenharmony_ci 1615cabdff1aSopenharmony_ci /* load in advance */ 1616cabdff1aSopenharmony_ci LD_UB2(src + src_stride, src_stride, src10, src11); 1617cabdff1aSopenharmony_ci 1618cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); 1619cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); 1620cabdff1aSopenharmony_ci SW(dst_val0, dst); 1621cabdff1aSopenharmony_ci dst += dst_stride; 1622cabdff1aSopenharmony_ci SW(dst_val1, dst); 1623cabdff1aSopenharmony_ci 1624cabdff1aSopenharmony_ci dst += dst_stride; 1625cabdff1aSopenharmony_ci } 1626cabdff1aSopenharmony_ci 1627cabdff1aSopenharmony_ci src_minus10 = (v16u8) __msa_ilvr_b((v16i8) src10, (v16i8) src_minus10); 1628cabdff1aSopenharmony_ci src_zero0 = __msa_ilvr_b((v16i8) src_minus11, (v16i8) src_minus11); 1629cabdff1aSopenharmony_ci src_minus11 = (v16u8) __msa_ilvr_b((v16i8) src11, (v16i8) src_minus11); 1630cabdff1aSopenharmony_ci src_zero1 = __msa_ilvr_b((v16i8) src10, (v16i8) src10); 1631cabdff1aSopenharmony_ci 1632cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 1633cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 1634cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 1635cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 1636cabdff1aSopenharmony_ci 1637cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 1638cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 1639cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 1640cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 1641cabdff1aSopenharmony_ci 1642cabdff1aSopenharmony_ci offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); 1643cabdff1aSopenharmony_ci offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); 1644cabdff1aSopenharmony_ci 1645cabdff1aSopenharmony_ci offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); 1646cabdff1aSopenharmony_ci dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); 1647cabdff1aSopenharmony_ci 1648cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, 1649cabdff1aSopenharmony_ci offset, offset, offset); 1650cabdff1aSopenharmony_ci 1651cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1652cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(dst0, offset); 1653cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1654cabdff1aSopenharmony_ci 1655cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); 1656cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); 1657cabdff1aSopenharmony_ci SW(dst_val0, dst); 1658cabdff1aSopenharmony_ci dst += dst_stride; 1659cabdff1aSopenharmony_ci SW(dst_val1, dst); 1660cabdff1aSopenharmony_ci} 1661cabdff1aSopenharmony_ci 1662cabdff1aSopenharmony_cistatic void hevc_sao_edge_filter_90degree_8width_msa(uint8_t *dst, 1663cabdff1aSopenharmony_ci int32_t dst_stride, 1664cabdff1aSopenharmony_ci uint8_t *src, 1665cabdff1aSopenharmony_ci int32_t src_stride, 1666cabdff1aSopenharmony_ci int16_t *sao_offset_val, 1667cabdff1aSopenharmony_ci int32_t height) 1668cabdff1aSopenharmony_ci{ 1669cabdff1aSopenharmony_ci uint64_t dst_val0, dst_val1; 1670cabdff1aSopenharmony_ci v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1671cabdff1aSopenharmony_ci v16u8 const1 = (v16u8) __msa_ldi_b(1); 1672cabdff1aSopenharmony_ci v16i8 offset, sao_offset = LD_SB(sao_offset_val); 1673cabdff1aSopenharmony_ci v16i8 src_zero0, src_zero1, dst0; 1674cabdff1aSopenharmony_ci v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11; 1675cabdff1aSopenharmony_ci v16u8 src_minus10, src_minus11, src10, src11; 1676cabdff1aSopenharmony_ci v8i16 offset_mask0, offset_mask1; 1677cabdff1aSopenharmony_ci 1678cabdff1aSopenharmony_ci sao_offset = __msa_pckev_b(sao_offset, sao_offset); 1679cabdff1aSopenharmony_ci 1680cabdff1aSopenharmony_ci /* load in advance */ 1681cabdff1aSopenharmony_ci LD_UB2(src - src_stride, src_stride, src_minus10, src_minus11); 1682cabdff1aSopenharmony_ci LD_UB2(src + src_stride, src_stride, src10, src11); 1683cabdff1aSopenharmony_ci 1684cabdff1aSopenharmony_ci for (height -= 2; height; height -= 2) { 1685cabdff1aSopenharmony_ci src += (src_stride << 1); 1686cabdff1aSopenharmony_ci 1687cabdff1aSopenharmony_ci src_minus10 = (v16u8) __msa_ilvr_b((v16i8) src10, (v16i8) src_minus10); 1688cabdff1aSopenharmony_ci src_zero0 = __msa_ilvr_b((v16i8) src_minus11, (v16i8) src_minus11); 1689cabdff1aSopenharmony_ci src_minus11 = (v16u8) __msa_ilvr_b((v16i8) src11, (v16i8) src_minus11); 1690cabdff1aSopenharmony_ci src_zero1 = __msa_ilvr_b((v16i8) src10, (v16i8) src10); 1691cabdff1aSopenharmony_ci 1692cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 1693cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 1694cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 1695cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 1696cabdff1aSopenharmony_ci 1697cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 1698cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 1699cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 1700cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 1701cabdff1aSopenharmony_ci 1702cabdff1aSopenharmony_ci offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); 1703cabdff1aSopenharmony_ci offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); 1704cabdff1aSopenharmony_ci 1705cabdff1aSopenharmony_ci offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); 1706cabdff1aSopenharmony_ci dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); 1707cabdff1aSopenharmony_ci 1708cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, 1709cabdff1aSopenharmony_ci offset, offset, offset); 1710cabdff1aSopenharmony_ci 1711cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1712cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(dst0, offset); 1713cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1714cabdff1aSopenharmony_ci 1715cabdff1aSopenharmony_ci src_minus10 = src10; 1716cabdff1aSopenharmony_ci src_minus11 = src11; 1717cabdff1aSopenharmony_ci 1718cabdff1aSopenharmony_ci /* load in advance */ 1719cabdff1aSopenharmony_ci LD_UB2(src + src_stride, src_stride, src10, src11); 1720cabdff1aSopenharmony_ci 1721cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); 1722cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); 1723cabdff1aSopenharmony_ci SD(dst_val0, dst); 1724cabdff1aSopenharmony_ci dst += dst_stride; 1725cabdff1aSopenharmony_ci SD(dst_val1, dst); 1726cabdff1aSopenharmony_ci dst += dst_stride; 1727cabdff1aSopenharmony_ci } 1728cabdff1aSopenharmony_ci 1729cabdff1aSopenharmony_ci src_minus10 = (v16u8) __msa_ilvr_b((v16i8) src10, (v16i8) src_minus10); 1730cabdff1aSopenharmony_ci src_zero0 = __msa_ilvr_b((v16i8) src_minus11, (v16i8) src_minus11); 1731cabdff1aSopenharmony_ci src_minus11 = (v16u8) __msa_ilvr_b((v16i8) src11, (v16i8) src_minus11); 1732cabdff1aSopenharmony_ci src_zero1 = __msa_ilvr_b((v16i8) src10, (v16i8) src10); 1733cabdff1aSopenharmony_ci 1734cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 1735cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 1736cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 1737cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 1738cabdff1aSopenharmony_ci 1739cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 1740cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 1741cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 1742cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 1743cabdff1aSopenharmony_ci 1744cabdff1aSopenharmony_ci offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); 1745cabdff1aSopenharmony_ci offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); 1746cabdff1aSopenharmony_ci 1747cabdff1aSopenharmony_ci offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); 1748cabdff1aSopenharmony_ci dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); 1749cabdff1aSopenharmony_ci 1750cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, 1751cabdff1aSopenharmony_ci offset, offset); 1752cabdff1aSopenharmony_ci 1753cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1754cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(dst0, offset); 1755cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1756cabdff1aSopenharmony_ci 1757cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); 1758cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); 1759cabdff1aSopenharmony_ci SD(dst_val0, dst); 1760cabdff1aSopenharmony_ci dst += dst_stride; 1761cabdff1aSopenharmony_ci SD(dst_val1, dst); 1762cabdff1aSopenharmony_ci} 1763cabdff1aSopenharmony_ci 1764cabdff1aSopenharmony_cistatic void hevc_sao_edge_filter_90degree_16multiple_msa(uint8_t *dst, 1765cabdff1aSopenharmony_ci int32_t dst_stride, 1766cabdff1aSopenharmony_ci uint8_t *src, 1767cabdff1aSopenharmony_ci int32_t src_stride, 1768cabdff1aSopenharmony_ci int16_t * 1769cabdff1aSopenharmony_ci sao_offset_val, 1770cabdff1aSopenharmony_ci int32_t width, 1771cabdff1aSopenharmony_ci int32_t height) 1772cabdff1aSopenharmony_ci{ 1773cabdff1aSopenharmony_ci uint8_t *src_orig = src; 1774cabdff1aSopenharmony_ci uint8_t *dst_orig = dst; 1775cabdff1aSopenharmony_ci int32_t h_cnt, v_cnt; 1776cabdff1aSopenharmony_ci v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1777cabdff1aSopenharmony_ci v16u8 const1 = (v16u8) __msa_ldi_b(1); 1778cabdff1aSopenharmony_ci v16u8 cmp_minus10, cmp_plus10, diff_minus10, diff_plus10, cmp_minus11; 1779cabdff1aSopenharmony_ci v16u8 cmp_plus11, diff_minus11, diff_plus11, cmp_minus12, cmp_plus12; 1780cabdff1aSopenharmony_ci v16u8 diff_minus12, diff_plus12, cmp_minus13, cmp_plus13, diff_minus13; 1781cabdff1aSopenharmony_ci v16u8 diff_plus13; 1782cabdff1aSopenharmony_ci v16u8 src10, src_minus10, dst0, src11, src_minus11, dst1; 1783cabdff1aSopenharmony_ci v16u8 src12, dst2, src13, dst3; 1784cabdff1aSopenharmony_ci v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3, sao_offset; 1785cabdff1aSopenharmony_ci 1786cabdff1aSopenharmony_ci sao_offset = LD_SB(sao_offset_val); 1787cabdff1aSopenharmony_ci sao_offset = __msa_pckev_b(sao_offset, sao_offset); 1788cabdff1aSopenharmony_ci 1789cabdff1aSopenharmony_ci for (v_cnt = 0; v_cnt < width; v_cnt += 16) { 1790cabdff1aSopenharmony_ci src = src_orig + v_cnt; 1791cabdff1aSopenharmony_ci dst = dst_orig + v_cnt; 1792cabdff1aSopenharmony_ci 1793cabdff1aSopenharmony_ci LD_UB2(src - src_stride, src_stride, src_minus10, src_minus11); 1794cabdff1aSopenharmony_ci 1795cabdff1aSopenharmony_ci for (h_cnt = (height >> 2); h_cnt--;) { 1796cabdff1aSopenharmony_ci LD_UB4(src + src_stride, src_stride, src10, src11, src12, src13); 1797cabdff1aSopenharmony_ci 1798cabdff1aSopenharmony_ci cmp_minus10 = (src_minus11 == src_minus10); 1799cabdff1aSopenharmony_ci cmp_plus10 = (src_minus11 == src10); 1800cabdff1aSopenharmony_ci cmp_minus11 = (src10 == src_minus11); 1801cabdff1aSopenharmony_ci cmp_plus11 = (src10 == src11); 1802cabdff1aSopenharmony_ci cmp_minus12 = (src11 == src10); 1803cabdff1aSopenharmony_ci cmp_plus12 = (src11 == src12); 1804cabdff1aSopenharmony_ci cmp_minus13 = (src12 == src11); 1805cabdff1aSopenharmony_ci cmp_plus13 = (src12 == src13); 1806cabdff1aSopenharmony_ci 1807cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 1808cabdff1aSopenharmony_ci diff_plus10 = __msa_nor_v(cmp_plus10, cmp_plus10); 1809cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 1810cabdff1aSopenharmony_ci diff_plus11 = __msa_nor_v(cmp_plus11, cmp_plus11); 1811cabdff1aSopenharmony_ci diff_minus12 = __msa_nor_v(cmp_minus12, cmp_minus12); 1812cabdff1aSopenharmony_ci diff_plus12 = __msa_nor_v(cmp_plus12, cmp_plus12); 1813cabdff1aSopenharmony_ci diff_minus13 = __msa_nor_v(cmp_minus13, cmp_minus13); 1814cabdff1aSopenharmony_ci diff_plus13 = __msa_nor_v(cmp_plus13, cmp_plus13); 1815cabdff1aSopenharmony_ci 1816cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < src_minus11); 1817cabdff1aSopenharmony_ci cmp_plus10 = (src10 < src_minus11); 1818cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < src10); 1819cabdff1aSopenharmony_ci cmp_plus11 = (src11 < src10); 1820cabdff1aSopenharmony_ci cmp_minus12 = (src10 < src11); 1821cabdff1aSopenharmony_ci cmp_plus12 = (src12 < src11); 1822cabdff1aSopenharmony_ci cmp_minus13 = (src11 < src12); 1823cabdff1aSopenharmony_ci cmp_plus13 = (src13 < src12); 1824cabdff1aSopenharmony_ci 1825cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 1826cabdff1aSopenharmony_ci diff_plus10 = __msa_bmnz_v(diff_plus10, const1, cmp_plus10); 1827cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 1828cabdff1aSopenharmony_ci diff_plus11 = __msa_bmnz_v(diff_plus11, const1, cmp_plus11); 1829cabdff1aSopenharmony_ci diff_minus12 = __msa_bmnz_v(diff_minus12, const1, cmp_minus12); 1830cabdff1aSopenharmony_ci diff_plus12 = __msa_bmnz_v(diff_plus12, const1, cmp_plus12); 1831cabdff1aSopenharmony_ci diff_minus13 = __msa_bmnz_v(diff_minus13, const1, cmp_minus13); 1832cabdff1aSopenharmony_ci diff_plus13 = __msa_bmnz_v(diff_plus13, const1, cmp_plus13); 1833cabdff1aSopenharmony_ci 1834cabdff1aSopenharmony_ci offset_mask0 = 2 + (v16i8) diff_minus10 + (v16i8) diff_plus10; 1835cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, 1836cabdff1aSopenharmony_ci offset_mask0, offset_mask0, offset_mask0, offset_mask0); 1837cabdff1aSopenharmony_ci offset_mask1 = 2 + (v16i8) diff_minus11 + (v16i8) diff_plus11; 1838cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, 1839cabdff1aSopenharmony_ci offset_mask1, offset_mask1, offset_mask1, offset_mask1); 1840cabdff1aSopenharmony_ci offset_mask2 = 2 + (v16i8) diff_minus12 + (v16i8) diff_plus12; 1841cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, 1842cabdff1aSopenharmony_ci offset_mask2, offset_mask2, offset_mask2, offset_mask2); 1843cabdff1aSopenharmony_ci offset_mask3 = 2 + (v16i8) diff_minus13 + (v16i8) diff_plus13; 1844cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, 1845cabdff1aSopenharmony_ci offset_mask3, offset_mask3, offset_mask3, offset_mask3); 1846cabdff1aSopenharmony_ci 1847cabdff1aSopenharmony_ci src_minus10 = src12; 1848cabdff1aSopenharmony_ci XORI_B4_128_UB(src_minus11, src10, src11, src12); 1849cabdff1aSopenharmony_ci 1850cabdff1aSopenharmony_ci dst0 = (v16u8) __msa_adds_s_b((v16i8) src_minus11, offset_mask0); 1851cabdff1aSopenharmony_ci dst1 = (v16u8) __msa_adds_s_b((v16i8) src10, offset_mask1); 1852cabdff1aSopenharmony_ci dst2 = (v16u8) __msa_adds_s_b((v16i8) src11, offset_mask2); 1853cabdff1aSopenharmony_ci dst3 = (v16u8) __msa_adds_s_b((v16i8) src12, offset_mask3); 1854cabdff1aSopenharmony_ci 1855cabdff1aSopenharmony_ci XORI_B4_128_UB(dst0, dst1, dst2, dst3); 1856cabdff1aSopenharmony_ci src_minus11 = src13; 1857cabdff1aSopenharmony_ci 1858cabdff1aSopenharmony_ci ST_UB4(dst0, dst1, dst2, dst3, dst, dst_stride); 1859cabdff1aSopenharmony_ci 1860cabdff1aSopenharmony_ci src += (src_stride << 2); 1861cabdff1aSopenharmony_ci dst += (dst_stride << 2); 1862cabdff1aSopenharmony_ci } 1863cabdff1aSopenharmony_ci } 1864cabdff1aSopenharmony_ci} 1865cabdff1aSopenharmony_ci 1866cabdff1aSopenharmony_cistatic void hevc_sao_edge_filter_45degree_4width_msa(uint8_t *dst, 1867cabdff1aSopenharmony_ci int32_t dst_stride, 1868cabdff1aSopenharmony_ci uint8_t *src, 1869cabdff1aSopenharmony_ci int32_t src_stride, 1870cabdff1aSopenharmony_ci int16_t *sao_offset_val, 1871cabdff1aSopenharmony_ci int32_t height) 1872cabdff1aSopenharmony_ci{ 1873cabdff1aSopenharmony_ci uint8_t *src_orig; 1874cabdff1aSopenharmony_ci uint32_t dst_val0, dst_val1; 1875cabdff1aSopenharmony_ci v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1876cabdff1aSopenharmony_ci v16u8 const1 = (v16u8) __msa_ldi_b(1); 1877cabdff1aSopenharmony_ci v16i8 offset, sao_offset = LD_SB(sao_offset_val); 1878cabdff1aSopenharmony_ci v16u8 cmp_minus10, diff_minus10, src_minus10, cmp_minus11, diff_minus11; 1879cabdff1aSopenharmony_ci v16u8 src_minus11, src10, src11; 1880cabdff1aSopenharmony_ci v16i8 src_plus0, src_zero0, src_plus1, src_zero1, dst0; 1881cabdff1aSopenharmony_ci v8i16 offset_mask0, offset_mask1; 1882cabdff1aSopenharmony_ci v16i8 zeros = { 0 }; 1883cabdff1aSopenharmony_ci 1884cabdff1aSopenharmony_ci sao_offset = __msa_pckev_b(sao_offset, sao_offset); 1885cabdff1aSopenharmony_ci 1886cabdff1aSopenharmony_ci src_orig = src - 1; 1887cabdff1aSopenharmony_ci 1888cabdff1aSopenharmony_ci /* load in advance */ 1889cabdff1aSopenharmony_ci LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11); 1890cabdff1aSopenharmony_ci LD_UB2(src_orig + src_stride, src_stride, src10, src11); 1891cabdff1aSopenharmony_ci 1892cabdff1aSopenharmony_ci for (height -= 2; height; height -= 2) { 1893cabdff1aSopenharmony_ci src_orig += (src_stride << 1); 1894cabdff1aSopenharmony_ci 1895cabdff1aSopenharmony_ci SLDI_B2_SB(zeros, src_minus11, zeros, src10, 1, src_zero0, src_zero1); 1896cabdff1aSopenharmony_ci SLDI_B2_SB(zeros, src10, zeros, src11, 2, src_plus0, src_plus1); 1897cabdff1aSopenharmony_ci 1898cabdff1aSopenharmony_ci ILVR_B2_UB(src_plus0, src_minus10, src_plus1, src_minus11, src_minus10, 1899cabdff1aSopenharmony_ci src_minus11); 1900cabdff1aSopenharmony_ci ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0, 1901cabdff1aSopenharmony_ci src_zero1); 1902cabdff1aSopenharmony_ci 1903cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 1904cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 1905cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 1906cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 1907cabdff1aSopenharmony_ci 1908cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 1909cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 1910cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 1911cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 1912cabdff1aSopenharmony_ci 1913cabdff1aSopenharmony_ci offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); 1914cabdff1aSopenharmony_ci offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); 1915cabdff1aSopenharmony_ci 1916cabdff1aSopenharmony_ci offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); 1917cabdff1aSopenharmony_ci dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); 1918cabdff1aSopenharmony_ci 1919cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, 1920cabdff1aSopenharmony_ci offset, offset, offset); 1921cabdff1aSopenharmony_ci 1922cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1923cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(dst0, offset); 1924cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1925cabdff1aSopenharmony_ci 1926cabdff1aSopenharmony_ci src_minus10 = src10; 1927cabdff1aSopenharmony_ci src_minus11 = src11; 1928cabdff1aSopenharmony_ci 1929cabdff1aSopenharmony_ci /* load in advance */ 1930cabdff1aSopenharmony_ci LD_UB2(src_orig + src_stride, src_stride, src10, src11); 1931cabdff1aSopenharmony_ci 1932cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); 1933cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); 1934cabdff1aSopenharmony_ci SW(dst_val0, dst); 1935cabdff1aSopenharmony_ci dst += dst_stride; 1936cabdff1aSopenharmony_ci SW(dst_val1, dst); 1937cabdff1aSopenharmony_ci 1938cabdff1aSopenharmony_ci dst += dst_stride; 1939cabdff1aSopenharmony_ci } 1940cabdff1aSopenharmony_ci 1941cabdff1aSopenharmony_ci SLDI_B2_SB(zeros, src_minus11, zeros, src10, 1, src_zero0, src_zero1); 1942cabdff1aSopenharmony_ci SLDI_B2_SB(zeros, src10, zeros, src11, 2, src_plus0, src_plus1); 1943cabdff1aSopenharmony_ci 1944cabdff1aSopenharmony_ci ILVR_B2_UB(src_plus0, src_minus10, src_plus1, src_minus11, src_minus10, 1945cabdff1aSopenharmony_ci src_minus11); 1946cabdff1aSopenharmony_ci ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0, 1947cabdff1aSopenharmony_ci src_zero1); 1948cabdff1aSopenharmony_ci 1949cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 1950cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 1951cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 1952cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 1953cabdff1aSopenharmony_ci 1954cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 1955cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 1956cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 1957cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 1958cabdff1aSopenharmony_ci 1959cabdff1aSopenharmony_ci offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); 1960cabdff1aSopenharmony_ci offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); 1961cabdff1aSopenharmony_ci 1962cabdff1aSopenharmony_ci offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); 1963cabdff1aSopenharmony_ci dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); 1964cabdff1aSopenharmony_ci 1965cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, 1966cabdff1aSopenharmony_ci offset, offset); 1967cabdff1aSopenharmony_ci 1968cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1969cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(dst0, offset); 1970cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 1971cabdff1aSopenharmony_ci 1972cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); 1973cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); 1974cabdff1aSopenharmony_ci SW(dst_val0, dst); 1975cabdff1aSopenharmony_ci dst += dst_stride; 1976cabdff1aSopenharmony_ci SW(dst_val1, dst); 1977cabdff1aSopenharmony_ci} 1978cabdff1aSopenharmony_ci 1979cabdff1aSopenharmony_cistatic void hevc_sao_edge_filter_45degree_8width_msa(uint8_t *dst, 1980cabdff1aSopenharmony_ci int32_t dst_stride, 1981cabdff1aSopenharmony_ci uint8_t *src, 1982cabdff1aSopenharmony_ci int32_t src_stride, 1983cabdff1aSopenharmony_ci int16_t *sao_offset_val, 1984cabdff1aSopenharmony_ci int32_t height) 1985cabdff1aSopenharmony_ci{ 1986cabdff1aSopenharmony_ci uint8_t *src_orig; 1987cabdff1aSopenharmony_ci uint64_t dst_val0, dst_val1; 1988cabdff1aSopenharmony_ci v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1989cabdff1aSopenharmony_ci v16u8 const1 = (v16u8) __msa_ldi_b(1); 1990cabdff1aSopenharmony_ci v16i8 offset, sao_offset = LD_SB(sao_offset_val); 1991cabdff1aSopenharmony_ci v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11; 1992cabdff1aSopenharmony_ci v16u8 src_minus10, src10, src_minus11, src11; 1993cabdff1aSopenharmony_ci v16i8 src_zero0, src_plus10, src_zero1, src_plus11, dst0; 1994cabdff1aSopenharmony_ci v8i16 offset_mask0, offset_mask1; 1995cabdff1aSopenharmony_ci v16i8 zeros = { 0 }; 1996cabdff1aSopenharmony_ci 1997cabdff1aSopenharmony_ci sao_offset = __msa_pckev_b(sao_offset, sao_offset); 1998cabdff1aSopenharmony_ci src_orig = src - 1; 1999cabdff1aSopenharmony_ci 2000cabdff1aSopenharmony_ci /* load in advance */ 2001cabdff1aSopenharmony_ci LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11); 2002cabdff1aSopenharmony_ci LD_UB2(src_orig + src_stride, src_stride, src10, src11); 2003cabdff1aSopenharmony_ci 2004cabdff1aSopenharmony_ci for (height -= 2; height; height -= 2) { 2005cabdff1aSopenharmony_ci src_orig += (src_stride << 1); 2006cabdff1aSopenharmony_ci 2007cabdff1aSopenharmony_ci SLDI_B2_SB(zeros, src_minus11, zeros, src10, 1, src_zero0, src_zero1); 2008cabdff1aSopenharmony_ci SLDI_B2_SB(zeros, src10, zeros, src11, 2, src_plus10, src_plus11); 2009cabdff1aSopenharmony_ci 2010cabdff1aSopenharmony_ci ILVR_B2_UB(src_plus10, src_minus10, src_plus11, src_minus11, 2011cabdff1aSopenharmony_ci src_minus10, src_minus11); 2012cabdff1aSopenharmony_ci ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, 2013cabdff1aSopenharmony_ci src_zero0, src_zero1); 2014cabdff1aSopenharmony_ci 2015cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 2016cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 2017cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 2018cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 2019cabdff1aSopenharmony_ci 2020cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 2021cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 2022cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 2023cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 2024cabdff1aSopenharmony_ci 2025cabdff1aSopenharmony_ci offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); 2026cabdff1aSopenharmony_ci offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); 2027cabdff1aSopenharmony_ci 2028cabdff1aSopenharmony_ci offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); 2029cabdff1aSopenharmony_ci dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); 2030cabdff1aSopenharmony_ci 2031cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, 2032cabdff1aSopenharmony_ci offset, offset); 2033cabdff1aSopenharmony_ci 2034cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 2035cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(dst0, offset); 2036cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 2037cabdff1aSopenharmony_ci 2038cabdff1aSopenharmony_ci src_minus10 = src10; 2039cabdff1aSopenharmony_ci src_minus11 = src11; 2040cabdff1aSopenharmony_ci 2041cabdff1aSopenharmony_ci /* load in advance */ 2042cabdff1aSopenharmony_ci LD_UB2(src_orig + src_stride, src_stride, src10, src11); 2043cabdff1aSopenharmony_ci 2044cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); 2045cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); 2046cabdff1aSopenharmony_ci SD(dst_val0, dst); 2047cabdff1aSopenharmony_ci dst += dst_stride; 2048cabdff1aSopenharmony_ci SD(dst_val1, dst); 2049cabdff1aSopenharmony_ci dst += dst_stride; 2050cabdff1aSopenharmony_ci } 2051cabdff1aSopenharmony_ci 2052cabdff1aSopenharmony_ci SLDI_B2_SB(zeros, src_minus11, zeros, src10, 1, src_zero0, src_zero1); 2053cabdff1aSopenharmony_ci SLDI_B2_SB(zeros, src10, zeros, src11, 2, src_plus10, src_plus11); 2054cabdff1aSopenharmony_ci ILVR_B2_UB(src_plus10, src_minus10, src_plus11, src_minus11, src_minus10, 2055cabdff1aSopenharmony_ci src_minus11); 2056cabdff1aSopenharmony_ci ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0, 2057cabdff1aSopenharmony_ci src_zero1); 2058cabdff1aSopenharmony_ci 2059cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 2060cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 2061cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 2062cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 2063cabdff1aSopenharmony_ci 2064cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 2065cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 2066cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 2067cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 2068cabdff1aSopenharmony_ci 2069cabdff1aSopenharmony_ci offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); 2070cabdff1aSopenharmony_ci offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); 2071cabdff1aSopenharmony_ci 2072cabdff1aSopenharmony_ci offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); 2073cabdff1aSopenharmony_ci dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); 2074cabdff1aSopenharmony_ci 2075cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, 2076cabdff1aSopenharmony_ci offset, offset); 2077cabdff1aSopenharmony_ci 2078cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 2079cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(dst0, offset); 2080cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 2081cabdff1aSopenharmony_ci 2082cabdff1aSopenharmony_ci src_minus10 = src10; 2083cabdff1aSopenharmony_ci src_minus11 = src11; 2084cabdff1aSopenharmony_ci 2085cabdff1aSopenharmony_ci /* load in advance */ 2086cabdff1aSopenharmony_ci LD_UB2(src_orig + src_stride, src_stride, src10, src11); 2087cabdff1aSopenharmony_ci 2088cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); 2089cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); 2090cabdff1aSopenharmony_ci SD(dst_val0, dst); 2091cabdff1aSopenharmony_ci dst += dst_stride; 2092cabdff1aSopenharmony_ci SD(dst_val1, dst); 2093cabdff1aSopenharmony_ci} 2094cabdff1aSopenharmony_ci 2095cabdff1aSopenharmony_cistatic void hevc_sao_edge_filter_45degree_16multiple_msa(uint8_t *dst, 2096cabdff1aSopenharmony_ci int32_t dst_stride, 2097cabdff1aSopenharmony_ci uint8_t *src, 2098cabdff1aSopenharmony_ci int32_t src_stride, 2099cabdff1aSopenharmony_ci int16_t * 2100cabdff1aSopenharmony_ci sao_offset_val, 2101cabdff1aSopenharmony_ci int32_t width, 2102cabdff1aSopenharmony_ci int32_t height) 2103cabdff1aSopenharmony_ci{ 2104cabdff1aSopenharmony_ci uint8_t *src_orig = src; 2105cabdff1aSopenharmony_ci uint8_t *dst_orig = dst; 2106cabdff1aSopenharmony_ci int32_t v_cnt; 2107cabdff1aSopenharmony_ci v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 2108cabdff1aSopenharmony_ci v16u8 const1 = (v16u8) __msa_ldi_b(1); 2109cabdff1aSopenharmony_ci v16u8 cmp_minus10, cmp_plus10, diff_minus10, diff_plus10, cmp_minus11; 2110cabdff1aSopenharmony_ci v16u8 cmp_plus11, diff_minus11, diff_plus11, cmp_minus12, cmp_plus12; 2111cabdff1aSopenharmony_ci v16u8 diff_minus12, diff_plus12, cmp_minus13, cmp_plus13, diff_minus13; 2112cabdff1aSopenharmony_ci v16u8 diff_plus13, src_minus14, src_plus13; 2113cabdff1aSopenharmony_ci v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3; 2114cabdff1aSopenharmony_ci v16u8 src10, src_minus10, dst0, src11, src_minus11, dst1; 2115cabdff1aSopenharmony_ci v16u8 src12, src_minus12, dst2, src13, src_minus13, dst3; 2116cabdff1aSopenharmony_ci v16i8 src_zero0, src_plus10, src_zero1, src_plus11, src_zero2, src_plus12; 2117cabdff1aSopenharmony_ci v16i8 src_zero3, sao_offset; 2118cabdff1aSopenharmony_ci 2119cabdff1aSopenharmony_ci sao_offset = LD_SB(sao_offset_val); 2120cabdff1aSopenharmony_ci sao_offset = __msa_pckev_b(sao_offset, sao_offset); 2121cabdff1aSopenharmony_ci 2122cabdff1aSopenharmony_ci for (; height; height -= 4) { 2123cabdff1aSopenharmony_ci src_orig = src - 1; 2124cabdff1aSopenharmony_ci dst_orig = dst; 2125cabdff1aSopenharmony_ci LD_UB4(src_orig, src_stride, src_minus11, src_minus12, src_minus13, 2126cabdff1aSopenharmony_ci src_minus14); 2127cabdff1aSopenharmony_ci 2128cabdff1aSopenharmony_ci for (v_cnt = 0; v_cnt < width; v_cnt += 16) { 2129cabdff1aSopenharmony_ci src_minus10 = LD_UB(src_orig - src_stride); 2130cabdff1aSopenharmony_ci LD_UB4(src_orig + 16, src_stride, src10, src11, src12, src13); 2131cabdff1aSopenharmony_ci src_plus13 = LD_UB(src + 1 + v_cnt + (src_stride << 2)); 2132cabdff1aSopenharmony_ci src_orig += 16; 2133cabdff1aSopenharmony_ci 2134cabdff1aSopenharmony_ci SLDI_B4_SB(src10, src_minus11, src11, src_minus12, 2135cabdff1aSopenharmony_ci src12, src_minus13, src13, src_minus14, 1, 2136cabdff1aSopenharmony_ci src_zero0, src_zero1, src_zero2, src_zero3); 2137cabdff1aSopenharmony_ci SLDI_B2_SB(src11, src_minus12, src12, src_minus13, 2, src_plus10, 2138cabdff1aSopenharmony_ci src_plus11); 2139cabdff1aSopenharmony_ci 2140cabdff1aSopenharmony_ci src_plus12 = __msa_sldi_b((v16i8) src13, (v16i8) src_minus14, 2); 2141cabdff1aSopenharmony_ci 2142cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 2143cabdff1aSopenharmony_ci cmp_plus10 = ((v16u8) src_zero0 == (v16u8) src_plus10); 2144cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 2145cabdff1aSopenharmony_ci cmp_plus11 = ((v16u8) src_zero1 == (v16u8) src_plus11); 2146cabdff1aSopenharmony_ci cmp_minus12 = ((v16u8) src_zero2 == src_minus12); 2147cabdff1aSopenharmony_ci cmp_plus12 = ((v16u8) src_zero2 == (v16u8) src_plus12); 2148cabdff1aSopenharmony_ci cmp_minus13 = ((v16u8) src_zero3 == src_minus13); 2149cabdff1aSopenharmony_ci cmp_plus13 = ((v16u8) src_zero3 == src_plus13); 2150cabdff1aSopenharmony_ci 2151cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 2152cabdff1aSopenharmony_ci diff_plus10 = __msa_nor_v(cmp_plus10, cmp_plus10); 2153cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 2154cabdff1aSopenharmony_ci diff_plus11 = __msa_nor_v(cmp_plus11, cmp_plus11); 2155cabdff1aSopenharmony_ci diff_minus12 = __msa_nor_v(cmp_minus12, cmp_minus12); 2156cabdff1aSopenharmony_ci diff_plus12 = __msa_nor_v(cmp_plus12, cmp_plus12); 2157cabdff1aSopenharmony_ci diff_minus13 = __msa_nor_v(cmp_minus13, cmp_minus13); 2158cabdff1aSopenharmony_ci diff_plus13 = __msa_nor_v(cmp_plus13, cmp_plus13); 2159cabdff1aSopenharmony_ci 2160cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 2161cabdff1aSopenharmony_ci cmp_plus10 = ((v16u8) src_plus10 < (v16u8) src_zero0); 2162cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 2163cabdff1aSopenharmony_ci cmp_plus11 = ((v16u8) src_plus11 < (v16u8) src_zero1); 2164cabdff1aSopenharmony_ci cmp_minus12 = (src_minus12 < (v16u8) src_zero2); 2165cabdff1aSopenharmony_ci cmp_plus12 = ((v16u8) src_plus12 < (v16u8) src_zero2); 2166cabdff1aSopenharmony_ci cmp_minus13 = (src_minus13 < (v16u8) src_zero3); 2167cabdff1aSopenharmony_ci cmp_plus13 = (src_plus13 < (v16u8) src_zero3); 2168cabdff1aSopenharmony_ci 2169cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 2170cabdff1aSopenharmony_ci diff_plus10 = __msa_bmnz_v(diff_plus10, const1, cmp_plus10); 2171cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 2172cabdff1aSopenharmony_ci diff_plus11 = __msa_bmnz_v(diff_plus11, const1, cmp_plus11); 2173cabdff1aSopenharmony_ci diff_minus12 = __msa_bmnz_v(diff_minus12, const1, cmp_minus12); 2174cabdff1aSopenharmony_ci diff_plus12 = __msa_bmnz_v(diff_plus12, const1, cmp_plus12); 2175cabdff1aSopenharmony_ci diff_minus13 = __msa_bmnz_v(diff_minus13, const1, cmp_minus13); 2176cabdff1aSopenharmony_ci diff_plus13 = __msa_bmnz_v(diff_plus13, const1, cmp_plus13); 2177cabdff1aSopenharmony_ci 2178cabdff1aSopenharmony_ci offset_mask0 = 2 + (v16i8) diff_minus10 + (v16i8) diff_plus10; 2179cabdff1aSopenharmony_ci offset_mask1 = 2 + (v16i8) diff_minus11 + (v16i8) diff_plus11; 2180cabdff1aSopenharmony_ci offset_mask2 = 2 + (v16i8) diff_minus12 + (v16i8) diff_plus12; 2181cabdff1aSopenharmony_ci offset_mask3 = 2 + (v16i8) diff_minus13 + (v16i8) diff_plus13; 2182cabdff1aSopenharmony_ci 2183cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, 2184cabdff1aSopenharmony_ci offset_mask0, offset_mask0, offset_mask0, offset_mask0); 2185cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, 2186cabdff1aSopenharmony_ci offset_mask1, offset_mask1, offset_mask1, offset_mask1); 2187cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, 2188cabdff1aSopenharmony_ci offset_mask2, offset_mask2, offset_mask2, offset_mask2); 2189cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, 2190cabdff1aSopenharmony_ci offset_mask3, offset_mask3, offset_mask3, offset_mask3); 2191cabdff1aSopenharmony_ci 2192cabdff1aSopenharmony_ci XORI_B4_128_SB(src_zero0, src_zero1, src_zero2, src_zero3); 2193cabdff1aSopenharmony_ci 2194cabdff1aSopenharmony_ci dst0 = (v16u8) __msa_adds_s_b((v16i8) src_zero0, offset_mask0); 2195cabdff1aSopenharmony_ci dst1 = (v16u8) __msa_adds_s_b((v16i8) src_zero1, offset_mask1); 2196cabdff1aSopenharmony_ci dst2 = (v16u8) __msa_adds_s_b((v16i8) src_zero2, offset_mask2); 2197cabdff1aSopenharmony_ci dst3 = (v16u8) __msa_adds_s_b((v16i8) src_zero3, offset_mask3); 2198cabdff1aSopenharmony_ci 2199cabdff1aSopenharmony_ci XORI_B4_128_UB(dst0, dst1, dst2, dst3); 2200cabdff1aSopenharmony_ci 2201cabdff1aSopenharmony_ci src_minus11 = src10; 2202cabdff1aSopenharmony_ci src_minus12 = src11; 2203cabdff1aSopenharmony_ci src_minus13 = src12; 2204cabdff1aSopenharmony_ci src_minus14 = src13; 2205cabdff1aSopenharmony_ci 2206cabdff1aSopenharmony_ci ST_UB4(dst0, dst1, dst2, dst3, dst_orig, dst_stride); 2207cabdff1aSopenharmony_ci dst_orig += 16; 2208cabdff1aSopenharmony_ci } 2209cabdff1aSopenharmony_ci 2210cabdff1aSopenharmony_ci src += (src_stride << 2); 2211cabdff1aSopenharmony_ci dst += (dst_stride << 2); 2212cabdff1aSopenharmony_ci } 2213cabdff1aSopenharmony_ci} 2214cabdff1aSopenharmony_ci 2215cabdff1aSopenharmony_cistatic void hevc_sao_edge_filter_135degree_4width_msa(uint8_t *dst, 2216cabdff1aSopenharmony_ci int32_t dst_stride, 2217cabdff1aSopenharmony_ci uint8_t *src, 2218cabdff1aSopenharmony_ci int32_t src_stride, 2219cabdff1aSopenharmony_ci int16_t *sao_offset_val, 2220cabdff1aSopenharmony_ci int32_t height) 2221cabdff1aSopenharmony_ci{ 2222cabdff1aSopenharmony_ci uint8_t *src_orig; 2223cabdff1aSopenharmony_ci uint32_t dst_val0, dst_val1; 2224cabdff1aSopenharmony_ci v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 2225cabdff1aSopenharmony_ci v16u8 const1 = (v16u8) __msa_ldi_b(1); 2226cabdff1aSopenharmony_ci v16i8 offset, sao_offset = LD_SB(sao_offset_val); 2227cabdff1aSopenharmony_ci v16i8 src_zero0, src_zero1, dst0; 2228cabdff1aSopenharmony_ci v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11; 2229cabdff1aSopenharmony_ci v16u8 src_minus10, src10, src_minus11, src11; 2230cabdff1aSopenharmony_ci v8i16 offset_mask0, offset_mask1; 2231cabdff1aSopenharmony_ci v16i8 zeros = { 0 }; 2232cabdff1aSopenharmony_ci 2233cabdff1aSopenharmony_ci sao_offset = __msa_pckev_b(sao_offset, sao_offset); 2234cabdff1aSopenharmony_ci src_orig = src - 1; 2235cabdff1aSopenharmony_ci 2236cabdff1aSopenharmony_ci /* load in advance */ 2237cabdff1aSopenharmony_ci LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11); 2238cabdff1aSopenharmony_ci LD_UB2(src_orig + src_stride, src_stride, src10, src11); 2239cabdff1aSopenharmony_ci 2240cabdff1aSopenharmony_ci for (height -= 2; height; height -= 2) { 2241cabdff1aSopenharmony_ci src_orig += (src_stride << 1); 2242cabdff1aSopenharmony_ci 2243cabdff1aSopenharmony_ci SLDI_B2_SB(zeros, src_minus11, zeros, src10, 1, src_zero0, src_zero1); 2244cabdff1aSopenharmony_ci SLDI_B2_UB(zeros, src_minus10, zeros, src_minus11, 2, src_minus10, src_minus11); 2245cabdff1aSopenharmony_ci 2246cabdff1aSopenharmony_ci ILVR_B2_UB(src10, src_minus10, src11, src_minus11, src_minus10, 2247cabdff1aSopenharmony_ci src_minus11); 2248cabdff1aSopenharmony_ci ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0, 2249cabdff1aSopenharmony_ci src_zero1); 2250cabdff1aSopenharmony_ci 2251cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 2252cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 2253cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 2254cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 2255cabdff1aSopenharmony_ci 2256cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 2257cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 2258cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 2259cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 2260cabdff1aSopenharmony_ci 2261cabdff1aSopenharmony_ci offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); 2262cabdff1aSopenharmony_ci offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); 2263cabdff1aSopenharmony_ci 2264cabdff1aSopenharmony_ci offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); 2265cabdff1aSopenharmony_ci dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); 2266cabdff1aSopenharmony_ci 2267cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, 2268cabdff1aSopenharmony_ci offset, offset); 2269cabdff1aSopenharmony_ci 2270cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 2271cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(dst0, offset); 2272cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 2273cabdff1aSopenharmony_ci 2274cabdff1aSopenharmony_ci src_minus10 = src10; 2275cabdff1aSopenharmony_ci src_minus11 = src11; 2276cabdff1aSopenharmony_ci 2277cabdff1aSopenharmony_ci /* load in advance */ 2278cabdff1aSopenharmony_ci LD_UB2(src_orig + src_stride, src_stride, src10, src11); 2279cabdff1aSopenharmony_ci 2280cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); 2281cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); 2282cabdff1aSopenharmony_ci 2283cabdff1aSopenharmony_ci SW(dst_val0, dst); 2284cabdff1aSopenharmony_ci dst += dst_stride; 2285cabdff1aSopenharmony_ci SW(dst_val1, dst); 2286cabdff1aSopenharmony_ci 2287cabdff1aSopenharmony_ci dst += dst_stride; 2288cabdff1aSopenharmony_ci } 2289cabdff1aSopenharmony_ci 2290cabdff1aSopenharmony_ci SLDI_B2_SB(zeros, src_minus11, zeros, src10, 1, src_zero0, src_zero1); 2291cabdff1aSopenharmony_ci SLDI_B2_UB(zeros, src_minus10, zeros, src_minus11, 2, src_minus10, src_minus11); 2292cabdff1aSopenharmony_ci 2293cabdff1aSopenharmony_ci ILVR_B2_UB(src10, src_minus10, src11, src_minus11, src_minus10, 2294cabdff1aSopenharmony_ci src_minus11); 2295cabdff1aSopenharmony_ci ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0, 2296cabdff1aSopenharmony_ci src_zero1); 2297cabdff1aSopenharmony_ci 2298cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 2299cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 2300cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 2301cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 2302cabdff1aSopenharmony_ci 2303cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 2304cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 2305cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 2306cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 2307cabdff1aSopenharmony_ci 2308cabdff1aSopenharmony_ci offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); 2309cabdff1aSopenharmony_ci offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); 2310cabdff1aSopenharmony_ci 2311cabdff1aSopenharmony_ci offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); 2312cabdff1aSopenharmony_ci dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); 2313cabdff1aSopenharmony_ci 2314cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, 2315cabdff1aSopenharmony_ci offset, offset); 2316cabdff1aSopenharmony_ci 2317cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 2318cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(dst0, offset); 2319cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 2320cabdff1aSopenharmony_ci 2321cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_w((v4i32) dst0, 0); 2322cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_w((v4i32) dst0, 2); 2323cabdff1aSopenharmony_ci 2324cabdff1aSopenharmony_ci SW(dst_val0, dst); 2325cabdff1aSopenharmony_ci dst += dst_stride; 2326cabdff1aSopenharmony_ci SW(dst_val1, dst); 2327cabdff1aSopenharmony_ci dst += dst_stride; 2328cabdff1aSopenharmony_ci} 2329cabdff1aSopenharmony_ci 2330cabdff1aSopenharmony_cistatic void hevc_sao_edge_filter_135degree_8width_msa(uint8_t *dst, 2331cabdff1aSopenharmony_ci int32_t dst_stride, 2332cabdff1aSopenharmony_ci uint8_t *src, 2333cabdff1aSopenharmony_ci int32_t src_stride, 2334cabdff1aSopenharmony_ci int16_t *sao_offset_val, 2335cabdff1aSopenharmony_ci int32_t height) 2336cabdff1aSopenharmony_ci{ 2337cabdff1aSopenharmony_ci uint8_t *src_orig; 2338cabdff1aSopenharmony_ci uint64_t dst_val0, dst_val1; 2339cabdff1aSopenharmony_ci v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 2340cabdff1aSopenharmony_ci v16u8 const1 = (v16u8) __msa_ldi_b(1); 2341cabdff1aSopenharmony_ci v16i8 offset, sao_offset = LD_SB(sao_offset_val); 2342cabdff1aSopenharmony_ci v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11; 2343cabdff1aSopenharmony_ci v16u8 src_minus10, src10, src_minus11, src11; 2344cabdff1aSopenharmony_ci v16i8 src_zero0, src_zero1, dst0; 2345cabdff1aSopenharmony_ci v8i16 offset_mask0, offset_mask1; 2346cabdff1aSopenharmony_ci v16i8 zeros = { 0 }; 2347cabdff1aSopenharmony_ci 2348cabdff1aSopenharmony_ci sao_offset = __msa_pckev_b(sao_offset, sao_offset); 2349cabdff1aSopenharmony_ci src_orig = src - 1; 2350cabdff1aSopenharmony_ci 2351cabdff1aSopenharmony_ci /* load in advance */ 2352cabdff1aSopenharmony_ci LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11); 2353cabdff1aSopenharmony_ci LD_UB2(src_orig + src_stride, src_stride, src10, src11); 2354cabdff1aSopenharmony_ci 2355cabdff1aSopenharmony_ci for (height -= 2; height; height -= 2) { 2356cabdff1aSopenharmony_ci src_orig += (src_stride << 1); 2357cabdff1aSopenharmony_ci 2358cabdff1aSopenharmony_ci SLDI_B2_SB(zeros, src_minus11, zeros, src10, 1, src_zero0, src_zero1); 2359cabdff1aSopenharmony_ci SLDI_B2_UB(zeros, src_minus10, zeros, src_minus11, 2, src_minus10, src_minus11); 2360cabdff1aSopenharmony_ci ILVR_B2_UB(src10, src_minus10, src11, src_minus11, src_minus10, 2361cabdff1aSopenharmony_ci src_minus11); 2362cabdff1aSopenharmony_ci ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0, 2363cabdff1aSopenharmony_ci src_zero1); 2364cabdff1aSopenharmony_ci 2365cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 2366cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 2367cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 2368cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 2369cabdff1aSopenharmony_ci 2370cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 2371cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 2372cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 2373cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 2374cabdff1aSopenharmony_ci 2375cabdff1aSopenharmony_ci offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); 2376cabdff1aSopenharmony_ci offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); 2377cabdff1aSopenharmony_ci 2378cabdff1aSopenharmony_ci offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); 2379cabdff1aSopenharmony_ci dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); 2380cabdff1aSopenharmony_ci 2381cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, 2382cabdff1aSopenharmony_ci offset, offset); 2383cabdff1aSopenharmony_ci 2384cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 2385cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(dst0, offset); 2386cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 2387cabdff1aSopenharmony_ci 2388cabdff1aSopenharmony_ci src_minus10 = src10; 2389cabdff1aSopenharmony_ci src_minus11 = src11; 2390cabdff1aSopenharmony_ci 2391cabdff1aSopenharmony_ci /* load in advance */ 2392cabdff1aSopenharmony_ci LD_UB2(src_orig + src_stride, src_stride, src10, src11); 2393cabdff1aSopenharmony_ci 2394cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); 2395cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); 2396cabdff1aSopenharmony_ci 2397cabdff1aSopenharmony_ci SD(dst_val0, dst); 2398cabdff1aSopenharmony_ci dst += dst_stride; 2399cabdff1aSopenharmony_ci SD(dst_val1, dst); 2400cabdff1aSopenharmony_ci dst += dst_stride; 2401cabdff1aSopenharmony_ci } 2402cabdff1aSopenharmony_ci 2403cabdff1aSopenharmony_ci SLDI_B2_SB(zeros, src_minus11, zeros, src10, 1, src_zero0, src_zero1); 2404cabdff1aSopenharmony_ci SLDI_B2_UB(zeros, src_minus10, zeros, src_minus11, 2, src_minus10, src_minus11); 2405cabdff1aSopenharmony_ci ILVR_B2_UB(src10, src_minus10, src11, src_minus11, src_minus10, 2406cabdff1aSopenharmony_ci src_minus11); 2407cabdff1aSopenharmony_ci ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0, 2408cabdff1aSopenharmony_ci src_zero1); 2409cabdff1aSopenharmony_ci 2410cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 2411cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 2412cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 2413cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 2414cabdff1aSopenharmony_ci 2415cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 2416cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 2417cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 2418cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 2419cabdff1aSopenharmony_ci 2420cabdff1aSopenharmony_ci offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2); 2421cabdff1aSopenharmony_ci offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2); 2422cabdff1aSopenharmony_ci 2423cabdff1aSopenharmony_ci offset = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0); 2424cabdff1aSopenharmony_ci dst0 = __msa_pckev_b((v16i8) src_zero1, (v16i8) src_zero0); 2425cabdff1aSopenharmony_ci 2426cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset, offset, 2427cabdff1aSopenharmony_ci offset, offset); 2428cabdff1aSopenharmony_ci 2429cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 2430cabdff1aSopenharmony_ci dst0 = __msa_adds_s_b(dst0, offset); 2431cabdff1aSopenharmony_ci dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128); 2432cabdff1aSopenharmony_ci 2433cabdff1aSopenharmony_ci dst_val0 = __msa_copy_u_d((v2i64) dst0, 0); 2434cabdff1aSopenharmony_ci dst_val1 = __msa_copy_u_d((v2i64) dst0, 1); 2435cabdff1aSopenharmony_ci 2436cabdff1aSopenharmony_ci SD(dst_val0, dst); 2437cabdff1aSopenharmony_ci dst += dst_stride; 2438cabdff1aSopenharmony_ci SD(dst_val1, dst); 2439cabdff1aSopenharmony_ci dst += dst_stride; 2440cabdff1aSopenharmony_ci} 2441cabdff1aSopenharmony_ci 2442cabdff1aSopenharmony_cistatic void hevc_sao_edge_filter_135degree_16multiple_msa(uint8_t *dst, 2443cabdff1aSopenharmony_ci int32_t dst_stride, 2444cabdff1aSopenharmony_ci uint8_t *src, 2445cabdff1aSopenharmony_ci int32_t src_stride, 2446cabdff1aSopenharmony_ci int16_t * 2447cabdff1aSopenharmony_ci sao_offset_val, 2448cabdff1aSopenharmony_ci int32_t width, 2449cabdff1aSopenharmony_ci int32_t height) 2450cabdff1aSopenharmony_ci{ 2451cabdff1aSopenharmony_ci uint8_t *src_orig, *dst_orig; 2452cabdff1aSopenharmony_ci int32_t v_cnt; 2453cabdff1aSopenharmony_ci v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 2454cabdff1aSopenharmony_ci v16u8 const1 = (v16u8) __msa_ldi_b(1); 2455cabdff1aSopenharmony_ci v16u8 dst0, dst1, dst2, dst3; 2456cabdff1aSopenharmony_ci v16u8 cmp_minus10, cmp_minus11, cmp_minus12, cmp_minus13, cmp_plus10; 2457cabdff1aSopenharmony_ci v16u8 cmp_plus11, cmp_plus12, cmp_plus13, diff_minus10, diff_minus11; 2458cabdff1aSopenharmony_ci v16u8 diff_minus12, diff_minus13, diff_plus10, diff_plus11, diff_plus12; 2459cabdff1aSopenharmony_ci v16u8 diff_plus13, src10, src11, src12, src13, src_minus10, src_minus11; 2460cabdff1aSopenharmony_ci v16u8 src_plus10, src_plus11, src_plus12, src_plus13; 2461cabdff1aSopenharmony_ci v16i8 src_minus12, src_minus13, src_zero0, src_zero1, src_zero2, src_zero3; 2462cabdff1aSopenharmony_ci v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3, sao_offset; 2463cabdff1aSopenharmony_ci 2464cabdff1aSopenharmony_ci sao_offset = LD_SB(sao_offset_val); 2465cabdff1aSopenharmony_ci sao_offset = __msa_pckev_b(sao_offset, sao_offset); 2466cabdff1aSopenharmony_ci 2467cabdff1aSopenharmony_ci for (; height; height -= 4) { 2468cabdff1aSopenharmony_ci src_orig = src - 1; 2469cabdff1aSopenharmony_ci dst_orig = dst; 2470cabdff1aSopenharmony_ci 2471cabdff1aSopenharmony_ci LD_UB4(src_orig, src_stride, src_minus11, src_plus10, src_plus11, 2472cabdff1aSopenharmony_ci src_plus12); 2473cabdff1aSopenharmony_ci 2474cabdff1aSopenharmony_ci for (v_cnt = 0; v_cnt < width; v_cnt += 16) { 2475cabdff1aSopenharmony_ci src_minus10 = LD_UB(src_orig + 2 - src_stride); 2476cabdff1aSopenharmony_ci LD_UB4(src_orig + 16, src_stride, src10, src11, src12, src13); 2477cabdff1aSopenharmony_ci src_plus13 = LD_UB(src_orig + (src_stride << 2)); 2478cabdff1aSopenharmony_ci src_orig += 16; 2479cabdff1aSopenharmony_ci 2480cabdff1aSopenharmony_ci src_zero0 = __msa_sldi_b((v16i8) src10, (v16i8) src_minus11, 1); 2481cabdff1aSopenharmony_ci cmp_minus10 = ((v16u8) src_zero0 == src_minus10); 2482cabdff1aSopenharmony_ci cmp_plus10 = ((v16u8) src_zero0 == src_plus10); 2483cabdff1aSopenharmony_ci 2484cabdff1aSopenharmony_ci src_zero1 = __msa_sldi_b((v16i8) src11, (v16i8) src_plus10, 1); 2485cabdff1aSopenharmony_ci src_minus11 = (v16u8) __msa_sldi_b((v16i8) src10, 2486cabdff1aSopenharmony_ci (v16i8) src_minus11, 2); 2487cabdff1aSopenharmony_ci cmp_minus11 = ((v16u8) src_zero1 == src_minus11); 2488cabdff1aSopenharmony_ci cmp_plus11 = ((v16u8) src_zero1 == src_plus11); 2489cabdff1aSopenharmony_ci 2490cabdff1aSopenharmony_ci src_zero2 = __msa_sldi_b((v16i8) src12, (v16i8) src_plus11, 1); 2491cabdff1aSopenharmony_ci src_minus12 = __msa_sldi_b((v16i8) src11, (v16i8) src_plus10, 2); 2492cabdff1aSopenharmony_ci cmp_minus12 = ((v16u8) src_zero2 == (v16u8) src_minus12); 2493cabdff1aSopenharmony_ci cmp_plus12 = ((v16u8) src_zero2 == src_plus12); 2494cabdff1aSopenharmony_ci 2495cabdff1aSopenharmony_ci src_zero3 = __msa_sldi_b((v16i8) src13, (v16i8) src_plus12, 1); 2496cabdff1aSopenharmony_ci src_minus13 = __msa_sldi_b((v16i8) src12, (v16i8) src_plus11, 2); 2497cabdff1aSopenharmony_ci cmp_minus13 = ((v16u8) src_zero3 == (v16u8) src_minus13); 2498cabdff1aSopenharmony_ci cmp_plus13 = ((v16u8) src_zero3 == src_plus13); 2499cabdff1aSopenharmony_ci 2500cabdff1aSopenharmony_ci diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10); 2501cabdff1aSopenharmony_ci diff_plus10 = __msa_nor_v(cmp_plus10, cmp_plus10); 2502cabdff1aSopenharmony_ci diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11); 2503cabdff1aSopenharmony_ci diff_plus11 = __msa_nor_v(cmp_plus11, cmp_plus11); 2504cabdff1aSopenharmony_ci diff_minus12 = __msa_nor_v(cmp_minus12, cmp_minus12); 2505cabdff1aSopenharmony_ci diff_plus12 = __msa_nor_v(cmp_plus12, cmp_plus12); 2506cabdff1aSopenharmony_ci diff_minus13 = __msa_nor_v(cmp_minus13, cmp_minus13); 2507cabdff1aSopenharmony_ci diff_plus13 = __msa_nor_v(cmp_plus13, cmp_plus13); 2508cabdff1aSopenharmony_ci 2509cabdff1aSopenharmony_ci cmp_minus10 = (src_minus10 < (v16u8) src_zero0); 2510cabdff1aSopenharmony_ci cmp_plus10 = (src_plus10 < (v16u8) src_zero0); 2511cabdff1aSopenharmony_ci cmp_minus11 = (src_minus11 < (v16u8) src_zero1); 2512cabdff1aSopenharmony_ci cmp_plus11 = (src_plus11 < (v16u8) src_zero1); 2513cabdff1aSopenharmony_ci cmp_minus12 = ((v16u8) src_minus12 < (v16u8) src_zero2); 2514cabdff1aSopenharmony_ci cmp_plus12 = (src_plus12 < (v16u8) src_zero2); 2515cabdff1aSopenharmony_ci cmp_minus13 = ((v16u8) src_minus13 < (v16u8) src_zero3); 2516cabdff1aSopenharmony_ci cmp_plus13 = (src_plus13 < (v16u8) src_zero3); 2517cabdff1aSopenharmony_ci 2518cabdff1aSopenharmony_ci diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10); 2519cabdff1aSopenharmony_ci diff_plus10 = __msa_bmnz_v(diff_plus10, const1, cmp_plus10); 2520cabdff1aSopenharmony_ci diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11); 2521cabdff1aSopenharmony_ci diff_plus11 = __msa_bmnz_v(diff_plus11, const1, cmp_plus11); 2522cabdff1aSopenharmony_ci diff_minus12 = __msa_bmnz_v(diff_minus12, const1, cmp_minus12); 2523cabdff1aSopenharmony_ci diff_plus12 = __msa_bmnz_v(diff_plus12, const1, cmp_plus12); 2524cabdff1aSopenharmony_ci diff_minus13 = __msa_bmnz_v(diff_minus13, const1, cmp_minus13); 2525cabdff1aSopenharmony_ci diff_plus13 = __msa_bmnz_v(diff_plus13, const1, cmp_plus13); 2526cabdff1aSopenharmony_ci 2527cabdff1aSopenharmony_ci offset_mask0 = 2 + (v16i8) diff_minus10 + (v16i8) diff_plus10; 2528cabdff1aSopenharmony_ci offset_mask1 = 2 + (v16i8) diff_minus11 + (v16i8) diff_plus11; 2529cabdff1aSopenharmony_ci offset_mask2 = 2 + (v16i8) diff_minus12 + (v16i8) diff_plus12; 2530cabdff1aSopenharmony_ci offset_mask3 = 2 + (v16i8) diff_minus13 + (v16i8) diff_plus13; 2531cabdff1aSopenharmony_ci 2532cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, 2533cabdff1aSopenharmony_ci offset_mask0, offset_mask0, offset_mask0, offset_mask0); 2534cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, 2535cabdff1aSopenharmony_ci offset_mask1, offset_mask1, offset_mask1, offset_mask1); 2536cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, 2537cabdff1aSopenharmony_ci offset_mask2, offset_mask2, offset_mask2, offset_mask2); 2538cabdff1aSopenharmony_ci VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, 2539cabdff1aSopenharmony_ci offset_mask3, offset_mask3, offset_mask3, offset_mask3); 2540cabdff1aSopenharmony_ci 2541cabdff1aSopenharmony_ci XORI_B4_128_SB(src_zero0, src_zero1, src_zero2, src_zero3); 2542cabdff1aSopenharmony_ci 2543cabdff1aSopenharmony_ci dst0 = (v16u8) __msa_adds_s_b((v16i8) src_zero0, offset_mask0); 2544cabdff1aSopenharmony_ci dst1 = (v16u8) __msa_adds_s_b((v16i8) src_zero1, offset_mask1); 2545cabdff1aSopenharmony_ci dst2 = (v16u8) __msa_adds_s_b((v16i8) src_zero2, offset_mask2); 2546cabdff1aSopenharmony_ci dst3 = (v16u8) __msa_adds_s_b((v16i8) src_zero3, offset_mask3); 2547cabdff1aSopenharmony_ci 2548cabdff1aSopenharmony_ci XORI_B4_128_UB(dst0, dst1, dst2, dst3); 2549cabdff1aSopenharmony_ci 2550cabdff1aSopenharmony_ci src_minus11 = src10; 2551cabdff1aSopenharmony_ci src_plus10 = src11; 2552cabdff1aSopenharmony_ci src_plus11 = src12; 2553cabdff1aSopenharmony_ci src_plus12 = src13; 2554cabdff1aSopenharmony_ci 2555cabdff1aSopenharmony_ci ST_UB4(dst0, dst1, dst2, dst3, dst_orig, dst_stride); 2556cabdff1aSopenharmony_ci dst_orig += 16; 2557cabdff1aSopenharmony_ci } 2558cabdff1aSopenharmony_ci 2559cabdff1aSopenharmony_ci src += (src_stride << 2); 2560cabdff1aSopenharmony_ci dst += (dst_stride << 2); 2561cabdff1aSopenharmony_ci } 2562cabdff1aSopenharmony_ci} 2563cabdff1aSopenharmony_ci 2564cabdff1aSopenharmony_civoid ff_hevc_loop_filter_luma_h_8_msa(uint8_t *src, 2565cabdff1aSopenharmony_ci ptrdiff_t src_stride, 2566cabdff1aSopenharmony_ci int32_t beta, int32_t *tc, 2567cabdff1aSopenharmony_ci uint8_t *no_p, uint8_t *no_q) 2568cabdff1aSopenharmony_ci{ 2569cabdff1aSopenharmony_ci hevc_loopfilter_luma_hor_msa(src, src_stride, beta, tc, no_p, no_q); 2570cabdff1aSopenharmony_ci} 2571cabdff1aSopenharmony_ci 2572cabdff1aSopenharmony_civoid ff_hevc_loop_filter_luma_v_8_msa(uint8_t *src, 2573cabdff1aSopenharmony_ci ptrdiff_t src_stride, 2574cabdff1aSopenharmony_ci int32_t beta, int32_t *tc, 2575cabdff1aSopenharmony_ci uint8_t *no_p, uint8_t *no_q) 2576cabdff1aSopenharmony_ci{ 2577cabdff1aSopenharmony_ci hevc_loopfilter_luma_ver_msa(src, src_stride, beta, tc, no_p, no_q); 2578cabdff1aSopenharmony_ci} 2579cabdff1aSopenharmony_ci 2580cabdff1aSopenharmony_civoid ff_hevc_loop_filter_chroma_h_8_msa(uint8_t *src, 2581cabdff1aSopenharmony_ci ptrdiff_t src_stride, 2582cabdff1aSopenharmony_ci int32_t *tc, uint8_t *no_p, 2583cabdff1aSopenharmony_ci uint8_t *no_q) 2584cabdff1aSopenharmony_ci{ 2585cabdff1aSopenharmony_ci hevc_loopfilter_chroma_hor_msa(src, src_stride, tc, no_p, no_q); 2586cabdff1aSopenharmony_ci} 2587cabdff1aSopenharmony_ci 2588cabdff1aSopenharmony_civoid ff_hevc_loop_filter_chroma_v_8_msa(uint8_t *src, 2589cabdff1aSopenharmony_ci ptrdiff_t src_stride, 2590cabdff1aSopenharmony_ci int32_t *tc, uint8_t *no_p, 2591cabdff1aSopenharmony_ci uint8_t *no_q) 2592cabdff1aSopenharmony_ci{ 2593cabdff1aSopenharmony_ci hevc_loopfilter_chroma_ver_msa(src, src_stride, tc, no_p, no_q); 2594cabdff1aSopenharmony_ci} 2595cabdff1aSopenharmony_ci 2596cabdff1aSopenharmony_civoid ff_hevc_sao_band_filter_0_8_msa(uint8_t *dst, uint8_t *src, 2597cabdff1aSopenharmony_ci ptrdiff_t stride_dst, ptrdiff_t stride_src, 2598cabdff1aSopenharmony_ci int16_t *sao_offset_val, int sao_left_class, 2599cabdff1aSopenharmony_ci int width, int height) 2600cabdff1aSopenharmony_ci{ 2601cabdff1aSopenharmony_ci if (width >> 4) { 2602cabdff1aSopenharmony_ci hevc_sao_band_filter_16multiple_msa(dst, stride_dst, src, stride_src, 2603cabdff1aSopenharmony_ci sao_left_class, sao_offset_val, 2604cabdff1aSopenharmony_ci width - (width % 16), height); 2605cabdff1aSopenharmony_ci dst += width - (width % 16); 2606cabdff1aSopenharmony_ci src += width - (width % 16); 2607cabdff1aSopenharmony_ci width %= 16; 2608cabdff1aSopenharmony_ci } 2609cabdff1aSopenharmony_ci 2610cabdff1aSopenharmony_ci if (width >> 3) { 2611cabdff1aSopenharmony_ci hevc_sao_band_filter_8width_msa(dst, stride_dst, src, stride_src, 2612cabdff1aSopenharmony_ci sao_left_class, sao_offset_val, height); 2613cabdff1aSopenharmony_ci dst += 8; 2614cabdff1aSopenharmony_ci src += 8; 2615cabdff1aSopenharmony_ci width %= 8; 2616cabdff1aSopenharmony_ci } 2617cabdff1aSopenharmony_ci 2618cabdff1aSopenharmony_ci if (width) { 2619cabdff1aSopenharmony_ci hevc_sao_band_filter_4width_msa(dst, stride_dst, src, stride_src, 2620cabdff1aSopenharmony_ci sao_left_class, sao_offset_val, height); 2621cabdff1aSopenharmony_ci } 2622cabdff1aSopenharmony_ci} 2623cabdff1aSopenharmony_ci 2624cabdff1aSopenharmony_civoid ff_hevc_sao_edge_filter_8_msa(uint8_t *dst, uint8_t *src, 2625cabdff1aSopenharmony_ci ptrdiff_t stride_dst, 2626cabdff1aSopenharmony_ci int16_t *sao_offset_val, 2627cabdff1aSopenharmony_ci int eo, int width, int height) 2628cabdff1aSopenharmony_ci{ 2629cabdff1aSopenharmony_ci ptrdiff_t stride_src = (2 * MAX_PB_SIZE + AV_INPUT_BUFFER_PADDING_SIZE) / sizeof(uint8_t); 2630cabdff1aSopenharmony_ci 2631cabdff1aSopenharmony_ci switch (eo) { 2632cabdff1aSopenharmony_ci case 0: 2633cabdff1aSopenharmony_ci if (width >> 4) { 2634cabdff1aSopenharmony_ci hevc_sao_edge_filter_0degree_16multiple_msa(dst, stride_dst, 2635cabdff1aSopenharmony_ci src, stride_src, 2636cabdff1aSopenharmony_ci sao_offset_val, 2637cabdff1aSopenharmony_ci width - (width % 16), 2638cabdff1aSopenharmony_ci height); 2639cabdff1aSopenharmony_ci dst += width - (width % 16); 2640cabdff1aSopenharmony_ci src += width - (width % 16); 2641cabdff1aSopenharmony_ci width %= 16; 2642cabdff1aSopenharmony_ci } 2643cabdff1aSopenharmony_ci 2644cabdff1aSopenharmony_ci if (width >> 3) { 2645cabdff1aSopenharmony_ci hevc_sao_edge_filter_0degree_8width_msa(dst, stride_dst, 2646cabdff1aSopenharmony_ci src, stride_src, 2647cabdff1aSopenharmony_ci sao_offset_val, height); 2648cabdff1aSopenharmony_ci dst += 8; 2649cabdff1aSopenharmony_ci src += 8; 2650cabdff1aSopenharmony_ci width %= 8; 2651cabdff1aSopenharmony_ci } 2652cabdff1aSopenharmony_ci 2653cabdff1aSopenharmony_ci if (width) { 2654cabdff1aSopenharmony_ci hevc_sao_edge_filter_0degree_4width_msa(dst, stride_dst, 2655cabdff1aSopenharmony_ci src, stride_src, 2656cabdff1aSopenharmony_ci sao_offset_val, height); 2657cabdff1aSopenharmony_ci } 2658cabdff1aSopenharmony_ci break; 2659cabdff1aSopenharmony_ci 2660cabdff1aSopenharmony_ci case 1: 2661cabdff1aSopenharmony_ci if (width >> 4) { 2662cabdff1aSopenharmony_ci hevc_sao_edge_filter_90degree_16multiple_msa(dst, stride_dst, 2663cabdff1aSopenharmony_ci src, stride_src, 2664cabdff1aSopenharmony_ci sao_offset_val, 2665cabdff1aSopenharmony_ci width - (width % 16), 2666cabdff1aSopenharmony_ci height); 2667cabdff1aSopenharmony_ci dst += width - (width % 16); 2668cabdff1aSopenharmony_ci src += width - (width % 16); 2669cabdff1aSopenharmony_ci width %= 16; 2670cabdff1aSopenharmony_ci } 2671cabdff1aSopenharmony_ci 2672cabdff1aSopenharmony_ci if (width >> 3) { 2673cabdff1aSopenharmony_ci hevc_sao_edge_filter_90degree_8width_msa(dst, stride_dst, 2674cabdff1aSopenharmony_ci src, stride_src, 2675cabdff1aSopenharmony_ci sao_offset_val, height); 2676cabdff1aSopenharmony_ci dst += 8; 2677cabdff1aSopenharmony_ci src += 8; 2678cabdff1aSopenharmony_ci width %= 8; 2679cabdff1aSopenharmony_ci } 2680cabdff1aSopenharmony_ci 2681cabdff1aSopenharmony_ci if (width) { 2682cabdff1aSopenharmony_ci hevc_sao_edge_filter_90degree_4width_msa(dst, stride_dst, 2683cabdff1aSopenharmony_ci src, stride_src, 2684cabdff1aSopenharmony_ci sao_offset_val, height); 2685cabdff1aSopenharmony_ci } 2686cabdff1aSopenharmony_ci break; 2687cabdff1aSopenharmony_ci 2688cabdff1aSopenharmony_ci case 2: 2689cabdff1aSopenharmony_ci if (width >> 4) { 2690cabdff1aSopenharmony_ci hevc_sao_edge_filter_45degree_16multiple_msa(dst, stride_dst, 2691cabdff1aSopenharmony_ci src, stride_src, 2692cabdff1aSopenharmony_ci sao_offset_val, 2693cabdff1aSopenharmony_ci width - (width % 16), 2694cabdff1aSopenharmony_ci height); 2695cabdff1aSopenharmony_ci dst += width - (width % 16); 2696cabdff1aSopenharmony_ci src += width - (width % 16); 2697cabdff1aSopenharmony_ci width %= 16; 2698cabdff1aSopenharmony_ci } 2699cabdff1aSopenharmony_ci 2700cabdff1aSopenharmony_ci if (width >> 3) { 2701cabdff1aSopenharmony_ci hevc_sao_edge_filter_45degree_8width_msa(dst, stride_dst, 2702cabdff1aSopenharmony_ci src, stride_src, 2703cabdff1aSopenharmony_ci sao_offset_val, height); 2704cabdff1aSopenharmony_ci dst += 8; 2705cabdff1aSopenharmony_ci src += 8; 2706cabdff1aSopenharmony_ci width %= 8; 2707cabdff1aSopenharmony_ci } 2708cabdff1aSopenharmony_ci 2709cabdff1aSopenharmony_ci if (width) { 2710cabdff1aSopenharmony_ci hevc_sao_edge_filter_45degree_4width_msa(dst, stride_dst, 2711cabdff1aSopenharmony_ci src, stride_src, 2712cabdff1aSopenharmony_ci sao_offset_val, height); 2713cabdff1aSopenharmony_ci } 2714cabdff1aSopenharmony_ci break; 2715cabdff1aSopenharmony_ci 2716cabdff1aSopenharmony_ci case 3: 2717cabdff1aSopenharmony_ci if (width >> 4) { 2718cabdff1aSopenharmony_ci hevc_sao_edge_filter_135degree_16multiple_msa(dst, stride_dst, 2719cabdff1aSopenharmony_ci src, stride_src, 2720cabdff1aSopenharmony_ci sao_offset_val, 2721cabdff1aSopenharmony_ci width - (width % 16), 2722cabdff1aSopenharmony_ci height); 2723cabdff1aSopenharmony_ci dst += width - (width % 16); 2724cabdff1aSopenharmony_ci src += width - (width % 16); 2725cabdff1aSopenharmony_ci width %= 16; 2726cabdff1aSopenharmony_ci } 2727cabdff1aSopenharmony_ci 2728cabdff1aSopenharmony_ci if (width >> 3) { 2729cabdff1aSopenharmony_ci hevc_sao_edge_filter_135degree_8width_msa(dst, stride_dst, 2730cabdff1aSopenharmony_ci src, stride_src, 2731cabdff1aSopenharmony_ci sao_offset_val, height); 2732cabdff1aSopenharmony_ci dst += 8; 2733cabdff1aSopenharmony_ci src += 8; 2734cabdff1aSopenharmony_ci width %= 8; 2735cabdff1aSopenharmony_ci } 2736cabdff1aSopenharmony_ci 2737cabdff1aSopenharmony_ci if (width) { 2738cabdff1aSopenharmony_ci hevc_sao_edge_filter_135degree_4width_msa(dst, stride_dst, 2739cabdff1aSopenharmony_ci src, stride_src, 2740cabdff1aSopenharmony_ci sao_offset_val, height); 2741cabdff1aSopenharmony_ci } 2742cabdff1aSopenharmony_ci break; 2743cabdff1aSopenharmony_ci } 2744cabdff1aSopenharmony_ci} 2745