1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * AltiVec-enhanced yuv2yuvX 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * Copyright (C) 2004 Romain Dolbeau <romain@dolbeau.org> 5cabdff1aSopenharmony_ci * based on the equivalent C code in swscale.c 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * This file is part of FFmpeg. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 10cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 11cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 12cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 15cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 16cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17cabdff1aSopenharmony_ci * Lesser General Public License for more details. 18cabdff1aSopenharmony_ci * 19cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 20cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 21cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22cabdff1aSopenharmony_ci */ 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci#include <inttypes.h> 25cabdff1aSopenharmony_ci 26cabdff1aSopenharmony_ci#include "config.h" 27cabdff1aSopenharmony_ci#include "libswscale/swscale.h" 28cabdff1aSopenharmony_ci#include "libswscale/swscale_internal.h" 29cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 30cabdff1aSopenharmony_ci#include "libavutil/cpu.h" 31cabdff1aSopenharmony_ci#include "libavutil/mem_internal.h" 32cabdff1aSopenharmony_ci#include "yuv2rgb_altivec.h" 33cabdff1aSopenharmony_ci#include "libavutil/ppc/util_altivec.h" 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_ci#if HAVE_VSX 36cabdff1aSopenharmony_ci#define vzero vec_splat_s32(0) 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_ci#if !HAVE_BIGENDIAN 39cabdff1aSopenharmony_ci#define GET_LS(a,b,c,s) {\ 40cabdff1aSopenharmony_ci ls = a;\ 41cabdff1aSopenharmony_ci a = vec_vsx_ld(((b) << 1) + 16, s);\ 42cabdff1aSopenharmony_ci } 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_ci#define yuv2planeX_8(d1, d2, l1, src, x, perm, filter) do {\ 45cabdff1aSopenharmony_ci vector signed short ls;\ 46cabdff1aSopenharmony_ci vector signed int vf1, vf2, i1, i2;\ 47cabdff1aSopenharmony_ci GET_LS(l1, x, perm, src);\ 48cabdff1aSopenharmony_ci i1 = vec_mule(filter, ls);\ 49cabdff1aSopenharmony_ci i2 = vec_mulo(filter, ls);\ 50cabdff1aSopenharmony_ci vf1 = vec_mergeh(i1, i2);\ 51cabdff1aSopenharmony_ci vf2 = vec_mergel(i1, i2);\ 52cabdff1aSopenharmony_ci d1 = vec_add(d1, vf1);\ 53cabdff1aSopenharmony_ci d2 = vec_add(d2, vf2);\ 54cabdff1aSopenharmony_ci } while (0) 55cabdff1aSopenharmony_ci 56cabdff1aSopenharmony_ci#define LOAD_FILTER(vf,f) {\ 57cabdff1aSopenharmony_ci vf = vec_vsx_ld(joffset, f);\ 58cabdff1aSopenharmony_ci} 59cabdff1aSopenharmony_ci#define LOAD_L1(ll1,s,p){\ 60cabdff1aSopenharmony_ci ll1 = vec_vsx_ld(xoffset, s);\ 61cabdff1aSopenharmony_ci} 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_ci// The 3 above is 2 (filterSize == 4) + 1 (sizeof(short) == 2). 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_ci// The neat trick: We only care for half the elements, 66cabdff1aSopenharmony_ci// high or low depending on (i<<3)%16 (it's 0 or 8 here), 67cabdff1aSopenharmony_ci// and we're going to use vec_mule, so we choose 68cabdff1aSopenharmony_ci// carefully how to "unpack" the elements into the even slots. 69cabdff1aSopenharmony_ci#define GET_VF4(a, vf, f) {\ 70cabdff1aSopenharmony_ci vf = (vector signed short)vec_vsx_ld(a << 3, f);\ 71cabdff1aSopenharmony_ci vf = vec_mergeh(vf, (vector signed short)vzero);\ 72cabdff1aSopenharmony_ci} 73cabdff1aSopenharmony_ci#define FIRST_LOAD(sv, pos, s, per) {} 74cabdff1aSopenharmony_ci#define UPDATE_PTR(s0, d0, s1, d1) {} 75cabdff1aSopenharmony_ci#define LOAD_SRCV(pos, a, s, per, v0, v1, vf) {\ 76cabdff1aSopenharmony_ci vf = vec_vsx_ld(pos + a, s);\ 77cabdff1aSopenharmony_ci} 78cabdff1aSopenharmony_ci#define LOAD_SRCV8(pos, a, s, per, v0, v1, vf) LOAD_SRCV(pos, a, s, per, v0, v1, vf) 79cabdff1aSopenharmony_ci#define GET_VFD(a, b, f, vf0, vf1, per, vf, off) {\ 80cabdff1aSopenharmony_ci vf = vec_vsx_ld((a * 2 * filterSize) + (b * 2) + off, f);\ 81cabdff1aSopenharmony_ci} 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_ci#define FUNC(name) name ## _vsx 84cabdff1aSopenharmony_ci#include "swscale_ppc_template.c" 85cabdff1aSopenharmony_ci#undef FUNC 86cabdff1aSopenharmony_ci 87cabdff1aSopenharmony_ci#undef vzero 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_ci#endif /* !HAVE_BIGENDIAN */ 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_cistatic void yuv2plane1_8_u(const int16_t *src, uint8_t *dest, int dstW, 92cabdff1aSopenharmony_ci const uint8_t *dither, int offset, int start) 93cabdff1aSopenharmony_ci{ 94cabdff1aSopenharmony_ci int i; 95cabdff1aSopenharmony_ci for (i = start; i < dstW; i++) { 96cabdff1aSopenharmony_ci int val = (src[i] + dither[(i + offset) & 7]) >> 7; 97cabdff1aSopenharmony_ci dest[i] = av_clip_uint8(val); 98cabdff1aSopenharmony_ci } 99cabdff1aSopenharmony_ci} 100cabdff1aSopenharmony_ci 101cabdff1aSopenharmony_cistatic void yuv2plane1_8_vsx(const int16_t *src, uint8_t *dest, int dstW, 102cabdff1aSopenharmony_ci const uint8_t *dither, int offset) 103cabdff1aSopenharmony_ci{ 104cabdff1aSopenharmony_ci const int dst_u = -(uintptr_t)dest & 15; 105cabdff1aSopenharmony_ci int i, j; 106cabdff1aSopenharmony_ci LOCAL_ALIGNED(16, int16_t, val, [16]); 107cabdff1aSopenharmony_ci const vec_u16 shifts = (vec_u16) {7, 7, 7, 7, 7, 7, 7, 7}; 108cabdff1aSopenharmony_ci vec_s16 vi, vileft, ditherleft, ditherright; 109cabdff1aSopenharmony_ci vec_u8 vd; 110cabdff1aSopenharmony_ci 111cabdff1aSopenharmony_ci for (j = 0; j < 16; j++) { 112cabdff1aSopenharmony_ci val[j] = dither[(dst_u + offset + j) & 7]; 113cabdff1aSopenharmony_ci } 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci ditherleft = vec_ld(0, val); 116cabdff1aSopenharmony_ci ditherright = vec_ld(0, &val[8]); 117cabdff1aSopenharmony_ci 118cabdff1aSopenharmony_ci yuv2plane1_8_u(src, dest, dst_u, dither, offset, 0); 119cabdff1aSopenharmony_ci 120cabdff1aSopenharmony_ci for (i = dst_u; i < dstW - 15; i += 16) { 121cabdff1aSopenharmony_ci 122cabdff1aSopenharmony_ci vi = vec_vsx_ld(0, &src[i]); 123cabdff1aSopenharmony_ci vi = vec_adds(ditherleft, vi); 124cabdff1aSopenharmony_ci vileft = vec_sra(vi, shifts); 125cabdff1aSopenharmony_ci 126cabdff1aSopenharmony_ci vi = vec_vsx_ld(0, &src[i + 8]); 127cabdff1aSopenharmony_ci vi = vec_adds(ditherright, vi); 128cabdff1aSopenharmony_ci vi = vec_sra(vi, shifts); 129cabdff1aSopenharmony_ci 130cabdff1aSopenharmony_ci vd = vec_packsu(vileft, vi); 131cabdff1aSopenharmony_ci vec_st(vd, 0, &dest[i]); 132cabdff1aSopenharmony_ci } 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_ci yuv2plane1_8_u(src, dest, dstW, dither, offset, i); 135cabdff1aSopenharmony_ci} 136cabdff1aSopenharmony_ci 137cabdff1aSopenharmony_ci#if !HAVE_BIGENDIAN 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_ci#define output_pixel(pos, val) \ 140cabdff1aSopenharmony_ci if (big_endian) { \ 141cabdff1aSopenharmony_ci AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \ 142cabdff1aSopenharmony_ci } else { \ 143cabdff1aSopenharmony_ci AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \ 144cabdff1aSopenharmony_ci } 145cabdff1aSopenharmony_ci 146cabdff1aSopenharmony_cistatic void yuv2plane1_nbps_u(const int16_t *src, uint16_t *dest, int dstW, 147cabdff1aSopenharmony_ci int big_endian, int output_bits, int start) 148cabdff1aSopenharmony_ci{ 149cabdff1aSopenharmony_ci int i; 150cabdff1aSopenharmony_ci int shift = 15 - output_bits; 151cabdff1aSopenharmony_ci 152cabdff1aSopenharmony_ci for (i = start; i < dstW; i++) { 153cabdff1aSopenharmony_ci int val = src[i] + (1 << (shift - 1)); 154cabdff1aSopenharmony_ci output_pixel(&dest[i], val); 155cabdff1aSopenharmony_ci } 156cabdff1aSopenharmony_ci} 157cabdff1aSopenharmony_ci 158cabdff1aSopenharmony_cistatic av_always_inline void yuv2plane1_nbps_vsx(const int16_t *src, 159cabdff1aSopenharmony_ci uint16_t *dest, int dstW, 160cabdff1aSopenharmony_ci const int big_endian, 161cabdff1aSopenharmony_ci const int output_bits) 162cabdff1aSopenharmony_ci{ 163cabdff1aSopenharmony_ci const int dst_u = -(uintptr_t)dest & 7; 164cabdff1aSopenharmony_ci const int shift = 15 - output_bits; 165cabdff1aSopenharmony_ci const int add = (1 << (shift - 1)); 166cabdff1aSopenharmony_ci const int clip = (1 << output_bits) - 1; 167cabdff1aSopenharmony_ci const vec_u16 vadd = (vec_u16) {add, add, add, add, add, add, add, add}; 168cabdff1aSopenharmony_ci const vec_u16 vswap = (vec_u16) vec_splat_u16(big_endian ? 8 : 0); 169cabdff1aSopenharmony_ci const vec_u16 vshift = (vec_u16) vec_splat_u16(shift); 170cabdff1aSopenharmony_ci const vec_u16 vlargest = (vec_u16) {clip, clip, clip, clip, clip, clip, clip, clip}; 171cabdff1aSopenharmony_ci vec_u16 v; 172cabdff1aSopenharmony_ci int i; 173cabdff1aSopenharmony_ci 174cabdff1aSopenharmony_ci yuv2plane1_nbps_u(src, dest, dst_u, big_endian, output_bits, 0); 175cabdff1aSopenharmony_ci 176cabdff1aSopenharmony_ci for (i = dst_u; i < dstW - 7; i += 8) { 177cabdff1aSopenharmony_ci v = vec_vsx_ld(0, (const uint16_t *) &src[i]); 178cabdff1aSopenharmony_ci v = vec_add(v, vadd); 179cabdff1aSopenharmony_ci v = vec_sr(v, vshift); 180cabdff1aSopenharmony_ci v = vec_min(v, vlargest); 181cabdff1aSopenharmony_ci v = vec_rl(v, vswap); 182cabdff1aSopenharmony_ci vec_st(v, 0, &dest[i]); 183cabdff1aSopenharmony_ci } 184cabdff1aSopenharmony_ci 185cabdff1aSopenharmony_ci yuv2plane1_nbps_u(src, dest, dstW, big_endian, output_bits, i); 186cabdff1aSopenharmony_ci} 187cabdff1aSopenharmony_ci 188cabdff1aSopenharmony_cistatic void yuv2planeX_nbps_u(const int16_t *filter, int filterSize, 189cabdff1aSopenharmony_ci const int16_t **src, uint16_t *dest, int dstW, 190cabdff1aSopenharmony_ci int big_endian, int output_bits, int start) 191cabdff1aSopenharmony_ci{ 192cabdff1aSopenharmony_ci int i; 193cabdff1aSopenharmony_ci int shift = 11 + 16 - output_bits; 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_ci for (i = start; i < dstW; i++) { 196cabdff1aSopenharmony_ci int val = 1 << (shift - 1); 197cabdff1aSopenharmony_ci int j; 198cabdff1aSopenharmony_ci 199cabdff1aSopenharmony_ci for (j = 0; j < filterSize; j++) 200cabdff1aSopenharmony_ci val += src[j][i] * filter[j]; 201cabdff1aSopenharmony_ci 202cabdff1aSopenharmony_ci output_pixel(&dest[i], val); 203cabdff1aSopenharmony_ci } 204cabdff1aSopenharmony_ci} 205cabdff1aSopenharmony_ci 206cabdff1aSopenharmony_cistatic void yuv2planeX_nbps_vsx(const int16_t *filter, int filterSize, 207cabdff1aSopenharmony_ci const int16_t **src, uint16_t *dest, int dstW, 208cabdff1aSopenharmony_ci int big_endian, int output_bits) 209cabdff1aSopenharmony_ci{ 210cabdff1aSopenharmony_ci const int dst_u = -(uintptr_t)dest & 7; 211cabdff1aSopenharmony_ci const int shift = 11 + 16 - output_bits; 212cabdff1aSopenharmony_ci const int add = (1 << (shift - 1)); 213cabdff1aSopenharmony_ci const int clip = (1 << output_bits) - 1; 214cabdff1aSopenharmony_ci const uint16_t swap = big_endian ? 8 : 0; 215cabdff1aSopenharmony_ci const vec_u32 vadd = (vec_u32) {add, add, add, add}; 216cabdff1aSopenharmony_ci const vec_u32 vshift = (vec_u32) {shift, shift, shift, shift}; 217cabdff1aSopenharmony_ci const vec_u16 vswap = (vec_u16) {swap, swap, swap, swap, swap, swap, swap, swap}; 218cabdff1aSopenharmony_ci const vec_u16 vlargest = (vec_u16) {clip, clip, clip, clip, clip, clip, clip, clip}; 219cabdff1aSopenharmony_ci const vec_s16 vzero = vec_splat_s16(0); 220cabdff1aSopenharmony_ci const vec_u8 vperm = (vec_u8) {0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15}; 221cabdff1aSopenharmony_ci vec_s16 vfilter[MAX_FILTER_SIZE], vin; 222cabdff1aSopenharmony_ci vec_u16 v; 223cabdff1aSopenharmony_ci vec_u32 vleft, vright, vtmp; 224cabdff1aSopenharmony_ci int i, j; 225cabdff1aSopenharmony_ci 226cabdff1aSopenharmony_ci for (i = 0; i < filterSize; i++) { 227cabdff1aSopenharmony_ci vfilter[i] = (vec_s16) {filter[i], filter[i], filter[i], filter[i], 228cabdff1aSopenharmony_ci filter[i], filter[i], filter[i], filter[i]}; 229cabdff1aSopenharmony_ci } 230cabdff1aSopenharmony_ci 231cabdff1aSopenharmony_ci yuv2planeX_nbps_u(filter, filterSize, src, dest, dst_u, big_endian, output_bits, 0); 232cabdff1aSopenharmony_ci 233cabdff1aSopenharmony_ci for (i = dst_u; i < dstW - 7; i += 8) { 234cabdff1aSopenharmony_ci vleft = vright = vadd; 235cabdff1aSopenharmony_ci 236cabdff1aSopenharmony_ci for (j = 0; j < filterSize; j++) { 237cabdff1aSopenharmony_ci vin = vec_vsx_ld(0, &src[j][i]); 238cabdff1aSopenharmony_ci vtmp = (vec_u32) vec_mule(vin, vfilter[j]); 239cabdff1aSopenharmony_ci vleft = vec_add(vleft, vtmp); 240cabdff1aSopenharmony_ci vtmp = (vec_u32) vec_mulo(vin, vfilter[j]); 241cabdff1aSopenharmony_ci vright = vec_add(vright, vtmp); 242cabdff1aSopenharmony_ci } 243cabdff1aSopenharmony_ci 244cabdff1aSopenharmony_ci vleft = vec_sra(vleft, vshift); 245cabdff1aSopenharmony_ci vright = vec_sra(vright, vshift); 246cabdff1aSopenharmony_ci v = vec_packsu(vleft, vright); 247cabdff1aSopenharmony_ci v = (vec_u16) vec_max((vec_s16) v, vzero); 248cabdff1aSopenharmony_ci v = vec_min(v, vlargest); 249cabdff1aSopenharmony_ci v = vec_rl(v, vswap); 250cabdff1aSopenharmony_ci v = vec_perm(v, v, vperm); 251cabdff1aSopenharmony_ci vec_st(v, 0, &dest[i]); 252cabdff1aSopenharmony_ci } 253cabdff1aSopenharmony_ci 254cabdff1aSopenharmony_ci yuv2planeX_nbps_u(filter, filterSize, src, dest, dstW, big_endian, output_bits, i); 255cabdff1aSopenharmony_ci} 256cabdff1aSopenharmony_ci 257cabdff1aSopenharmony_ci 258cabdff1aSopenharmony_ci#undef output_pixel 259cabdff1aSopenharmony_ci 260cabdff1aSopenharmony_ci#define output_pixel(pos, val, bias, signedness) \ 261cabdff1aSopenharmony_ci if (big_endian) { \ 262cabdff1aSopenharmony_ci AV_WB16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \ 263cabdff1aSopenharmony_ci } else { \ 264cabdff1aSopenharmony_ci AV_WL16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \ 265cabdff1aSopenharmony_ci } 266cabdff1aSopenharmony_ci 267cabdff1aSopenharmony_cistatic void yuv2plane1_16_u(const int32_t *src, uint16_t *dest, int dstW, 268cabdff1aSopenharmony_ci int big_endian, int output_bits, int start) 269cabdff1aSopenharmony_ci{ 270cabdff1aSopenharmony_ci int i; 271cabdff1aSopenharmony_ci const int shift = 3; 272cabdff1aSopenharmony_ci 273cabdff1aSopenharmony_ci for (i = start; i < dstW; i++) { 274cabdff1aSopenharmony_ci int val = src[i] + (1 << (shift - 1)); 275cabdff1aSopenharmony_ci output_pixel(&dest[i], val, 0, uint); 276cabdff1aSopenharmony_ci } 277cabdff1aSopenharmony_ci} 278cabdff1aSopenharmony_ci 279cabdff1aSopenharmony_cistatic av_always_inline void yuv2plane1_16_vsx(const int32_t *src, 280cabdff1aSopenharmony_ci uint16_t *dest, int dstW, 281cabdff1aSopenharmony_ci const int big_endian, 282cabdff1aSopenharmony_ci int output_bits) 283cabdff1aSopenharmony_ci{ 284cabdff1aSopenharmony_ci const int dst_u = -(uintptr_t)dest & 7; 285cabdff1aSopenharmony_ci const int shift = 3; 286cabdff1aSopenharmony_ci const int add = (1 << (shift - 1)); 287cabdff1aSopenharmony_ci const vec_u32 vadd = (vec_u32) {add, add, add, add}; 288cabdff1aSopenharmony_ci const vec_u16 vswap = (vec_u16) vec_splat_u16(big_endian ? 8 : 0); 289cabdff1aSopenharmony_ci const vec_u32 vshift = (vec_u32) vec_splat_u32(shift); 290cabdff1aSopenharmony_ci vec_u32 v, v2; 291cabdff1aSopenharmony_ci vec_u16 vd; 292cabdff1aSopenharmony_ci int i; 293cabdff1aSopenharmony_ci 294cabdff1aSopenharmony_ci yuv2plane1_16_u(src, dest, dst_u, big_endian, output_bits, 0); 295cabdff1aSopenharmony_ci 296cabdff1aSopenharmony_ci for (i = dst_u; i < dstW - 7; i += 8) { 297cabdff1aSopenharmony_ci v = vec_vsx_ld(0, (const uint32_t *) &src[i]); 298cabdff1aSopenharmony_ci v = vec_add(v, vadd); 299cabdff1aSopenharmony_ci v = vec_sr(v, vshift); 300cabdff1aSopenharmony_ci 301cabdff1aSopenharmony_ci v2 = vec_vsx_ld(0, (const uint32_t *) &src[i + 4]); 302cabdff1aSopenharmony_ci v2 = vec_add(v2, vadd); 303cabdff1aSopenharmony_ci v2 = vec_sr(v2, vshift); 304cabdff1aSopenharmony_ci 305cabdff1aSopenharmony_ci vd = vec_packsu(v, v2); 306cabdff1aSopenharmony_ci vd = vec_rl(vd, vswap); 307cabdff1aSopenharmony_ci 308cabdff1aSopenharmony_ci vec_st(vd, 0, &dest[i]); 309cabdff1aSopenharmony_ci } 310cabdff1aSopenharmony_ci 311cabdff1aSopenharmony_ci yuv2plane1_16_u(src, dest, dstW, big_endian, output_bits, i); 312cabdff1aSopenharmony_ci} 313cabdff1aSopenharmony_ci 314cabdff1aSopenharmony_ci#if HAVE_POWER8 315cabdff1aSopenharmony_ci 316cabdff1aSopenharmony_cistatic void yuv2planeX_16_u(const int16_t *filter, int filterSize, 317cabdff1aSopenharmony_ci const int32_t **src, uint16_t *dest, int dstW, 318cabdff1aSopenharmony_ci int big_endian, int output_bits, int start) 319cabdff1aSopenharmony_ci{ 320cabdff1aSopenharmony_ci int i; 321cabdff1aSopenharmony_ci int shift = 15; 322cabdff1aSopenharmony_ci 323cabdff1aSopenharmony_ci for (i = start; i < dstW; i++) { 324cabdff1aSopenharmony_ci int val = 1 << (shift - 1); 325cabdff1aSopenharmony_ci int j; 326cabdff1aSopenharmony_ci 327cabdff1aSopenharmony_ci /* range of val is [0,0x7FFFFFFF], so 31 bits, but with lanczos/spline 328cabdff1aSopenharmony_ci * filters (or anything with negative coeffs, the range can be slightly 329cabdff1aSopenharmony_ci * wider in both directions. To account for this overflow, we subtract 330cabdff1aSopenharmony_ci * a constant so it always fits in the signed range (assuming a 331cabdff1aSopenharmony_ci * reasonable filterSize), and re-add that at the end. */ 332cabdff1aSopenharmony_ci val -= 0x40000000; 333cabdff1aSopenharmony_ci for (j = 0; j < filterSize; j++) 334cabdff1aSopenharmony_ci val += src[j][i] * (unsigned)filter[j]; 335cabdff1aSopenharmony_ci 336cabdff1aSopenharmony_ci output_pixel(&dest[i], val, 0x8000, int); 337cabdff1aSopenharmony_ci } 338cabdff1aSopenharmony_ci} 339cabdff1aSopenharmony_ci 340cabdff1aSopenharmony_cistatic void yuv2planeX_16_vsx(const int16_t *filter, int filterSize, 341cabdff1aSopenharmony_ci const int32_t **src, uint16_t *dest, int dstW, 342cabdff1aSopenharmony_ci int big_endian, int output_bits) 343cabdff1aSopenharmony_ci{ 344cabdff1aSopenharmony_ci const int dst_u = -(uintptr_t)dest & 7; 345cabdff1aSopenharmony_ci const int shift = 15; 346cabdff1aSopenharmony_ci const int bias = 0x8000; 347cabdff1aSopenharmony_ci const int add = (1 << (shift - 1)) - 0x40000000; 348cabdff1aSopenharmony_ci const uint16_t swap = big_endian ? 8 : 0; 349cabdff1aSopenharmony_ci const vec_u32 vadd = (vec_u32) {add, add, add, add}; 350cabdff1aSopenharmony_ci const vec_u32 vshift = (vec_u32) {shift, shift, shift, shift}; 351cabdff1aSopenharmony_ci const vec_u16 vswap = (vec_u16) {swap, swap, swap, swap, swap, swap, swap, swap}; 352cabdff1aSopenharmony_ci const vec_u16 vbias = (vec_u16) {bias, bias, bias, bias, bias, bias, bias, bias}; 353cabdff1aSopenharmony_ci vec_s32 vfilter[MAX_FILTER_SIZE]; 354cabdff1aSopenharmony_ci vec_u16 v; 355cabdff1aSopenharmony_ci vec_u32 vleft, vright, vtmp; 356cabdff1aSopenharmony_ci vec_s32 vin32l, vin32r; 357cabdff1aSopenharmony_ci int i, j; 358cabdff1aSopenharmony_ci 359cabdff1aSopenharmony_ci for (i = 0; i < filterSize; i++) { 360cabdff1aSopenharmony_ci vfilter[i] = (vec_s32) {filter[i], filter[i], filter[i], filter[i]}; 361cabdff1aSopenharmony_ci } 362cabdff1aSopenharmony_ci 363cabdff1aSopenharmony_ci yuv2planeX_16_u(filter, filterSize, src, dest, dst_u, big_endian, output_bits, 0); 364cabdff1aSopenharmony_ci 365cabdff1aSopenharmony_ci for (i = dst_u; i < dstW - 7; i += 8) { 366cabdff1aSopenharmony_ci vleft = vright = vadd; 367cabdff1aSopenharmony_ci 368cabdff1aSopenharmony_ci for (j = 0; j < filterSize; j++) { 369cabdff1aSopenharmony_ci vin32l = vec_vsx_ld(0, &src[j][i]); 370cabdff1aSopenharmony_ci vin32r = vec_vsx_ld(0, &src[j][i + 4]); 371cabdff1aSopenharmony_ci 372cabdff1aSopenharmony_ci vtmp = (vec_u32) vec_mul(vin32l, vfilter[j]); 373cabdff1aSopenharmony_ci vleft = vec_add(vleft, vtmp); 374cabdff1aSopenharmony_ci vtmp = (vec_u32) vec_mul(vin32r, vfilter[j]); 375cabdff1aSopenharmony_ci vright = vec_add(vright, vtmp); 376cabdff1aSopenharmony_ci } 377cabdff1aSopenharmony_ci 378cabdff1aSopenharmony_ci vleft = vec_sra(vleft, vshift); 379cabdff1aSopenharmony_ci vright = vec_sra(vright, vshift); 380cabdff1aSopenharmony_ci v = (vec_u16) vec_packs((vec_s32) vleft, (vec_s32) vright); 381cabdff1aSopenharmony_ci v = vec_add(v, vbias); 382cabdff1aSopenharmony_ci v = vec_rl(v, vswap); 383cabdff1aSopenharmony_ci vec_st(v, 0, &dest[i]); 384cabdff1aSopenharmony_ci } 385cabdff1aSopenharmony_ci 386cabdff1aSopenharmony_ci yuv2planeX_16_u(filter, filterSize, src, dest, dstW, big_endian, output_bits, i); 387cabdff1aSopenharmony_ci} 388cabdff1aSopenharmony_ci 389cabdff1aSopenharmony_ci#endif /* HAVE_POWER8 */ 390cabdff1aSopenharmony_ci 391cabdff1aSopenharmony_ci#define yuv2NBPS(bits, BE_LE, is_be, template_size, typeX_t) \ 392cabdff1aSopenharmony_ci yuv2NBPS1(bits, BE_LE, is_be, template_size, typeX_t) \ 393cabdff1aSopenharmony_ci yuv2NBPSX(bits, BE_LE, is_be, template_size, typeX_t) 394cabdff1aSopenharmony_ci 395cabdff1aSopenharmony_ci#define yuv2NBPS1(bits, BE_LE, is_be, template_size, typeX_t) \ 396cabdff1aSopenharmony_cistatic void yuv2plane1_ ## bits ## BE_LE ## _vsx(const int16_t *src, \ 397cabdff1aSopenharmony_ci uint8_t *dest, int dstW, \ 398cabdff1aSopenharmony_ci const uint8_t *dither, int offset) \ 399cabdff1aSopenharmony_ci{ \ 400cabdff1aSopenharmony_ci yuv2plane1_ ## template_size ## _vsx((const typeX_t *) src, \ 401cabdff1aSopenharmony_ci (uint16_t *) dest, dstW, is_be, bits); \ 402cabdff1aSopenharmony_ci} 403cabdff1aSopenharmony_ci 404cabdff1aSopenharmony_ci#define yuv2NBPSX(bits, BE_LE, is_be, template_size, typeX_t) \ 405cabdff1aSopenharmony_cistatic void yuv2planeX_ ## bits ## BE_LE ## _vsx(const int16_t *filter, int filterSize, \ 406cabdff1aSopenharmony_ci const int16_t **src, uint8_t *dest, int dstW, \ 407cabdff1aSopenharmony_ci const uint8_t *dither, int offset)\ 408cabdff1aSopenharmony_ci{ \ 409cabdff1aSopenharmony_ci yuv2planeX_## template_size ## _vsx(filter, \ 410cabdff1aSopenharmony_ci filterSize, (const typeX_t **) src, \ 411cabdff1aSopenharmony_ci (uint16_t *) dest, dstW, is_be, bits); \ 412cabdff1aSopenharmony_ci} 413cabdff1aSopenharmony_ci 414cabdff1aSopenharmony_ciyuv2NBPS( 9, BE, 1, nbps, int16_t) 415cabdff1aSopenharmony_ciyuv2NBPS( 9, LE, 0, nbps, int16_t) 416cabdff1aSopenharmony_ciyuv2NBPS(10, BE, 1, nbps, int16_t) 417cabdff1aSopenharmony_ciyuv2NBPS(10, LE, 0, nbps, int16_t) 418cabdff1aSopenharmony_ciyuv2NBPS(12, BE, 1, nbps, int16_t) 419cabdff1aSopenharmony_ciyuv2NBPS(12, LE, 0, nbps, int16_t) 420cabdff1aSopenharmony_ciyuv2NBPS(14, BE, 1, nbps, int16_t) 421cabdff1aSopenharmony_ciyuv2NBPS(14, LE, 0, nbps, int16_t) 422cabdff1aSopenharmony_ci 423cabdff1aSopenharmony_ciyuv2NBPS1(16, BE, 1, 16, int32_t) 424cabdff1aSopenharmony_ciyuv2NBPS1(16, LE, 0, 16, int32_t) 425cabdff1aSopenharmony_ci#if HAVE_POWER8 426cabdff1aSopenharmony_ciyuv2NBPSX(16, BE, 1, 16, int32_t) 427cabdff1aSopenharmony_ciyuv2NBPSX(16, LE, 0, 16, int32_t) 428cabdff1aSopenharmony_ci#endif 429cabdff1aSopenharmony_ci 430cabdff1aSopenharmony_ci#define WRITERGB \ 431cabdff1aSopenharmony_ci R_l = vec_max(R_l, zero32); \ 432cabdff1aSopenharmony_ci R_r = vec_max(R_r, zero32); \ 433cabdff1aSopenharmony_ci G_l = vec_max(G_l, zero32); \ 434cabdff1aSopenharmony_ci G_r = vec_max(G_r, zero32); \ 435cabdff1aSopenharmony_ci B_l = vec_max(B_l, zero32); \ 436cabdff1aSopenharmony_ci B_r = vec_max(B_r, zero32); \ 437cabdff1aSopenharmony_ci\ 438cabdff1aSopenharmony_ci R_l = vec_min(R_l, rgbclip); \ 439cabdff1aSopenharmony_ci R_r = vec_min(R_r, rgbclip); \ 440cabdff1aSopenharmony_ci G_l = vec_min(G_l, rgbclip); \ 441cabdff1aSopenharmony_ci G_r = vec_min(G_r, rgbclip); \ 442cabdff1aSopenharmony_ci B_l = vec_min(B_l, rgbclip); \ 443cabdff1aSopenharmony_ci B_r = vec_min(B_r, rgbclip); \ 444cabdff1aSopenharmony_ci\ 445cabdff1aSopenharmony_ci R_l = vec_sr(R_l, shift22); \ 446cabdff1aSopenharmony_ci R_r = vec_sr(R_r, shift22); \ 447cabdff1aSopenharmony_ci G_l = vec_sr(G_l, shift22); \ 448cabdff1aSopenharmony_ci G_r = vec_sr(G_r, shift22); \ 449cabdff1aSopenharmony_ci B_l = vec_sr(B_l, shift22); \ 450cabdff1aSopenharmony_ci B_r = vec_sr(B_r, shift22); \ 451cabdff1aSopenharmony_ci\ 452cabdff1aSopenharmony_ci rd16 = vec_packsu(R_l, R_r); \ 453cabdff1aSopenharmony_ci gd16 = vec_packsu(G_l, G_r); \ 454cabdff1aSopenharmony_ci bd16 = vec_packsu(B_l, B_r); \ 455cabdff1aSopenharmony_ci rd = vec_packsu(rd16, zero16); \ 456cabdff1aSopenharmony_ci gd = vec_packsu(gd16, zero16); \ 457cabdff1aSopenharmony_ci bd = vec_packsu(bd16, zero16); \ 458cabdff1aSopenharmony_ci\ 459cabdff1aSopenharmony_ci switch(target) { \ 460cabdff1aSopenharmony_ci case AV_PIX_FMT_RGB24: \ 461cabdff1aSopenharmony_ci out0 = vec_perm(rd, gd, perm3rg0); \ 462cabdff1aSopenharmony_ci out0 = vec_perm(out0, bd, perm3tb0); \ 463cabdff1aSopenharmony_ci out1 = vec_perm(rd, gd, perm3rg1); \ 464cabdff1aSopenharmony_ci out1 = vec_perm(out1, bd, perm3tb1); \ 465cabdff1aSopenharmony_ci\ 466cabdff1aSopenharmony_ci vec_vsx_st(out0, 0, dest); \ 467cabdff1aSopenharmony_ci vec_vsx_st(out1, 16, dest); \ 468cabdff1aSopenharmony_ci\ 469cabdff1aSopenharmony_ci dest += 24; \ 470cabdff1aSopenharmony_ci break; \ 471cabdff1aSopenharmony_ci case AV_PIX_FMT_BGR24: \ 472cabdff1aSopenharmony_ci out0 = vec_perm(bd, gd, perm3rg0); \ 473cabdff1aSopenharmony_ci out0 = vec_perm(out0, rd, perm3tb0); \ 474cabdff1aSopenharmony_ci out1 = vec_perm(bd, gd, perm3rg1); \ 475cabdff1aSopenharmony_ci out1 = vec_perm(out1, rd, perm3tb1); \ 476cabdff1aSopenharmony_ci\ 477cabdff1aSopenharmony_ci vec_vsx_st(out0, 0, dest); \ 478cabdff1aSopenharmony_ci vec_vsx_st(out1, 16, dest); \ 479cabdff1aSopenharmony_ci\ 480cabdff1aSopenharmony_ci dest += 24; \ 481cabdff1aSopenharmony_ci break; \ 482cabdff1aSopenharmony_ci case AV_PIX_FMT_BGRA: \ 483cabdff1aSopenharmony_ci out0 = vec_mergeh(bd, gd); \ 484cabdff1aSopenharmony_ci out1 = vec_mergeh(rd, ad); \ 485cabdff1aSopenharmony_ci\ 486cabdff1aSopenharmony_ci tmp8 = (vec_u8) vec_mergeh((vec_u16) out0, (vec_u16) out1); \ 487cabdff1aSopenharmony_ci vec_vsx_st(tmp8, 0, dest); \ 488cabdff1aSopenharmony_ci tmp8 = (vec_u8) vec_mergel((vec_u16) out0, (vec_u16) out1); \ 489cabdff1aSopenharmony_ci vec_vsx_st(tmp8, 16, dest); \ 490cabdff1aSopenharmony_ci\ 491cabdff1aSopenharmony_ci dest += 32; \ 492cabdff1aSopenharmony_ci break; \ 493cabdff1aSopenharmony_ci case AV_PIX_FMT_RGBA: \ 494cabdff1aSopenharmony_ci out0 = vec_mergeh(rd, gd); \ 495cabdff1aSopenharmony_ci out1 = vec_mergeh(bd, ad); \ 496cabdff1aSopenharmony_ci\ 497cabdff1aSopenharmony_ci tmp8 = (vec_u8) vec_mergeh((vec_u16) out0, (vec_u16) out1); \ 498cabdff1aSopenharmony_ci vec_vsx_st(tmp8, 0, dest); \ 499cabdff1aSopenharmony_ci tmp8 = (vec_u8) vec_mergel((vec_u16) out0, (vec_u16) out1); \ 500cabdff1aSopenharmony_ci vec_vsx_st(tmp8, 16, dest); \ 501cabdff1aSopenharmony_ci\ 502cabdff1aSopenharmony_ci dest += 32; \ 503cabdff1aSopenharmony_ci break; \ 504cabdff1aSopenharmony_ci case AV_PIX_FMT_ARGB: \ 505cabdff1aSopenharmony_ci out0 = vec_mergeh(ad, rd); \ 506cabdff1aSopenharmony_ci out1 = vec_mergeh(gd, bd); \ 507cabdff1aSopenharmony_ci\ 508cabdff1aSopenharmony_ci tmp8 = (vec_u8) vec_mergeh((vec_u16) out0, (vec_u16) out1); \ 509cabdff1aSopenharmony_ci vec_vsx_st(tmp8, 0, dest); \ 510cabdff1aSopenharmony_ci tmp8 = (vec_u8) vec_mergel((vec_u16) out0, (vec_u16) out1); \ 511cabdff1aSopenharmony_ci vec_vsx_st(tmp8, 16, dest); \ 512cabdff1aSopenharmony_ci\ 513cabdff1aSopenharmony_ci dest += 32; \ 514cabdff1aSopenharmony_ci break; \ 515cabdff1aSopenharmony_ci case AV_PIX_FMT_ABGR: \ 516cabdff1aSopenharmony_ci out0 = vec_mergeh(ad, bd); \ 517cabdff1aSopenharmony_ci out1 = vec_mergeh(gd, rd); \ 518cabdff1aSopenharmony_ci\ 519cabdff1aSopenharmony_ci tmp8 = (vec_u8) vec_mergeh((vec_u16) out0, (vec_u16) out1); \ 520cabdff1aSopenharmony_ci vec_vsx_st(tmp8, 0, dest); \ 521cabdff1aSopenharmony_ci tmp8 = (vec_u8) vec_mergel((vec_u16) out0, (vec_u16) out1); \ 522cabdff1aSopenharmony_ci vec_vsx_st(tmp8, 16, dest); \ 523cabdff1aSopenharmony_ci\ 524cabdff1aSopenharmony_ci dest += 32; \ 525cabdff1aSopenharmony_ci break; \ 526cabdff1aSopenharmony_ci } 527cabdff1aSopenharmony_ci 528cabdff1aSopenharmony_cistatic av_always_inline void 529cabdff1aSopenharmony_ciyuv2rgb_full_X_vsx_template(SwsContext *c, const int16_t *lumFilter, 530cabdff1aSopenharmony_ci const int16_t **lumSrc, int lumFilterSize, 531cabdff1aSopenharmony_ci const int16_t *chrFilter, const int16_t **chrUSrc, 532cabdff1aSopenharmony_ci const int16_t **chrVSrc, int chrFilterSize, 533cabdff1aSopenharmony_ci const int16_t **alpSrc, uint8_t *dest, 534cabdff1aSopenharmony_ci int dstW, int y, enum AVPixelFormat target, int hasAlpha) 535cabdff1aSopenharmony_ci{ 536cabdff1aSopenharmony_ci vec_s16 vv; 537cabdff1aSopenharmony_ci vec_s32 vy32_l, vy32_r, vu32_l, vu32_r, vv32_l, vv32_r, tmp32; 538cabdff1aSopenharmony_ci vec_s32 R_l, R_r, G_l, G_r, B_l, B_r; 539cabdff1aSopenharmony_ci vec_s32 tmp, tmp2, tmp3, tmp4; 540cabdff1aSopenharmony_ci vec_u16 rd16, gd16, bd16; 541cabdff1aSopenharmony_ci vec_u8 rd, bd, gd, ad, out0, out1, tmp8; 542cabdff1aSopenharmony_ci vec_s16 vlumFilter[MAX_FILTER_SIZE], vchrFilter[MAX_FILTER_SIZE]; 543cabdff1aSopenharmony_ci const vec_s32 ystart = vec_splats(1 << 9); 544cabdff1aSopenharmony_ci const vec_s32 uvstart = vec_splats((1 << 9) - (128 << 19)); 545cabdff1aSopenharmony_ci const vec_u16 zero16 = vec_splat_u16(0); 546cabdff1aSopenharmony_ci const vec_s32 y_offset = vec_splats(c->yuv2rgb_y_offset); 547cabdff1aSopenharmony_ci const vec_s32 y_coeff = vec_splats(c->yuv2rgb_y_coeff); 548cabdff1aSopenharmony_ci const vec_s32 y_add = vec_splats(1 << 21); 549cabdff1aSopenharmony_ci const vec_s32 v2r_coeff = vec_splats(c->yuv2rgb_v2r_coeff); 550cabdff1aSopenharmony_ci const vec_s32 v2g_coeff = vec_splats(c->yuv2rgb_v2g_coeff); 551cabdff1aSopenharmony_ci const vec_s32 u2g_coeff = vec_splats(c->yuv2rgb_u2g_coeff); 552cabdff1aSopenharmony_ci const vec_s32 u2b_coeff = vec_splats(c->yuv2rgb_u2b_coeff); 553cabdff1aSopenharmony_ci const vec_s32 rgbclip = vec_splats(1 << 30); 554cabdff1aSopenharmony_ci const vec_s32 zero32 = vec_splat_s32(0); 555cabdff1aSopenharmony_ci const vec_u32 shift22 = vec_splats(22U); 556cabdff1aSopenharmony_ci const vec_u32 shift10 = vec_splat_u32(10); 557cabdff1aSopenharmony_ci int i, j; 558cabdff1aSopenharmony_ci 559cabdff1aSopenharmony_ci // Various permutations 560cabdff1aSopenharmony_ci const vec_u8 perm3rg0 = (vec_u8) {0x0, 0x10, 0, 561cabdff1aSopenharmony_ci 0x1, 0x11, 0, 562cabdff1aSopenharmony_ci 0x2, 0x12, 0, 563cabdff1aSopenharmony_ci 0x3, 0x13, 0, 564cabdff1aSopenharmony_ci 0x4, 0x14, 0, 565cabdff1aSopenharmony_ci 0x5 }; 566cabdff1aSopenharmony_ci const vec_u8 perm3rg1 = (vec_u8) { 0x15, 0, 567cabdff1aSopenharmony_ci 0x6, 0x16, 0, 568cabdff1aSopenharmony_ci 0x7, 0x17, 0 }; 569cabdff1aSopenharmony_ci const vec_u8 perm3tb0 = (vec_u8) {0x0, 0x1, 0x10, 570cabdff1aSopenharmony_ci 0x3, 0x4, 0x11, 571cabdff1aSopenharmony_ci 0x6, 0x7, 0x12, 572cabdff1aSopenharmony_ci 0x9, 0xa, 0x13, 573cabdff1aSopenharmony_ci 0xc, 0xd, 0x14, 574cabdff1aSopenharmony_ci 0xf }; 575cabdff1aSopenharmony_ci const vec_u8 perm3tb1 = (vec_u8) { 0x0, 0x15, 576cabdff1aSopenharmony_ci 0x2, 0x3, 0x16, 577cabdff1aSopenharmony_ci 0x5, 0x6, 0x17 }; 578cabdff1aSopenharmony_ci 579cabdff1aSopenharmony_ci ad = vec_splats((uint8_t) 255); 580cabdff1aSopenharmony_ci 581cabdff1aSopenharmony_ci for (i = 0; i < lumFilterSize; i++) 582cabdff1aSopenharmony_ci vlumFilter[i] = vec_splats(lumFilter[i]); 583cabdff1aSopenharmony_ci for (i = 0; i < chrFilterSize; i++) 584cabdff1aSopenharmony_ci vchrFilter[i] = vec_splats(chrFilter[i]); 585cabdff1aSopenharmony_ci 586cabdff1aSopenharmony_ci for (i = 0; i < dstW; i += 8) { 587cabdff1aSopenharmony_ci vy32_l = 588cabdff1aSopenharmony_ci vy32_r = ystart; 589cabdff1aSopenharmony_ci vu32_l = 590cabdff1aSopenharmony_ci vu32_r = 591cabdff1aSopenharmony_ci vv32_l = 592cabdff1aSopenharmony_ci vv32_r = uvstart; 593cabdff1aSopenharmony_ci 594cabdff1aSopenharmony_ci for (j = 0; j < lumFilterSize; j++) { 595cabdff1aSopenharmony_ci vv = vec_ld(0, &lumSrc[j][i]); 596cabdff1aSopenharmony_ci tmp = vec_mule(vv, vlumFilter[j]); 597cabdff1aSopenharmony_ci tmp2 = vec_mulo(vv, vlumFilter[j]); 598cabdff1aSopenharmony_ci tmp3 = vec_mergeh(tmp, tmp2); 599cabdff1aSopenharmony_ci tmp4 = vec_mergel(tmp, tmp2); 600cabdff1aSopenharmony_ci 601cabdff1aSopenharmony_ci vy32_l = vec_adds(vy32_l, tmp3); 602cabdff1aSopenharmony_ci vy32_r = vec_adds(vy32_r, tmp4); 603cabdff1aSopenharmony_ci } 604cabdff1aSopenharmony_ci 605cabdff1aSopenharmony_ci for (j = 0; j < chrFilterSize; j++) { 606cabdff1aSopenharmony_ci vv = vec_ld(0, &chrUSrc[j][i]); 607cabdff1aSopenharmony_ci tmp = vec_mule(vv, vchrFilter[j]); 608cabdff1aSopenharmony_ci tmp2 = vec_mulo(vv, vchrFilter[j]); 609cabdff1aSopenharmony_ci tmp3 = vec_mergeh(tmp, tmp2); 610cabdff1aSopenharmony_ci tmp4 = vec_mergel(tmp, tmp2); 611cabdff1aSopenharmony_ci 612cabdff1aSopenharmony_ci vu32_l = vec_adds(vu32_l, tmp3); 613cabdff1aSopenharmony_ci vu32_r = vec_adds(vu32_r, tmp4); 614cabdff1aSopenharmony_ci 615cabdff1aSopenharmony_ci vv = vec_ld(0, &chrVSrc[j][i]); 616cabdff1aSopenharmony_ci tmp = vec_mule(vv, vchrFilter[j]); 617cabdff1aSopenharmony_ci tmp2 = vec_mulo(vv, vchrFilter[j]); 618cabdff1aSopenharmony_ci tmp3 = vec_mergeh(tmp, tmp2); 619cabdff1aSopenharmony_ci tmp4 = vec_mergel(tmp, tmp2); 620cabdff1aSopenharmony_ci 621cabdff1aSopenharmony_ci vv32_l = vec_adds(vv32_l, tmp3); 622cabdff1aSopenharmony_ci vv32_r = vec_adds(vv32_r, tmp4); 623cabdff1aSopenharmony_ci } 624cabdff1aSopenharmony_ci 625cabdff1aSopenharmony_ci vy32_l = vec_sra(vy32_l, shift10); 626cabdff1aSopenharmony_ci vy32_r = vec_sra(vy32_r, shift10); 627cabdff1aSopenharmony_ci vu32_l = vec_sra(vu32_l, shift10); 628cabdff1aSopenharmony_ci vu32_r = vec_sra(vu32_r, shift10); 629cabdff1aSopenharmony_ci vv32_l = vec_sra(vv32_l, shift10); 630cabdff1aSopenharmony_ci vv32_r = vec_sra(vv32_r, shift10); 631cabdff1aSopenharmony_ci 632cabdff1aSopenharmony_ci vy32_l = vec_sub(vy32_l, y_offset); 633cabdff1aSopenharmony_ci vy32_r = vec_sub(vy32_r, y_offset); 634cabdff1aSopenharmony_ci vy32_l = vec_mul(vy32_l, y_coeff); 635cabdff1aSopenharmony_ci vy32_r = vec_mul(vy32_r, y_coeff); 636cabdff1aSopenharmony_ci vy32_l = vec_add(vy32_l, y_add); 637cabdff1aSopenharmony_ci vy32_r = vec_add(vy32_r, y_add); 638cabdff1aSopenharmony_ci 639cabdff1aSopenharmony_ci R_l = vec_mul(vv32_l, v2r_coeff); 640cabdff1aSopenharmony_ci R_l = vec_add(R_l, vy32_l); 641cabdff1aSopenharmony_ci R_r = vec_mul(vv32_r, v2r_coeff); 642cabdff1aSopenharmony_ci R_r = vec_add(R_r, vy32_r); 643cabdff1aSopenharmony_ci G_l = vec_mul(vv32_l, v2g_coeff); 644cabdff1aSopenharmony_ci tmp32 = vec_mul(vu32_l, u2g_coeff); 645cabdff1aSopenharmony_ci G_l = vec_add(G_l, vy32_l); 646cabdff1aSopenharmony_ci G_l = vec_add(G_l, tmp32); 647cabdff1aSopenharmony_ci G_r = vec_mul(vv32_r, v2g_coeff); 648cabdff1aSopenharmony_ci tmp32 = vec_mul(vu32_r, u2g_coeff); 649cabdff1aSopenharmony_ci G_r = vec_add(G_r, vy32_r); 650cabdff1aSopenharmony_ci G_r = vec_add(G_r, tmp32); 651cabdff1aSopenharmony_ci 652cabdff1aSopenharmony_ci B_l = vec_mul(vu32_l, u2b_coeff); 653cabdff1aSopenharmony_ci B_l = vec_add(B_l, vy32_l); 654cabdff1aSopenharmony_ci B_r = vec_mul(vu32_r, u2b_coeff); 655cabdff1aSopenharmony_ci B_r = vec_add(B_r, vy32_r); 656cabdff1aSopenharmony_ci 657cabdff1aSopenharmony_ci WRITERGB 658cabdff1aSopenharmony_ci } 659cabdff1aSopenharmony_ci} 660cabdff1aSopenharmony_ci 661cabdff1aSopenharmony_ci#define SETUP(x, buf0, alpha1, buf1, alpha) { \ 662cabdff1aSopenharmony_ci x = vec_ld(0, buf0); \ 663cabdff1aSopenharmony_ci tmp = vec_mule(x, alpha1); \ 664cabdff1aSopenharmony_ci tmp2 = vec_mulo(x, alpha1); \ 665cabdff1aSopenharmony_ci tmp3 = vec_mergeh(tmp, tmp2); \ 666cabdff1aSopenharmony_ci tmp4 = vec_mergel(tmp, tmp2); \ 667cabdff1aSopenharmony_ci\ 668cabdff1aSopenharmony_ci x = vec_ld(0, buf1); \ 669cabdff1aSopenharmony_ci tmp = vec_mule(x, alpha); \ 670cabdff1aSopenharmony_ci tmp2 = vec_mulo(x, alpha); \ 671cabdff1aSopenharmony_ci tmp5 = vec_mergeh(tmp, tmp2); \ 672cabdff1aSopenharmony_ci tmp6 = vec_mergel(tmp, tmp2); \ 673cabdff1aSopenharmony_ci\ 674cabdff1aSopenharmony_ci tmp3 = vec_add(tmp3, tmp5); \ 675cabdff1aSopenharmony_ci tmp4 = vec_add(tmp4, tmp6); \ 676cabdff1aSopenharmony_ci} 677cabdff1aSopenharmony_ci 678cabdff1aSopenharmony_ci 679cabdff1aSopenharmony_cistatic av_always_inline void 680cabdff1aSopenharmony_ciyuv2rgb_full_2_vsx_template(SwsContext *c, const int16_t *buf[2], 681cabdff1aSopenharmony_ci const int16_t *ubuf[2], const int16_t *vbuf[2], 682cabdff1aSopenharmony_ci const int16_t *abuf[2], uint8_t *dest, int dstW, 683cabdff1aSopenharmony_ci int yalpha, int uvalpha, int y, 684cabdff1aSopenharmony_ci enum AVPixelFormat target, int hasAlpha) 685cabdff1aSopenharmony_ci{ 686cabdff1aSopenharmony_ci const int16_t *buf0 = buf[0], *buf1 = buf[1], 687cabdff1aSopenharmony_ci *ubuf0 = ubuf[0], *ubuf1 = ubuf[1], 688cabdff1aSopenharmony_ci *vbuf0 = vbuf[0], *vbuf1 = vbuf[1], 689cabdff1aSopenharmony_ci *abuf0 = hasAlpha ? abuf[0] : NULL, 690cabdff1aSopenharmony_ci *abuf1 = hasAlpha ? abuf[1] : NULL; 691cabdff1aSopenharmony_ci const int16_t yalpha1 = 4096 - yalpha; 692cabdff1aSopenharmony_ci const int16_t uvalpha1 = 4096 - uvalpha; 693cabdff1aSopenharmony_ci vec_s16 vy, vu, vv, A = vec_splat_s16(0); 694cabdff1aSopenharmony_ci vec_s32 vy32_l, vy32_r, vu32_l, vu32_r, vv32_l, vv32_r, tmp32; 695cabdff1aSopenharmony_ci vec_s32 R_l, R_r, G_l, G_r, B_l, B_r; 696cabdff1aSopenharmony_ci vec_s32 tmp, tmp2, tmp3, tmp4, tmp5, tmp6; 697cabdff1aSopenharmony_ci vec_u16 rd16, gd16, bd16; 698cabdff1aSopenharmony_ci vec_u8 rd, bd, gd, ad, out0, out1, tmp8; 699cabdff1aSopenharmony_ci const vec_s16 vyalpha1 = vec_splats(yalpha1); 700cabdff1aSopenharmony_ci const vec_s16 vuvalpha1 = vec_splats(uvalpha1); 701cabdff1aSopenharmony_ci const vec_s16 vyalpha = vec_splats((int16_t) yalpha); 702cabdff1aSopenharmony_ci const vec_s16 vuvalpha = vec_splats((int16_t) uvalpha); 703cabdff1aSopenharmony_ci const vec_u16 zero16 = vec_splat_u16(0); 704cabdff1aSopenharmony_ci const vec_s32 y_offset = vec_splats(c->yuv2rgb_y_offset); 705cabdff1aSopenharmony_ci const vec_s32 y_coeff = vec_splats(c->yuv2rgb_y_coeff); 706cabdff1aSopenharmony_ci const vec_s32 y_add = vec_splats(1 << 21); 707cabdff1aSopenharmony_ci const vec_s32 v2r_coeff = vec_splats(c->yuv2rgb_v2r_coeff); 708cabdff1aSopenharmony_ci const vec_s32 v2g_coeff = vec_splats(c->yuv2rgb_v2g_coeff); 709cabdff1aSopenharmony_ci const vec_s32 u2g_coeff = vec_splats(c->yuv2rgb_u2g_coeff); 710cabdff1aSopenharmony_ci const vec_s32 u2b_coeff = vec_splats(c->yuv2rgb_u2b_coeff); 711cabdff1aSopenharmony_ci const vec_s32 rgbclip = vec_splats(1 << 30); 712cabdff1aSopenharmony_ci const vec_s32 zero32 = vec_splat_s32(0); 713cabdff1aSopenharmony_ci const vec_u32 shift19 = vec_splats(19U); 714cabdff1aSopenharmony_ci const vec_u32 shift22 = vec_splats(22U); 715cabdff1aSopenharmony_ci const vec_u32 shift10 = vec_splat_u32(10); 716cabdff1aSopenharmony_ci const vec_s32 dec128 = vec_splats(128 << 19); 717cabdff1aSopenharmony_ci const vec_s32 add18 = vec_splats(1 << 18); 718cabdff1aSopenharmony_ci int i; 719cabdff1aSopenharmony_ci 720cabdff1aSopenharmony_ci // Various permutations 721cabdff1aSopenharmony_ci const vec_u8 perm3rg0 = (vec_u8) {0x0, 0x10, 0, 722cabdff1aSopenharmony_ci 0x1, 0x11, 0, 723cabdff1aSopenharmony_ci 0x2, 0x12, 0, 724cabdff1aSopenharmony_ci 0x3, 0x13, 0, 725cabdff1aSopenharmony_ci 0x4, 0x14, 0, 726cabdff1aSopenharmony_ci 0x5 }; 727cabdff1aSopenharmony_ci const vec_u8 perm3rg1 = (vec_u8) { 0x15, 0, 728cabdff1aSopenharmony_ci 0x6, 0x16, 0, 729cabdff1aSopenharmony_ci 0x7, 0x17, 0 }; 730cabdff1aSopenharmony_ci const vec_u8 perm3tb0 = (vec_u8) {0x0, 0x1, 0x10, 731cabdff1aSopenharmony_ci 0x3, 0x4, 0x11, 732cabdff1aSopenharmony_ci 0x6, 0x7, 0x12, 733cabdff1aSopenharmony_ci 0x9, 0xa, 0x13, 734cabdff1aSopenharmony_ci 0xc, 0xd, 0x14, 735cabdff1aSopenharmony_ci 0xf }; 736cabdff1aSopenharmony_ci const vec_u8 perm3tb1 = (vec_u8) { 0x0, 0x15, 737cabdff1aSopenharmony_ci 0x2, 0x3, 0x16, 738cabdff1aSopenharmony_ci 0x5, 0x6, 0x17 }; 739cabdff1aSopenharmony_ci 740cabdff1aSopenharmony_ci av_assert2(yalpha <= 4096U); 741cabdff1aSopenharmony_ci av_assert2(uvalpha <= 4096U); 742cabdff1aSopenharmony_ci 743cabdff1aSopenharmony_ci for (i = 0; i < dstW; i += 8) { 744cabdff1aSopenharmony_ci SETUP(vy, &buf0[i], vyalpha1, &buf1[i], vyalpha); 745cabdff1aSopenharmony_ci vy32_l = vec_sra(tmp3, shift10); 746cabdff1aSopenharmony_ci vy32_r = vec_sra(tmp4, shift10); 747cabdff1aSopenharmony_ci 748cabdff1aSopenharmony_ci SETUP(vu, &ubuf0[i], vuvalpha1, &ubuf1[i], vuvalpha); 749cabdff1aSopenharmony_ci tmp3 = vec_sub(tmp3, dec128); 750cabdff1aSopenharmony_ci tmp4 = vec_sub(tmp4, dec128); 751cabdff1aSopenharmony_ci vu32_l = vec_sra(tmp3, shift10); 752cabdff1aSopenharmony_ci vu32_r = vec_sra(tmp4, shift10); 753cabdff1aSopenharmony_ci 754cabdff1aSopenharmony_ci SETUP(vv, &vbuf0[i], vuvalpha1, &vbuf1[i], vuvalpha); 755cabdff1aSopenharmony_ci tmp3 = vec_sub(tmp3, dec128); 756cabdff1aSopenharmony_ci tmp4 = vec_sub(tmp4, dec128); 757cabdff1aSopenharmony_ci vv32_l = vec_sra(tmp3, shift10); 758cabdff1aSopenharmony_ci vv32_r = vec_sra(tmp4, shift10); 759cabdff1aSopenharmony_ci 760cabdff1aSopenharmony_ci if (hasAlpha) { 761cabdff1aSopenharmony_ci SETUP(A, &abuf0[i], vyalpha1, &abuf1[i], vyalpha); 762cabdff1aSopenharmony_ci tmp3 = vec_add(tmp3, add18); 763cabdff1aSopenharmony_ci tmp4 = vec_add(tmp4, add18); 764cabdff1aSopenharmony_ci tmp3 = vec_sra(tmp3, shift19); 765cabdff1aSopenharmony_ci tmp4 = vec_sra(tmp4, shift19); 766cabdff1aSopenharmony_ci A = vec_packs(tmp3, tmp4); 767cabdff1aSopenharmony_ci ad = vec_packsu(A, (vec_s16) zero16); 768cabdff1aSopenharmony_ci } else { 769cabdff1aSopenharmony_ci ad = vec_splats((uint8_t) 255); 770cabdff1aSopenharmony_ci } 771cabdff1aSopenharmony_ci 772cabdff1aSopenharmony_ci vy32_l = vec_sub(vy32_l, y_offset); 773cabdff1aSopenharmony_ci vy32_r = vec_sub(vy32_r, y_offset); 774cabdff1aSopenharmony_ci vy32_l = vec_mul(vy32_l, y_coeff); 775cabdff1aSopenharmony_ci vy32_r = vec_mul(vy32_r, y_coeff); 776cabdff1aSopenharmony_ci vy32_l = vec_add(vy32_l, y_add); 777cabdff1aSopenharmony_ci vy32_r = vec_add(vy32_r, y_add); 778cabdff1aSopenharmony_ci 779cabdff1aSopenharmony_ci R_l = vec_mul(vv32_l, v2r_coeff); 780cabdff1aSopenharmony_ci R_l = vec_add(R_l, vy32_l); 781cabdff1aSopenharmony_ci R_r = vec_mul(vv32_r, v2r_coeff); 782cabdff1aSopenharmony_ci R_r = vec_add(R_r, vy32_r); 783cabdff1aSopenharmony_ci G_l = vec_mul(vv32_l, v2g_coeff); 784cabdff1aSopenharmony_ci tmp32 = vec_mul(vu32_l, u2g_coeff); 785cabdff1aSopenharmony_ci G_l = vec_add(G_l, vy32_l); 786cabdff1aSopenharmony_ci G_l = vec_add(G_l, tmp32); 787cabdff1aSopenharmony_ci G_r = vec_mul(vv32_r, v2g_coeff); 788cabdff1aSopenharmony_ci tmp32 = vec_mul(vu32_r, u2g_coeff); 789cabdff1aSopenharmony_ci G_r = vec_add(G_r, vy32_r); 790cabdff1aSopenharmony_ci G_r = vec_add(G_r, tmp32); 791cabdff1aSopenharmony_ci 792cabdff1aSopenharmony_ci B_l = vec_mul(vu32_l, u2b_coeff); 793cabdff1aSopenharmony_ci B_l = vec_add(B_l, vy32_l); 794cabdff1aSopenharmony_ci B_r = vec_mul(vu32_r, u2b_coeff); 795cabdff1aSopenharmony_ci B_r = vec_add(B_r, vy32_r); 796cabdff1aSopenharmony_ci 797cabdff1aSopenharmony_ci WRITERGB 798cabdff1aSopenharmony_ci } 799cabdff1aSopenharmony_ci} 800cabdff1aSopenharmony_ci 801cabdff1aSopenharmony_cistatic av_always_inline void 802cabdff1aSopenharmony_ciyuv2rgb_2_vsx_template(SwsContext *c, const int16_t *buf[2], 803cabdff1aSopenharmony_ci const int16_t *ubuf[2], const int16_t *vbuf[2], 804cabdff1aSopenharmony_ci const int16_t *abuf[2], uint8_t *dest, int dstW, 805cabdff1aSopenharmony_ci int yalpha, int uvalpha, int y, 806cabdff1aSopenharmony_ci enum AVPixelFormat target, int hasAlpha) 807cabdff1aSopenharmony_ci{ 808cabdff1aSopenharmony_ci const int16_t *buf0 = buf[0], *buf1 = buf[1], 809cabdff1aSopenharmony_ci *ubuf0 = ubuf[0], *ubuf1 = ubuf[1], 810cabdff1aSopenharmony_ci *vbuf0 = vbuf[0], *vbuf1 = vbuf[1], 811cabdff1aSopenharmony_ci *abuf0 = hasAlpha ? abuf[0] : NULL, 812cabdff1aSopenharmony_ci *abuf1 = hasAlpha ? abuf[1] : NULL; 813cabdff1aSopenharmony_ci const int16_t yalpha1 = 4096 - yalpha; 814cabdff1aSopenharmony_ci const int16_t uvalpha1 = 4096 - uvalpha; 815cabdff1aSopenharmony_ci vec_s16 vy, vu, vv, A = vec_splat_s16(0); 816cabdff1aSopenharmony_ci vec_s32 vy32_l, vy32_r, vu32_l, vu32_r, vv32_l, vv32_r, tmp32; 817cabdff1aSopenharmony_ci vec_s32 R_l, R_r, G_l, G_r, B_l, B_r, vud32_l, vud32_r, vvd32_l, vvd32_r; 818cabdff1aSopenharmony_ci vec_s32 tmp, tmp2, tmp3, tmp4, tmp5, tmp6; 819cabdff1aSopenharmony_ci vec_u16 rd16, gd16, bd16; 820cabdff1aSopenharmony_ci vec_u8 rd, bd, gd, ad, out0, out1, tmp8; 821cabdff1aSopenharmony_ci const vec_s16 vyalpha1 = vec_splats(yalpha1); 822cabdff1aSopenharmony_ci const vec_s16 vuvalpha1 = vec_splats(uvalpha1); 823cabdff1aSopenharmony_ci const vec_s16 vyalpha = vec_splats((int16_t) yalpha); 824cabdff1aSopenharmony_ci const vec_s16 vuvalpha = vec_splats((int16_t) uvalpha); 825cabdff1aSopenharmony_ci const vec_u16 zero16 = vec_splat_u16(0); 826cabdff1aSopenharmony_ci const vec_s32 y_offset = vec_splats(c->yuv2rgb_y_offset); 827cabdff1aSopenharmony_ci const vec_s32 y_coeff = vec_splats(c->yuv2rgb_y_coeff); 828cabdff1aSopenharmony_ci const vec_s32 y_add = vec_splats(1 << 21); 829cabdff1aSopenharmony_ci const vec_s32 v2r_coeff = vec_splats(c->yuv2rgb_v2r_coeff); 830cabdff1aSopenharmony_ci const vec_s32 v2g_coeff = vec_splats(c->yuv2rgb_v2g_coeff); 831cabdff1aSopenharmony_ci const vec_s32 u2g_coeff = vec_splats(c->yuv2rgb_u2g_coeff); 832cabdff1aSopenharmony_ci const vec_s32 u2b_coeff = vec_splats(c->yuv2rgb_u2b_coeff); 833cabdff1aSopenharmony_ci const vec_s32 rgbclip = vec_splats(1 << 30); 834cabdff1aSopenharmony_ci const vec_s32 zero32 = vec_splat_s32(0); 835cabdff1aSopenharmony_ci const vec_u32 shift19 = vec_splats(19U); 836cabdff1aSopenharmony_ci const vec_u32 shift22 = vec_splats(22U); 837cabdff1aSopenharmony_ci const vec_u32 shift10 = vec_splat_u32(10); 838cabdff1aSopenharmony_ci const vec_s32 dec128 = vec_splats(128 << 19); 839cabdff1aSopenharmony_ci const vec_s32 add18 = vec_splats(1 << 18); 840cabdff1aSopenharmony_ci int i; 841cabdff1aSopenharmony_ci 842cabdff1aSopenharmony_ci // Various permutations 843cabdff1aSopenharmony_ci const vec_u8 doubleleft = (vec_u8) {0, 1, 2, 3, 844cabdff1aSopenharmony_ci 0, 1, 2, 3, 845cabdff1aSopenharmony_ci 4, 5, 6, 7, 846cabdff1aSopenharmony_ci 4, 5, 6, 7 }; 847cabdff1aSopenharmony_ci const vec_u8 doubleright = (vec_u8) {8, 9, 10, 11, 848cabdff1aSopenharmony_ci 8, 9, 10, 11, 849cabdff1aSopenharmony_ci 12, 13, 14, 15, 850cabdff1aSopenharmony_ci 12, 13, 14, 15 }; 851cabdff1aSopenharmony_ci const vec_u8 perm3rg0 = (vec_u8) {0x0, 0x10, 0, 852cabdff1aSopenharmony_ci 0x1, 0x11, 0, 853cabdff1aSopenharmony_ci 0x2, 0x12, 0, 854cabdff1aSopenharmony_ci 0x3, 0x13, 0, 855cabdff1aSopenharmony_ci 0x4, 0x14, 0, 856cabdff1aSopenharmony_ci 0x5 }; 857cabdff1aSopenharmony_ci const vec_u8 perm3rg1 = (vec_u8) { 0x15, 0, 858cabdff1aSopenharmony_ci 0x6, 0x16, 0, 859cabdff1aSopenharmony_ci 0x7, 0x17, 0 }; 860cabdff1aSopenharmony_ci const vec_u8 perm3tb0 = (vec_u8) {0x0, 0x1, 0x10, 861cabdff1aSopenharmony_ci 0x3, 0x4, 0x11, 862cabdff1aSopenharmony_ci 0x6, 0x7, 0x12, 863cabdff1aSopenharmony_ci 0x9, 0xa, 0x13, 864cabdff1aSopenharmony_ci 0xc, 0xd, 0x14, 865cabdff1aSopenharmony_ci 0xf }; 866cabdff1aSopenharmony_ci const vec_u8 perm3tb1 = (vec_u8) { 0x0, 0x15, 867cabdff1aSopenharmony_ci 0x2, 0x3, 0x16, 868cabdff1aSopenharmony_ci 0x5, 0x6, 0x17 }; 869cabdff1aSopenharmony_ci 870cabdff1aSopenharmony_ci av_assert2(yalpha <= 4096U); 871cabdff1aSopenharmony_ci av_assert2(uvalpha <= 4096U); 872cabdff1aSopenharmony_ci 873cabdff1aSopenharmony_ci for (i = 0; i < (dstW + 1) >> 1; i += 8) { 874cabdff1aSopenharmony_ci SETUP(vy, &buf0[i * 2], vyalpha1, &buf1[i * 2], vyalpha); 875cabdff1aSopenharmony_ci vy32_l = vec_sra(tmp3, shift10); 876cabdff1aSopenharmony_ci vy32_r = vec_sra(tmp4, shift10); 877cabdff1aSopenharmony_ci 878cabdff1aSopenharmony_ci SETUP(vu, &ubuf0[i], vuvalpha1, &ubuf1[i], vuvalpha); 879cabdff1aSopenharmony_ci tmp3 = vec_sub(tmp3, dec128); 880cabdff1aSopenharmony_ci tmp4 = vec_sub(tmp4, dec128); 881cabdff1aSopenharmony_ci vu32_l = vec_sra(tmp3, shift10); 882cabdff1aSopenharmony_ci vu32_r = vec_sra(tmp4, shift10); 883cabdff1aSopenharmony_ci 884cabdff1aSopenharmony_ci SETUP(vv, &vbuf0[i], vuvalpha1, &vbuf1[i], vuvalpha); 885cabdff1aSopenharmony_ci tmp3 = vec_sub(tmp3, dec128); 886cabdff1aSopenharmony_ci tmp4 = vec_sub(tmp4, dec128); 887cabdff1aSopenharmony_ci vv32_l = vec_sra(tmp3, shift10); 888cabdff1aSopenharmony_ci vv32_r = vec_sra(tmp4, shift10); 889cabdff1aSopenharmony_ci 890cabdff1aSopenharmony_ci if (hasAlpha) { 891cabdff1aSopenharmony_ci SETUP(A, &abuf0[i], vyalpha1, &abuf1[i], vyalpha); 892cabdff1aSopenharmony_ci tmp3 = vec_add(tmp3, add18); 893cabdff1aSopenharmony_ci tmp4 = vec_add(tmp4, add18); 894cabdff1aSopenharmony_ci tmp3 = vec_sra(tmp3, shift19); 895cabdff1aSopenharmony_ci tmp4 = vec_sra(tmp4, shift19); 896cabdff1aSopenharmony_ci A = vec_packs(tmp3, tmp4); 897cabdff1aSopenharmony_ci ad = vec_packsu(A, (vec_s16) zero16); 898cabdff1aSopenharmony_ci } else { 899cabdff1aSopenharmony_ci ad = vec_splats((uint8_t) 255); 900cabdff1aSopenharmony_ci } 901cabdff1aSopenharmony_ci 902cabdff1aSopenharmony_ci vy32_l = vec_sub(vy32_l, y_offset); 903cabdff1aSopenharmony_ci vy32_r = vec_sub(vy32_r, y_offset); 904cabdff1aSopenharmony_ci vy32_l = vec_mul(vy32_l, y_coeff); 905cabdff1aSopenharmony_ci vy32_r = vec_mul(vy32_r, y_coeff); 906cabdff1aSopenharmony_ci vy32_l = vec_add(vy32_l, y_add); 907cabdff1aSopenharmony_ci vy32_r = vec_add(vy32_r, y_add); 908cabdff1aSopenharmony_ci 909cabdff1aSopenharmony_ci // Use the first UV half 910cabdff1aSopenharmony_ci vud32_l = vec_perm(vu32_l, vu32_l, doubleleft); 911cabdff1aSopenharmony_ci vud32_r = vec_perm(vu32_l, vu32_l, doubleright); 912cabdff1aSopenharmony_ci vvd32_l = vec_perm(vv32_l, vv32_l, doubleleft); 913cabdff1aSopenharmony_ci vvd32_r = vec_perm(vv32_l, vv32_l, doubleright); 914cabdff1aSopenharmony_ci 915cabdff1aSopenharmony_ci R_l = vec_mul(vvd32_l, v2r_coeff); 916cabdff1aSopenharmony_ci R_l = vec_add(R_l, vy32_l); 917cabdff1aSopenharmony_ci R_r = vec_mul(vvd32_r, v2r_coeff); 918cabdff1aSopenharmony_ci R_r = vec_add(R_r, vy32_r); 919cabdff1aSopenharmony_ci G_l = vec_mul(vvd32_l, v2g_coeff); 920cabdff1aSopenharmony_ci tmp32 = vec_mul(vud32_l, u2g_coeff); 921cabdff1aSopenharmony_ci G_l = vec_add(G_l, vy32_l); 922cabdff1aSopenharmony_ci G_l = vec_add(G_l, tmp32); 923cabdff1aSopenharmony_ci G_r = vec_mul(vvd32_r, v2g_coeff); 924cabdff1aSopenharmony_ci tmp32 = vec_mul(vud32_r, u2g_coeff); 925cabdff1aSopenharmony_ci G_r = vec_add(G_r, vy32_r); 926cabdff1aSopenharmony_ci G_r = vec_add(G_r, tmp32); 927cabdff1aSopenharmony_ci 928cabdff1aSopenharmony_ci B_l = vec_mul(vud32_l, u2b_coeff); 929cabdff1aSopenharmony_ci B_l = vec_add(B_l, vy32_l); 930cabdff1aSopenharmony_ci B_r = vec_mul(vud32_r, u2b_coeff); 931cabdff1aSopenharmony_ci B_r = vec_add(B_r, vy32_r); 932cabdff1aSopenharmony_ci 933cabdff1aSopenharmony_ci WRITERGB 934cabdff1aSopenharmony_ci 935cabdff1aSopenharmony_ci // New Y for the second half 936cabdff1aSopenharmony_ci SETUP(vy, &buf0[i * 2 + 8], vyalpha1, &buf1[i * 2 + 8], vyalpha); 937cabdff1aSopenharmony_ci vy32_l = vec_sra(tmp3, shift10); 938cabdff1aSopenharmony_ci vy32_r = vec_sra(tmp4, shift10); 939cabdff1aSopenharmony_ci 940cabdff1aSopenharmony_ci vy32_l = vec_sub(vy32_l, y_offset); 941cabdff1aSopenharmony_ci vy32_r = vec_sub(vy32_r, y_offset); 942cabdff1aSopenharmony_ci vy32_l = vec_mul(vy32_l, y_coeff); 943cabdff1aSopenharmony_ci vy32_r = vec_mul(vy32_r, y_coeff); 944cabdff1aSopenharmony_ci vy32_l = vec_add(vy32_l, y_add); 945cabdff1aSopenharmony_ci vy32_r = vec_add(vy32_r, y_add); 946cabdff1aSopenharmony_ci 947cabdff1aSopenharmony_ci // Second UV half 948cabdff1aSopenharmony_ci vud32_l = vec_perm(vu32_r, vu32_r, doubleleft); 949cabdff1aSopenharmony_ci vud32_r = vec_perm(vu32_r, vu32_r, doubleright); 950cabdff1aSopenharmony_ci vvd32_l = vec_perm(vv32_r, vv32_r, doubleleft); 951cabdff1aSopenharmony_ci vvd32_r = vec_perm(vv32_r, vv32_r, doubleright); 952cabdff1aSopenharmony_ci 953cabdff1aSopenharmony_ci R_l = vec_mul(vvd32_l, v2r_coeff); 954cabdff1aSopenharmony_ci R_l = vec_add(R_l, vy32_l); 955cabdff1aSopenharmony_ci R_r = vec_mul(vvd32_r, v2r_coeff); 956cabdff1aSopenharmony_ci R_r = vec_add(R_r, vy32_r); 957cabdff1aSopenharmony_ci G_l = vec_mul(vvd32_l, v2g_coeff); 958cabdff1aSopenharmony_ci tmp32 = vec_mul(vud32_l, u2g_coeff); 959cabdff1aSopenharmony_ci G_l = vec_add(G_l, vy32_l); 960cabdff1aSopenharmony_ci G_l = vec_add(G_l, tmp32); 961cabdff1aSopenharmony_ci G_r = vec_mul(vvd32_r, v2g_coeff); 962cabdff1aSopenharmony_ci tmp32 = vec_mul(vud32_r, u2g_coeff); 963cabdff1aSopenharmony_ci G_r = vec_add(G_r, vy32_r); 964cabdff1aSopenharmony_ci G_r = vec_add(G_r, tmp32); 965cabdff1aSopenharmony_ci 966cabdff1aSopenharmony_ci B_l = vec_mul(vud32_l, u2b_coeff); 967cabdff1aSopenharmony_ci B_l = vec_add(B_l, vy32_l); 968cabdff1aSopenharmony_ci B_r = vec_mul(vud32_r, u2b_coeff); 969cabdff1aSopenharmony_ci B_r = vec_add(B_r, vy32_r); 970cabdff1aSopenharmony_ci 971cabdff1aSopenharmony_ci WRITERGB 972cabdff1aSopenharmony_ci } 973cabdff1aSopenharmony_ci} 974cabdff1aSopenharmony_ci 975cabdff1aSopenharmony_ci#undef SETUP 976cabdff1aSopenharmony_ci 977cabdff1aSopenharmony_cistatic av_always_inline void 978cabdff1aSopenharmony_ciyuv2rgb_full_1_vsx_template(SwsContext *c, const int16_t *buf0, 979cabdff1aSopenharmony_ci const int16_t *ubuf[2], const int16_t *vbuf[2], 980cabdff1aSopenharmony_ci const int16_t *abuf0, uint8_t *dest, int dstW, 981cabdff1aSopenharmony_ci int uvalpha, int y, enum AVPixelFormat target, 982cabdff1aSopenharmony_ci int hasAlpha) 983cabdff1aSopenharmony_ci{ 984cabdff1aSopenharmony_ci const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0]; 985cabdff1aSopenharmony_ci const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1]; 986cabdff1aSopenharmony_ci vec_s16 vy, vu, vv, A = vec_splat_s16(0), tmp16; 987cabdff1aSopenharmony_ci vec_s32 vy32_l, vy32_r, vu32_l, vu32_r, vv32_l, vv32_r, tmp32, tmp32_2; 988cabdff1aSopenharmony_ci vec_s32 R_l, R_r, G_l, G_r, B_l, B_r; 989cabdff1aSopenharmony_ci vec_u16 rd16, gd16, bd16; 990cabdff1aSopenharmony_ci vec_u8 rd, bd, gd, ad, out0, out1, tmp8; 991cabdff1aSopenharmony_ci const vec_u16 zero16 = vec_splat_u16(0); 992cabdff1aSopenharmony_ci const vec_s32 y_offset = vec_splats(c->yuv2rgb_y_offset); 993cabdff1aSopenharmony_ci const vec_s32 y_coeff = vec_splats(c->yuv2rgb_y_coeff); 994cabdff1aSopenharmony_ci const vec_s32 y_add = vec_splats(1 << 21); 995cabdff1aSopenharmony_ci const vec_s32 v2r_coeff = vec_splats(c->yuv2rgb_v2r_coeff); 996cabdff1aSopenharmony_ci const vec_s32 v2g_coeff = vec_splats(c->yuv2rgb_v2g_coeff); 997cabdff1aSopenharmony_ci const vec_s32 u2g_coeff = vec_splats(c->yuv2rgb_u2g_coeff); 998cabdff1aSopenharmony_ci const vec_s32 u2b_coeff = vec_splats(c->yuv2rgb_u2b_coeff); 999cabdff1aSopenharmony_ci const vec_s32 rgbclip = vec_splats(1 << 30); 1000cabdff1aSopenharmony_ci const vec_s32 zero32 = vec_splat_s32(0); 1001cabdff1aSopenharmony_ci const vec_u32 shift2 = vec_splat_u32(2); 1002cabdff1aSopenharmony_ci const vec_u32 shift22 = vec_splats(22U); 1003cabdff1aSopenharmony_ci const vec_u16 sub7 = vec_splats((uint16_t) (128 << 7)); 1004cabdff1aSopenharmony_ci const vec_u16 sub8 = vec_splats((uint16_t) (128 << 8)); 1005cabdff1aSopenharmony_ci const vec_s16 mul4 = vec_splat_s16(4); 1006cabdff1aSopenharmony_ci const vec_s16 mul8 = vec_splat_s16(8); 1007cabdff1aSopenharmony_ci const vec_s16 add64 = vec_splat_s16(64); 1008cabdff1aSopenharmony_ci const vec_u16 shift7 = vec_splat_u16(7); 1009cabdff1aSopenharmony_ci const vec_s16 max255 = vec_splat_s16(255); 1010cabdff1aSopenharmony_ci int i; 1011cabdff1aSopenharmony_ci 1012cabdff1aSopenharmony_ci // Various permutations 1013cabdff1aSopenharmony_ci const vec_u8 perm3rg0 = (vec_u8) {0x0, 0x10, 0, 1014cabdff1aSopenharmony_ci 0x1, 0x11, 0, 1015cabdff1aSopenharmony_ci 0x2, 0x12, 0, 1016cabdff1aSopenharmony_ci 0x3, 0x13, 0, 1017cabdff1aSopenharmony_ci 0x4, 0x14, 0, 1018cabdff1aSopenharmony_ci 0x5 }; 1019cabdff1aSopenharmony_ci const vec_u8 perm3rg1 = (vec_u8) { 0x15, 0, 1020cabdff1aSopenharmony_ci 0x6, 0x16, 0, 1021cabdff1aSopenharmony_ci 0x7, 0x17, 0 }; 1022cabdff1aSopenharmony_ci const vec_u8 perm3tb0 = (vec_u8) {0x0, 0x1, 0x10, 1023cabdff1aSopenharmony_ci 0x3, 0x4, 0x11, 1024cabdff1aSopenharmony_ci 0x6, 0x7, 0x12, 1025cabdff1aSopenharmony_ci 0x9, 0xa, 0x13, 1026cabdff1aSopenharmony_ci 0xc, 0xd, 0x14, 1027cabdff1aSopenharmony_ci 0xf }; 1028cabdff1aSopenharmony_ci const vec_u8 perm3tb1 = (vec_u8) { 0x0, 0x15, 1029cabdff1aSopenharmony_ci 0x2, 0x3, 0x16, 1030cabdff1aSopenharmony_ci 0x5, 0x6, 0x17 }; 1031cabdff1aSopenharmony_ci 1032cabdff1aSopenharmony_ci for (i = 0; i < dstW; i += 8) { // The x86 asm also overwrites padding bytes. 1033cabdff1aSopenharmony_ci vy = vec_ld(0, &buf0[i]); 1034cabdff1aSopenharmony_ci vy32_l = vec_unpackh(vy); 1035cabdff1aSopenharmony_ci vy32_r = vec_unpackl(vy); 1036cabdff1aSopenharmony_ci vy32_l = vec_sl(vy32_l, shift2); 1037cabdff1aSopenharmony_ci vy32_r = vec_sl(vy32_r, shift2); 1038cabdff1aSopenharmony_ci 1039cabdff1aSopenharmony_ci vu = vec_ld(0, &ubuf0[i]); 1040cabdff1aSopenharmony_ci vv = vec_ld(0, &vbuf0[i]); 1041cabdff1aSopenharmony_ci if (uvalpha < 2048) { 1042cabdff1aSopenharmony_ci vu = (vec_s16) vec_sub((vec_u16) vu, sub7); 1043cabdff1aSopenharmony_ci vv = (vec_s16) vec_sub((vec_u16) vv, sub7); 1044cabdff1aSopenharmony_ci 1045cabdff1aSopenharmony_ci tmp32 = vec_mule(vu, mul4); 1046cabdff1aSopenharmony_ci tmp32_2 = vec_mulo(vu, mul4); 1047cabdff1aSopenharmony_ci vu32_l = vec_mergeh(tmp32, tmp32_2); 1048cabdff1aSopenharmony_ci vu32_r = vec_mergel(tmp32, tmp32_2); 1049cabdff1aSopenharmony_ci tmp32 = vec_mule(vv, mul4); 1050cabdff1aSopenharmony_ci tmp32_2 = vec_mulo(vv, mul4); 1051cabdff1aSopenharmony_ci vv32_l = vec_mergeh(tmp32, tmp32_2); 1052cabdff1aSopenharmony_ci vv32_r = vec_mergel(tmp32, tmp32_2); 1053cabdff1aSopenharmony_ci } else { 1054cabdff1aSopenharmony_ci tmp16 = vec_ld(0, &ubuf1[i]); 1055cabdff1aSopenharmony_ci vu = vec_add(vu, tmp16); 1056cabdff1aSopenharmony_ci vu = (vec_s16) vec_sub((vec_u16) vu, sub8); 1057cabdff1aSopenharmony_ci tmp16 = vec_ld(0, &vbuf1[i]); 1058cabdff1aSopenharmony_ci vv = vec_add(vv, tmp16); 1059cabdff1aSopenharmony_ci vv = (vec_s16) vec_sub((vec_u16) vv, sub8); 1060cabdff1aSopenharmony_ci 1061cabdff1aSopenharmony_ci vu32_l = vec_mule(vu, mul8); 1062cabdff1aSopenharmony_ci vu32_r = vec_mulo(vu, mul8); 1063cabdff1aSopenharmony_ci vv32_l = vec_mule(vv, mul8); 1064cabdff1aSopenharmony_ci vv32_r = vec_mulo(vv, mul8); 1065cabdff1aSopenharmony_ci } 1066cabdff1aSopenharmony_ci 1067cabdff1aSopenharmony_ci if (hasAlpha) { 1068cabdff1aSopenharmony_ci A = vec_ld(0, &abuf0[i]); 1069cabdff1aSopenharmony_ci A = vec_add(A, add64); 1070cabdff1aSopenharmony_ci A = vec_sr(A, shift7); 1071cabdff1aSopenharmony_ci A = vec_max(A, max255); 1072cabdff1aSopenharmony_ci ad = vec_packsu(A, (vec_s16) zero16); 1073cabdff1aSopenharmony_ci } else { 1074cabdff1aSopenharmony_ci ad = vec_splats((uint8_t) 255); 1075cabdff1aSopenharmony_ci } 1076cabdff1aSopenharmony_ci 1077cabdff1aSopenharmony_ci vy32_l = vec_sub(vy32_l, y_offset); 1078cabdff1aSopenharmony_ci vy32_r = vec_sub(vy32_r, y_offset); 1079cabdff1aSopenharmony_ci vy32_l = vec_mul(vy32_l, y_coeff); 1080cabdff1aSopenharmony_ci vy32_r = vec_mul(vy32_r, y_coeff); 1081cabdff1aSopenharmony_ci vy32_l = vec_add(vy32_l, y_add); 1082cabdff1aSopenharmony_ci vy32_r = vec_add(vy32_r, y_add); 1083cabdff1aSopenharmony_ci 1084cabdff1aSopenharmony_ci R_l = vec_mul(vv32_l, v2r_coeff); 1085cabdff1aSopenharmony_ci R_l = vec_add(R_l, vy32_l); 1086cabdff1aSopenharmony_ci R_r = vec_mul(vv32_r, v2r_coeff); 1087cabdff1aSopenharmony_ci R_r = vec_add(R_r, vy32_r); 1088cabdff1aSopenharmony_ci G_l = vec_mul(vv32_l, v2g_coeff); 1089cabdff1aSopenharmony_ci tmp32 = vec_mul(vu32_l, u2g_coeff); 1090cabdff1aSopenharmony_ci G_l = vec_add(G_l, vy32_l); 1091cabdff1aSopenharmony_ci G_l = vec_add(G_l, tmp32); 1092cabdff1aSopenharmony_ci G_r = vec_mul(vv32_r, v2g_coeff); 1093cabdff1aSopenharmony_ci tmp32 = vec_mul(vu32_r, u2g_coeff); 1094cabdff1aSopenharmony_ci G_r = vec_add(G_r, vy32_r); 1095cabdff1aSopenharmony_ci G_r = vec_add(G_r, tmp32); 1096cabdff1aSopenharmony_ci 1097cabdff1aSopenharmony_ci B_l = vec_mul(vu32_l, u2b_coeff); 1098cabdff1aSopenharmony_ci B_l = vec_add(B_l, vy32_l); 1099cabdff1aSopenharmony_ci B_r = vec_mul(vu32_r, u2b_coeff); 1100cabdff1aSopenharmony_ci B_r = vec_add(B_r, vy32_r); 1101cabdff1aSopenharmony_ci 1102cabdff1aSopenharmony_ci WRITERGB 1103cabdff1aSopenharmony_ci } 1104cabdff1aSopenharmony_ci} 1105cabdff1aSopenharmony_ci 1106cabdff1aSopenharmony_cistatic av_always_inline void 1107cabdff1aSopenharmony_ciyuv2rgb_1_vsx_template(SwsContext *c, const int16_t *buf0, 1108cabdff1aSopenharmony_ci const int16_t *ubuf[2], const int16_t *vbuf[2], 1109cabdff1aSopenharmony_ci const int16_t *abuf0, uint8_t *dest, int dstW, 1110cabdff1aSopenharmony_ci int uvalpha, int y, enum AVPixelFormat target, 1111cabdff1aSopenharmony_ci int hasAlpha) 1112cabdff1aSopenharmony_ci{ 1113cabdff1aSopenharmony_ci const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0]; 1114cabdff1aSopenharmony_ci const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1]; 1115cabdff1aSopenharmony_ci vec_s16 vy, vu, vv, A = vec_splat_s16(0), tmp16; 1116cabdff1aSopenharmony_ci vec_s32 vy32_l, vy32_r, vu32_l, vu32_r, vv32_l, vv32_r, tmp32, tmp32_2; 1117cabdff1aSopenharmony_ci vec_s32 vud32_l, vud32_r, vvd32_l, vvd32_r; 1118cabdff1aSopenharmony_ci vec_s32 R_l, R_r, G_l, G_r, B_l, B_r; 1119cabdff1aSopenharmony_ci vec_u16 rd16, gd16, bd16; 1120cabdff1aSopenharmony_ci vec_u8 rd, bd, gd, ad, out0, out1, tmp8; 1121cabdff1aSopenharmony_ci const vec_u16 zero16 = vec_splat_u16(0); 1122cabdff1aSopenharmony_ci const vec_s32 y_offset = vec_splats(c->yuv2rgb_y_offset); 1123cabdff1aSopenharmony_ci const vec_s32 y_coeff = vec_splats(c->yuv2rgb_y_coeff); 1124cabdff1aSopenharmony_ci const vec_s32 y_add = vec_splats(1 << 21); 1125cabdff1aSopenharmony_ci const vec_s32 v2r_coeff = vec_splats(c->yuv2rgb_v2r_coeff); 1126cabdff1aSopenharmony_ci const vec_s32 v2g_coeff = vec_splats(c->yuv2rgb_v2g_coeff); 1127cabdff1aSopenharmony_ci const vec_s32 u2g_coeff = vec_splats(c->yuv2rgb_u2g_coeff); 1128cabdff1aSopenharmony_ci const vec_s32 u2b_coeff = vec_splats(c->yuv2rgb_u2b_coeff); 1129cabdff1aSopenharmony_ci const vec_s32 rgbclip = vec_splats(1 << 30); 1130cabdff1aSopenharmony_ci const vec_s32 zero32 = vec_splat_s32(0); 1131cabdff1aSopenharmony_ci const vec_u32 shift2 = vec_splat_u32(2); 1132cabdff1aSopenharmony_ci const vec_u32 shift22 = vec_splats(22U); 1133cabdff1aSopenharmony_ci const vec_u16 sub7 = vec_splats((uint16_t) (128 << 7)); 1134cabdff1aSopenharmony_ci const vec_u16 sub8 = vec_splats((uint16_t) (128 << 8)); 1135cabdff1aSopenharmony_ci const vec_s16 mul4 = vec_splat_s16(4); 1136cabdff1aSopenharmony_ci const vec_s16 mul8 = vec_splat_s16(8); 1137cabdff1aSopenharmony_ci const vec_s16 add64 = vec_splat_s16(64); 1138cabdff1aSopenharmony_ci const vec_u16 shift7 = vec_splat_u16(7); 1139cabdff1aSopenharmony_ci const vec_s16 max255 = vec_splat_s16(255); 1140cabdff1aSopenharmony_ci int i; 1141cabdff1aSopenharmony_ci 1142cabdff1aSopenharmony_ci // Various permutations 1143cabdff1aSopenharmony_ci const vec_u8 doubleleft = (vec_u8) {0, 1, 2, 3, 1144cabdff1aSopenharmony_ci 0, 1, 2, 3, 1145cabdff1aSopenharmony_ci 4, 5, 6, 7, 1146cabdff1aSopenharmony_ci 4, 5, 6, 7 }; 1147cabdff1aSopenharmony_ci const vec_u8 doubleright = (vec_u8) {8, 9, 10, 11, 1148cabdff1aSopenharmony_ci 8, 9, 10, 11, 1149cabdff1aSopenharmony_ci 12, 13, 14, 15, 1150cabdff1aSopenharmony_ci 12, 13, 14, 15 }; 1151cabdff1aSopenharmony_ci const vec_u8 perm3rg0 = (vec_u8) {0x0, 0x10, 0, 1152cabdff1aSopenharmony_ci 0x1, 0x11, 0, 1153cabdff1aSopenharmony_ci 0x2, 0x12, 0, 1154cabdff1aSopenharmony_ci 0x3, 0x13, 0, 1155cabdff1aSopenharmony_ci 0x4, 0x14, 0, 1156cabdff1aSopenharmony_ci 0x5 }; 1157cabdff1aSopenharmony_ci const vec_u8 perm3rg1 = (vec_u8) { 0x15, 0, 1158cabdff1aSopenharmony_ci 0x6, 0x16, 0, 1159cabdff1aSopenharmony_ci 0x7, 0x17, 0 }; 1160cabdff1aSopenharmony_ci const vec_u8 perm3tb0 = (vec_u8) {0x0, 0x1, 0x10, 1161cabdff1aSopenharmony_ci 0x3, 0x4, 0x11, 1162cabdff1aSopenharmony_ci 0x6, 0x7, 0x12, 1163cabdff1aSopenharmony_ci 0x9, 0xa, 0x13, 1164cabdff1aSopenharmony_ci 0xc, 0xd, 0x14, 1165cabdff1aSopenharmony_ci 0xf }; 1166cabdff1aSopenharmony_ci const vec_u8 perm3tb1 = (vec_u8) { 0x0, 0x15, 1167cabdff1aSopenharmony_ci 0x2, 0x3, 0x16, 1168cabdff1aSopenharmony_ci 0x5, 0x6, 0x17 }; 1169cabdff1aSopenharmony_ci 1170cabdff1aSopenharmony_ci for (i = 0; i < (dstW + 1) >> 1; i += 8) { // The x86 asm also overwrites padding bytes. 1171cabdff1aSopenharmony_ci vy = vec_ld(0, &buf0[i * 2]); 1172cabdff1aSopenharmony_ci vy32_l = vec_unpackh(vy); 1173cabdff1aSopenharmony_ci vy32_r = vec_unpackl(vy); 1174cabdff1aSopenharmony_ci vy32_l = vec_sl(vy32_l, shift2); 1175cabdff1aSopenharmony_ci vy32_r = vec_sl(vy32_r, shift2); 1176cabdff1aSopenharmony_ci 1177cabdff1aSopenharmony_ci vu = vec_ld(0, &ubuf0[i]); 1178cabdff1aSopenharmony_ci vv = vec_ld(0, &vbuf0[i]); 1179cabdff1aSopenharmony_ci if (uvalpha < 2048) { 1180cabdff1aSopenharmony_ci vu = (vec_s16) vec_sub((vec_u16) vu, sub7); 1181cabdff1aSopenharmony_ci vv = (vec_s16) vec_sub((vec_u16) vv, sub7); 1182cabdff1aSopenharmony_ci 1183cabdff1aSopenharmony_ci tmp32 = vec_mule(vu, mul4); 1184cabdff1aSopenharmony_ci tmp32_2 = vec_mulo(vu, mul4); 1185cabdff1aSopenharmony_ci vu32_l = vec_mergeh(tmp32, tmp32_2); 1186cabdff1aSopenharmony_ci vu32_r = vec_mergel(tmp32, tmp32_2); 1187cabdff1aSopenharmony_ci tmp32 = vec_mule(vv, mul4); 1188cabdff1aSopenharmony_ci tmp32_2 = vec_mulo(vv, mul4); 1189cabdff1aSopenharmony_ci vv32_l = vec_mergeh(tmp32, tmp32_2); 1190cabdff1aSopenharmony_ci vv32_r = vec_mergel(tmp32, tmp32_2); 1191cabdff1aSopenharmony_ci } else { 1192cabdff1aSopenharmony_ci tmp16 = vec_ld(0, &ubuf1[i]); 1193cabdff1aSopenharmony_ci vu = vec_add(vu, tmp16); 1194cabdff1aSopenharmony_ci vu = (vec_s16) vec_sub((vec_u16) vu, sub8); 1195cabdff1aSopenharmony_ci tmp16 = vec_ld(0, &vbuf1[i]); 1196cabdff1aSopenharmony_ci vv = vec_add(vv, tmp16); 1197cabdff1aSopenharmony_ci vv = (vec_s16) vec_sub((vec_u16) vv, sub8); 1198cabdff1aSopenharmony_ci 1199cabdff1aSopenharmony_ci vu32_l = vec_mule(vu, mul8); 1200cabdff1aSopenharmony_ci vu32_r = vec_mulo(vu, mul8); 1201cabdff1aSopenharmony_ci vv32_l = vec_mule(vv, mul8); 1202cabdff1aSopenharmony_ci vv32_r = vec_mulo(vv, mul8); 1203cabdff1aSopenharmony_ci } 1204cabdff1aSopenharmony_ci 1205cabdff1aSopenharmony_ci if (hasAlpha) { 1206cabdff1aSopenharmony_ci A = vec_ld(0, &abuf0[i]); 1207cabdff1aSopenharmony_ci A = vec_add(A, add64); 1208cabdff1aSopenharmony_ci A = vec_sr(A, shift7); 1209cabdff1aSopenharmony_ci A = vec_max(A, max255); 1210cabdff1aSopenharmony_ci ad = vec_packsu(A, (vec_s16) zero16); 1211cabdff1aSopenharmony_ci } else { 1212cabdff1aSopenharmony_ci ad = vec_splats((uint8_t) 255); 1213cabdff1aSopenharmony_ci } 1214cabdff1aSopenharmony_ci 1215cabdff1aSopenharmony_ci vy32_l = vec_sub(vy32_l, y_offset); 1216cabdff1aSopenharmony_ci vy32_r = vec_sub(vy32_r, y_offset); 1217cabdff1aSopenharmony_ci vy32_l = vec_mul(vy32_l, y_coeff); 1218cabdff1aSopenharmony_ci vy32_r = vec_mul(vy32_r, y_coeff); 1219cabdff1aSopenharmony_ci vy32_l = vec_add(vy32_l, y_add); 1220cabdff1aSopenharmony_ci vy32_r = vec_add(vy32_r, y_add); 1221cabdff1aSopenharmony_ci 1222cabdff1aSopenharmony_ci // Use the first UV half 1223cabdff1aSopenharmony_ci vud32_l = vec_perm(vu32_l, vu32_l, doubleleft); 1224cabdff1aSopenharmony_ci vud32_r = vec_perm(vu32_l, vu32_l, doubleright); 1225cabdff1aSopenharmony_ci vvd32_l = vec_perm(vv32_l, vv32_l, doubleleft); 1226cabdff1aSopenharmony_ci vvd32_r = vec_perm(vv32_l, vv32_l, doubleright); 1227cabdff1aSopenharmony_ci 1228cabdff1aSopenharmony_ci R_l = vec_mul(vvd32_l, v2r_coeff); 1229cabdff1aSopenharmony_ci R_l = vec_add(R_l, vy32_l); 1230cabdff1aSopenharmony_ci R_r = vec_mul(vvd32_r, v2r_coeff); 1231cabdff1aSopenharmony_ci R_r = vec_add(R_r, vy32_r); 1232cabdff1aSopenharmony_ci G_l = vec_mul(vvd32_l, v2g_coeff); 1233cabdff1aSopenharmony_ci tmp32 = vec_mul(vud32_l, u2g_coeff); 1234cabdff1aSopenharmony_ci G_l = vec_add(G_l, vy32_l); 1235cabdff1aSopenharmony_ci G_l = vec_add(G_l, tmp32); 1236cabdff1aSopenharmony_ci G_r = vec_mul(vvd32_r, v2g_coeff); 1237cabdff1aSopenharmony_ci tmp32 = vec_mul(vud32_r, u2g_coeff); 1238cabdff1aSopenharmony_ci G_r = vec_add(G_r, vy32_r); 1239cabdff1aSopenharmony_ci G_r = vec_add(G_r, tmp32); 1240cabdff1aSopenharmony_ci 1241cabdff1aSopenharmony_ci B_l = vec_mul(vud32_l, u2b_coeff); 1242cabdff1aSopenharmony_ci B_l = vec_add(B_l, vy32_l); 1243cabdff1aSopenharmony_ci B_r = vec_mul(vud32_r, u2b_coeff); 1244cabdff1aSopenharmony_ci B_r = vec_add(B_r, vy32_r); 1245cabdff1aSopenharmony_ci 1246cabdff1aSopenharmony_ci WRITERGB 1247cabdff1aSopenharmony_ci 1248cabdff1aSopenharmony_ci // New Y for the second half 1249cabdff1aSopenharmony_ci vy = vec_ld(16, &buf0[i * 2]); 1250cabdff1aSopenharmony_ci vy32_l = vec_unpackh(vy); 1251cabdff1aSopenharmony_ci vy32_r = vec_unpackl(vy); 1252cabdff1aSopenharmony_ci vy32_l = vec_sl(vy32_l, shift2); 1253cabdff1aSopenharmony_ci vy32_r = vec_sl(vy32_r, shift2); 1254cabdff1aSopenharmony_ci 1255cabdff1aSopenharmony_ci vy32_l = vec_sub(vy32_l, y_offset); 1256cabdff1aSopenharmony_ci vy32_r = vec_sub(vy32_r, y_offset); 1257cabdff1aSopenharmony_ci vy32_l = vec_mul(vy32_l, y_coeff); 1258cabdff1aSopenharmony_ci vy32_r = vec_mul(vy32_r, y_coeff); 1259cabdff1aSopenharmony_ci vy32_l = vec_add(vy32_l, y_add); 1260cabdff1aSopenharmony_ci vy32_r = vec_add(vy32_r, y_add); 1261cabdff1aSopenharmony_ci 1262cabdff1aSopenharmony_ci // Second UV half 1263cabdff1aSopenharmony_ci vud32_l = vec_perm(vu32_r, vu32_r, doubleleft); 1264cabdff1aSopenharmony_ci vud32_r = vec_perm(vu32_r, vu32_r, doubleright); 1265cabdff1aSopenharmony_ci vvd32_l = vec_perm(vv32_r, vv32_r, doubleleft); 1266cabdff1aSopenharmony_ci vvd32_r = vec_perm(vv32_r, vv32_r, doubleright); 1267cabdff1aSopenharmony_ci 1268cabdff1aSopenharmony_ci R_l = vec_mul(vvd32_l, v2r_coeff); 1269cabdff1aSopenharmony_ci R_l = vec_add(R_l, vy32_l); 1270cabdff1aSopenharmony_ci R_r = vec_mul(vvd32_r, v2r_coeff); 1271cabdff1aSopenharmony_ci R_r = vec_add(R_r, vy32_r); 1272cabdff1aSopenharmony_ci G_l = vec_mul(vvd32_l, v2g_coeff); 1273cabdff1aSopenharmony_ci tmp32 = vec_mul(vud32_l, u2g_coeff); 1274cabdff1aSopenharmony_ci G_l = vec_add(G_l, vy32_l); 1275cabdff1aSopenharmony_ci G_l = vec_add(G_l, tmp32); 1276cabdff1aSopenharmony_ci G_r = vec_mul(vvd32_r, v2g_coeff); 1277cabdff1aSopenharmony_ci tmp32 = vec_mul(vud32_r, u2g_coeff); 1278cabdff1aSopenharmony_ci G_r = vec_add(G_r, vy32_r); 1279cabdff1aSopenharmony_ci G_r = vec_add(G_r, tmp32); 1280cabdff1aSopenharmony_ci 1281cabdff1aSopenharmony_ci B_l = vec_mul(vud32_l, u2b_coeff); 1282cabdff1aSopenharmony_ci B_l = vec_add(B_l, vy32_l); 1283cabdff1aSopenharmony_ci B_r = vec_mul(vud32_r, u2b_coeff); 1284cabdff1aSopenharmony_ci B_r = vec_add(B_r, vy32_r); 1285cabdff1aSopenharmony_ci 1286cabdff1aSopenharmony_ci WRITERGB 1287cabdff1aSopenharmony_ci } 1288cabdff1aSopenharmony_ci} 1289cabdff1aSopenharmony_ci 1290cabdff1aSopenharmony_ci#undef WRITERGB 1291cabdff1aSopenharmony_ci 1292cabdff1aSopenharmony_ci#define YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \ 1293cabdff1aSopenharmony_cistatic void name ## ext ## _X_vsx(SwsContext *c, const int16_t *lumFilter, \ 1294cabdff1aSopenharmony_ci const int16_t **lumSrc, int lumFilterSize, \ 1295cabdff1aSopenharmony_ci const int16_t *chrFilter, const int16_t **chrUSrc, \ 1296cabdff1aSopenharmony_ci const int16_t **chrVSrc, int chrFilterSize, \ 1297cabdff1aSopenharmony_ci const int16_t **alpSrc, uint8_t *dest, int dstW, \ 1298cabdff1aSopenharmony_ci int y) \ 1299cabdff1aSopenharmony_ci{ \ 1300cabdff1aSopenharmony_ci name ## base ## _X_vsx_template(c, lumFilter, lumSrc, lumFilterSize, \ 1301cabdff1aSopenharmony_ci chrFilter, chrUSrc, chrVSrc, chrFilterSize, \ 1302cabdff1aSopenharmony_ci alpSrc, dest, dstW, y, fmt, hasAlpha); \ 1303cabdff1aSopenharmony_ci} 1304cabdff1aSopenharmony_ci 1305cabdff1aSopenharmony_ci#define YUV2RGBWRAPPERX2(name, base, ext, fmt, hasAlpha) \ 1306cabdff1aSopenharmony_cistatic void name ## ext ## _2_vsx(SwsContext *c, const int16_t *buf[2], \ 1307cabdff1aSopenharmony_ci const int16_t *ubuf[2], const int16_t *vbuf[2], \ 1308cabdff1aSopenharmony_ci const int16_t *abuf[2], uint8_t *dest, int dstW, \ 1309cabdff1aSopenharmony_ci int yalpha, int uvalpha, int y) \ 1310cabdff1aSopenharmony_ci{ \ 1311cabdff1aSopenharmony_ci name ## base ## _2_vsx_template(c, buf, ubuf, vbuf, abuf, \ 1312cabdff1aSopenharmony_ci dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha); \ 1313cabdff1aSopenharmony_ci} 1314cabdff1aSopenharmony_ci 1315cabdff1aSopenharmony_ci#define YUV2RGBWRAPPER(name, base, ext, fmt, hasAlpha) \ 1316cabdff1aSopenharmony_cistatic void name ## ext ## _1_vsx(SwsContext *c, const int16_t *buf0, \ 1317cabdff1aSopenharmony_ci const int16_t *ubuf[2], const int16_t *vbuf[2], \ 1318cabdff1aSopenharmony_ci const int16_t *abuf0, uint8_t *dest, int dstW, \ 1319cabdff1aSopenharmony_ci int uvalpha, int y) \ 1320cabdff1aSopenharmony_ci{ \ 1321cabdff1aSopenharmony_ci name ## base ## _1_vsx_template(c, buf0, ubuf, vbuf, abuf0, dest, \ 1322cabdff1aSopenharmony_ci dstW, uvalpha, y, fmt, hasAlpha); \ 1323cabdff1aSopenharmony_ci} 1324cabdff1aSopenharmony_ci 1325cabdff1aSopenharmony_ciYUV2RGBWRAPPER(yuv2, rgb, bgrx32, AV_PIX_FMT_BGRA, 0) 1326cabdff1aSopenharmony_ciYUV2RGBWRAPPER(yuv2, rgb, rgbx32, AV_PIX_FMT_RGBA, 0) 1327cabdff1aSopenharmony_ciYUV2RGBWRAPPER(yuv2, rgb, xrgb32, AV_PIX_FMT_ARGB, 0) 1328cabdff1aSopenharmony_ciYUV2RGBWRAPPER(yuv2, rgb, xbgr32, AV_PIX_FMT_ABGR, 0) 1329cabdff1aSopenharmony_ci 1330cabdff1aSopenharmony_ciYUV2RGBWRAPPER(yuv2, rgb, rgb24, AV_PIX_FMT_RGB24, 0) 1331cabdff1aSopenharmony_ciYUV2RGBWRAPPER(yuv2, rgb, bgr24, AV_PIX_FMT_BGR24, 0) 1332cabdff1aSopenharmony_ci 1333cabdff1aSopenharmony_ciYUV2RGBWRAPPERX2(yuv2, rgb, bgrx32, AV_PIX_FMT_BGRA, 0) 1334cabdff1aSopenharmony_ciYUV2RGBWRAPPERX2(yuv2, rgb, rgbx32, AV_PIX_FMT_RGBA, 0) 1335cabdff1aSopenharmony_ciYUV2RGBWRAPPERX2(yuv2, rgb, xrgb32, AV_PIX_FMT_ARGB, 0) 1336cabdff1aSopenharmony_ciYUV2RGBWRAPPERX2(yuv2, rgb, xbgr32, AV_PIX_FMT_ABGR, 0) 1337cabdff1aSopenharmony_ci 1338cabdff1aSopenharmony_ciYUV2RGBWRAPPERX2(yuv2, rgb, rgb24, AV_PIX_FMT_RGB24, 0) 1339cabdff1aSopenharmony_ciYUV2RGBWRAPPERX2(yuv2, rgb, bgr24, AV_PIX_FMT_BGR24, 0) 1340cabdff1aSopenharmony_ci 1341cabdff1aSopenharmony_ciYUV2RGBWRAPPER(yuv2, rgb_full, bgrx32_full, AV_PIX_FMT_BGRA, 0) 1342cabdff1aSopenharmony_ciYUV2RGBWRAPPER(yuv2, rgb_full, rgbx32_full, AV_PIX_FMT_RGBA, 0) 1343cabdff1aSopenharmony_ciYUV2RGBWRAPPER(yuv2, rgb_full, xrgb32_full, AV_PIX_FMT_ARGB, 0) 1344cabdff1aSopenharmony_ciYUV2RGBWRAPPER(yuv2, rgb_full, xbgr32_full, AV_PIX_FMT_ABGR, 0) 1345cabdff1aSopenharmony_ci 1346cabdff1aSopenharmony_ciYUV2RGBWRAPPER(yuv2, rgb_full, rgb24_full, AV_PIX_FMT_RGB24, 0) 1347cabdff1aSopenharmony_ciYUV2RGBWRAPPER(yuv2, rgb_full, bgr24_full, AV_PIX_FMT_BGR24, 0) 1348cabdff1aSopenharmony_ci 1349cabdff1aSopenharmony_ciYUV2RGBWRAPPERX2(yuv2, rgb_full, bgrx32_full, AV_PIX_FMT_BGRA, 0) 1350cabdff1aSopenharmony_ciYUV2RGBWRAPPERX2(yuv2, rgb_full, rgbx32_full, AV_PIX_FMT_RGBA, 0) 1351cabdff1aSopenharmony_ciYUV2RGBWRAPPERX2(yuv2, rgb_full, xrgb32_full, AV_PIX_FMT_ARGB, 0) 1352cabdff1aSopenharmony_ciYUV2RGBWRAPPERX2(yuv2, rgb_full, xbgr32_full, AV_PIX_FMT_ABGR, 0) 1353cabdff1aSopenharmony_ci 1354cabdff1aSopenharmony_ciYUV2RGBWRAPPERX2(yuv2, rgb_full, rgb24_full, AV_PIX_FMT_RGB24, 0) 1355cabdff1aSopenharmony_ciYUV2RGBWRAPPERX2(yuv2, rgb_full, bgr24_full, AV_PIX_FMT_BGR24, 0) 1356cabdff1aSopenharmony_ci 1357cabdff1aSopenharmony_ciYUV2RGBWRAPPERX(yuv2, rgb_full, bgrx32_full, AV_PIX_FMT_BGRA, 0) 1358cabdff1aSopenharmony_ciYUV2RGBWRAPPERX(yuv2, rgb_full, rgbx32_full, AV_PIX_FMT_RGBA, 0) 1359cabdff1aSopenharmony_ciYUV2RGBWRAPPERX(yuv2, rgb_full, xrgb32_full, AV_PIX_FMT_ARGB, 0) 1360cabdff1aSopenharmony_ciYUV2RGBWRAPPERX(yuv2, rgb_full, xbgr32_full, AV_PIX_FMT_ABGR, 0) 1361cabdff1aSopenharmony_ci 1362cabdff1aSopenharmony_ciYUV2RGBWRAPPERX(yuv2, rgb_full, rgb24_full, AV_PIX_FMT_RGB24, 0) 1363cabdff1aSopenharmony_ciYUV2RGBWRAPPERX(yuv2, rgb_full, bgr24_full, AV_PIX_FMT_BGR24, 0) 1364cabdff1aSopenharmony_ci 1365cabdff1aSopenharmony_cistatic av_always_inline void 1366cabdff1aSopenharmony_ciwrite422(const vec_s16 vy1, const vec_s16 vy2, 1367cabdff1aSopenharmony_ci const vec_s16 vu, const vec_s16 vv, 1368cabdff1aSopenharmony_ci uint8_t *dest, const enum AVPixelFormat target) 1369cabdff1aSopenharmony_ci{ 1370cabdff1aSopenharmony_ci vec_u8 vd1, vd2, tmp; 1371cabdff1aSopenharmony_ci const vec_u8 yuyv1 = (vec_u8) { 1372cabdff1aSopenharmony_ci 0x0, 0x10, 0x1, 0x18, 1373cabdff1aSopenharmony_ci 0x2, 0x11, 0x3, 0x19, 1374cabdff1aSopenharmony_ci 0x4, 0x12, 0x5, 0x1a, 1375cabdff1aSopenharmony_ci 0x6, 0x13, 0x7, 0x1b }; 1376cabdff1aSopenharmony_ci const vec_u8 yuyv2 = (vec_u8) { 1377cabdff1aSopenharmony_ci 0x8, 0x14, 0x9, 0x1c, 1378cabdff1aSopenharmony_ci 0xa, 0x15, 0xb, 0x1d, 1379cabdff1aSopenharmony_ci 0xc, 0x16, 0xd, 0x1e, 1380cabdff1aSopenharmony_ci 0xe, 0x17, 0xf, 0x1f }; 1381cabdff1aSopenharmony_ci const vec_u8 yvyu1 = (vec_u8) { 1382cabdff1aSopenharmony_ci 0x0, 0x18, 0x1, 0x10, 1383cabdff1aSopenharmony_ci 0x2, 0x19, 0x3, 0x11, 1384cabdff1aSopenharmony_ci 0x4, 0x1a, 0x5, 0x12, 1385cabdff1aSopenharmony_ci 0x6, 0x1b, 0x7, 0x13 }; 1386cabdff1aSopenharmony_ci const vec_u8 yvyu2 = (vec_u8) { 1387cabdff1aSopenharmony_ci 0x8, 0x1c, 0x9, 0x14, 1388cabdff1aSopenharmony_ci 0xa, 0x1d, 0xb, 0x15, 1389cabdff1aSopenharmony_ci 0xc, 0x1e, 0xd, 0x16, 1390cabdff1aSopenharmony_ci 0xe, 0x1f, 0xf, 0x17 }; 1391cabdff1aSopenharmony_ci const vec_u8 uyvy1 = (vec_u8) { 1392cabdff1aSopenharmony_ci 0x10, 0x0, 0x18, 0x1, 1393cabdff1aSopenharmony_ci 0x11, 0x2, 0x19, 0x3, 1394cabdff1aSopenharmony_ci 0x12, 0x4, 0x1a, 0x5, 1395cabdff1aSopenharmony_ci 0x13, 0x6, 0x1b, 0x7 }; 1396cabdff1aSopenharmony_ci const vec_u8 uyvy2 = (vec_u8) { 1397cabdff1aSopenharmony_ci 0x14, 0x8, 0x1c, 0x9, 1398cabdff1aSopenharmony_ci 0x15, 0xa, 0x1d, 0xb, 1399cabdff1aSopenharmony_ci 0x16, 0xc, 0x1e, 0xd, 1400cabdff1aSopenharmony_ci 0x17, 0xe, 0x1f, 0xf }; 1401cabdff1aSopenharmony_ci 1402cabdff1aSopenharmony_ci vd1 = vec_packsu(vy1, vy2); 1403cabdff1aSopenharmony_ci vd2 = vec_packsu(vu, vv); 1404cabdff1aSopenharmony_ci 1405cabdff1aSopenharmony_ci switch (target) { 1406cabdff1aSopenharmony_ci case AV_PIX_FMT_YUYV422: 1407cabdff1aSopenharmony_ci tmp = vec_perm(vd1, vd2, yuyv1); 1408cabdff1aSopenharmony_ci vec_st(tmp, 0, dest); 1409cabdff1aSopenharmony_ci tmp = vec_perm(vd1, vd2, yuyv2); 1410cabdff1aSopenharmony_ci vec_st(tmp, 16, dest); 1411cabdff1aSopenharmony_ci break; 1412cabdff1aSopenharmony_ci case AV_PIX_FMT_YVYU422: 1413cabdff1aSopenharmony_ci tmp = vec_perm(vd1, vd2, yvyu1); 1414cabdff1aSopenharmony_ci vec_st(tmp, 0, dest); 1415cabdff1aSopenharmony_ci tmp = vec_perm(vd1, vd2, yvyu2); 1416cabdff1aSopenharmony_ci vec_st(tmp, 16, dest); 1417cabdff1aSopenharmony_ci break; 1418cabdff1aSopenharmony_ci case AV_PIX_FMT_UYVY422: 1419cabdff1aSopenharmony_ci tmp = vec_perm(vd1, vd2, uyvy1); 1420cabdff1aSopenharmony_ci vec_st(tmp, 0, dest); 1421cabdff1aSopenharmony_ci tmp = vec_perm(vd1, vd2, uyvy2); 1422cabdff1aSopenharmony_ci vec_st(tmp, 16, dest); 1423cabdff1aSopenharmony_ci break; 1424cabdff1aSopenharmony_ci } 1425cabdff1aSopenharmony_ci} 1426cabdff1aSopenharmony_ci 1427cabdff1aSopenharmony_cistatic av_always_inline void 1428cabdff1aSopenharmony_ciyuv2422_X_vsx_template(SwsContext *c, const int16_t *lumFilter, 1429cabdff1aSopenharmony_ci const int16_t **lumSrc, int lumFilterSize, 1430cabdff1aSopenharmony_ci const int16_t *chrFilter, const int16_t **chrUSrc, 1431cabdff1aSopenharmony_ci const int16_t **chrVSrc, int chrFilterSize, 1432cabdff1aSopenharmony_ci const int16_t **alpSrc, uint8_t *dest, int dstW, 1433cabdff1aSopenharmony_ci int y, enum AVPixelFormat target) 1434cabdff1aSopenharmony_ci{ 1435cabdff1aSopenharmony_ci int i, j; 1436cabdff1aSopenharmony_ci vec_s16 vy1, vy2, vu, vv; 1437cabdff1aSopenharmony_ci vec_s32 vy32[4], vu32[2], vv32[2], tmp, tmp2, tmp3, tmp4; 1438cabdff1aSopenharmony_ci vec_s16 vlumFilter[MAX_FILTER_SIZE], vchrFilter[MAX_FILTER_SIZE]; 1439cabdff1aSopenharmony_ci const vec_s32 start = vec_splats(1 << 18); 1440cabdff1aSopenharmony_ci const vec_u32 shift19 = vec_splats(19U); 1441cabdff1aSopenharmony_ci 1442cabdff1aSopenharmony_ci for (i = 0; i < lumFilterSize; i++) 1443cabdff1aSopenharmony_ci vlumFilter[i] = vec_splats(lumFilter[i]); 1444cabdff1aSopenharmony_ci for (i = 0; i < chrFilterSize; i++) 1445cabdff1aSopenharmony_ci vchrFilter[i] = vec_splats(chrFilter[i]); 1446cabdff1aSopenharmony_ci 1447cabdff1aSopenharmony_ci for (i = 0; i < ((dstW + 1) >> 1); i += 8) { 1448cabdff1aSopenharmony_ci vy32[0] = 1449cabdff1aSopenharmony_ci vy32[1] = 1450cabdff1aSopenharmony_ci vy32[2] = 1451cabdff1aSopenharmony_ci vy32[3] = 1452cabdff1aSopenharmony_ci vu32[0] = 1453cabdff1aSopenharmony_ci vu32[1] = 1454cabdff1aSopenharmony_ci vv32[0] = 1455cabdff1aSopenharmony_ci vv32[1] = start; 1456cabdff1aSopenharmony_ci 1457cabdff1aSopenharmony_ci for (j = 0; j < lumFilterSize; j++) { 1458cabdff1aSopenharmony_ci vv = vec_ld(0, &lumSrc[j][i * 2]); 1459cabdff1aSopenharmony_ci tmp = vec_mule(vv, vlumFilter[j]); 1460cabdff1aSopenharmony_ci tmp2 = vec_mulo(vv, vlumFilter[j]); 1461cabdff1aSopenharmony_ci tmp3 = vec_mergeh(tmp, tmp2); 1462cabdff1aSopenharmony_ci tmp4 = vec_mergel(tmp, tmp2); 1463cabdff1aSopenharmony_ci 1464cabdff1aSopenharmony_ci vy32[0] = vec_adds(vy32[0], tmp3); 1465cabdff1aSopenharmony_ci vy32[1] = vec_adds(vy32[1], tmp4); 1466cabdff1aSopenharmony_ci 1467cabdff1aSopenharmony_ci vv = vec_ld(0, &lumSrc[j][(i + 4) * 2]); 1468cabdff1aSopenharmony_ci tmp = vec_mule(vv, vlumFilter[j]); 1469cabdff1aSopenharmony_ci tmp2 = vec_mulo(vv, vlumFilter[j]); 1470cabdff1aSopenharmony_ci tmp3 = vec_mergeh(tmp, tmp2); 1471cabdff1aSopenharmony_ci tmp4 = vec_mergel(tmp, tmp2); 1472cabdff1aSopenharmony_ci 1473cabdff1aSopenharmony_ci vy32[2] = vec_adds(vy32[2], tmp3); 1474cabdff1aSopenharmony_ci vy32[3] = vec_adds(vy32[3], tmp4); 1475cabdff1aSopenharmony_ci } 1476cabdff1aSopenharmony_ci 1477cabdff1aSopenharmony_ci for (j = 0; j < chrFilterSize; j++) { 1478cabdff1aSopenharmony_ci vv = vec_ld(0, &chrUSrc[j][i]); 1479cabdff1aSopenharmony_ci tmp = vec_mule(vv, vchrFilter[j]); 1480cabdff1aSopenharmony_ci tmp2 = vec_mulo(vv, vchrFilter[j]); 1481cabdff1aSopenharmony_ci tmp3 = vec_mergeh(tmp, tmp2); 1482cabdff1aSopenharmony_ci tmp4 = vec_mergel(tmp, tmp2); 1483cabdff1aSopenharmony_ci 1484cabdff1aSopenharmony_ci vu32[0] = vec_adds(vu32[0], tmp3); 1485cabdff1aSopenharmony_ci vu32[1] = vec_adds(vu32[1], tmp4); 1486cabdff1aSopenharmony_ci 1487cabdff1aSopenharmony_ci vv = vec_ld(0, &chrVSrc[j][i]); 1488cabdff1aSopenharmony_ci tmp = vec_mule(vv, vchrFilter[j]); 1489cabdff1aSopenharmony_ci tmp2 = vec_mulo(vv, vchrFilter[j]); 1490cabdff1aSopenharmony_ci tmp3 = vec_mergeh(tmp, tmp2); 1491cabdff1aSopenharmony_ci tmp4 = vec_mergel(tmp, tmp2); 1492cabdff1aSopenharmony_ci 1493cabdff1aSopenharmony_ci vv32[0] = vec_adds(vv32[0], tmp3); 1494cabdff1aSopenharmony_ci vv32[1] = vec_adds(vv32[1], tmp4); 1495cabdff1aSopenharmony_ci } 1496cabdff1aSopenharmony_ci 1497cabdff1aSopenharmony_ci for (j = 0; j < 4; j++) { 1498cabdff1aSopenharmony_ci vy32[j] = vec_sra(vy32[j], shift19); 1499cabdff1aSopenharmony_ci } 1500cabdff1aSopenharmony_ci for (j = 0; j < 2; j++) { 1501cabdff1aSopenharmony_ci vu32[j] = vec_sra(vu32[j], shift19); 1502cabdff1aSopenharmony_ci vv32[j] = vec_sra(vv32[j], shift19); 1503cabdff1aSopenharmony_ci } 1504cabdff1aSopenharmony_ci 1505cabdff1aSopenharmony_ci vy1 = vec_packs(vy32[0], vy32[1]); 1506cabdff1aSopenharmony_ci vy2 = vec_packs(vy32[2], vy32[3]); 1507cabdff1aSopenharmony_ci vu = vec_packs(vu32[0], vu32[1]); 1508cabdff1aSopenharmony_ci vv = vec_packs(vv32[0], vv32[1]); 1509cabdff1aSopenharmony_ci 1510cabdff1aSopenharmony_ci write422(vy1, vy2, vu, vv, &dest[i * 4], target); 1511cabdff1aSopenharmony_ci } 1512cabdff1aSopenharmony_ci} 1513cabdff1aSopenharmony_ci 1514cabdff1aSopenharmony_ci#define SETUP(x, buf0, buf1, alpha) { \ 1515cabdff1aSopenharmony_ci x = vec_ld(0, buf0); \ 1516cabdff1aSopenharmony_ci tmp = vec_mule(x, alpha); \ 1517cabdff1aSopenharmony_ci tmp2 = vec_mulo(x, alpha); \ 1518cabdff1aSopenharmony_ci tmp3 = vec_mergeh(tmp, tmp2); \ 1519cabdff1aSopenharmony_ci tmp4 = vec_mergel(tmp, tmp2); \ 1520cabdff1aSopenharmony_ci\ 1521cabdff1aSopenharmony_ci x = vec_ld(0, buf1); \ 1522cabdff1aSopenharmony_ci tmp = vec_mule(x, alpha); \ 1523cabdff1aSopenharmony_ci tmp2 = vec_mulo(x, alpha); \ 1524cabdff1aSopenharmony_ci tmp5 = vec_mergeh(tmp, tmp2); \ 1525cabdff1aSopenharmony_ci tmp6 = vec_mergel(tmp, tmp2); \ 1526cabdff1aSopenharmony_ci\ 1527cabdff1aSopenharmony_ci tmp3 = vec_add(tmp3, tmp5); \ 1528cabdff1aSopenharmony_ci tmp4 = vec_add(tmp4, tmp6); \ 1529cabdff1aSopenharmony_ci\ 1530cabdff1aSopenharmony_ci tmp3 = vec_sra(tmp3, shift19); \ 1531cabdff1aSopenharmony_ci tmp4 = vec_sra(tmp4, shift19); \ 1532cabdff1aSopenharmony_ci x = vec_packs(tmp3, tmp4); \ 1533cabdff1aSopenharmony_ci} 1534cabdff1aSopenharmony_ci 1535cabdff1aSopenharmony_cistatic av_always_inline void 1536cabdff1aSopenharmony_ciyuv2422_2_vsx_template(SwsContext *c, const int16_t *buf[2], 1537cabdff1aSopenharmony_ci const int16_t *ubuf[2], const int16_t *vbuf[2], 1538cabdff1aSopenharmony_ci const int16_t *abuf[2], uint8_t *dest, int dstW, 1539cabdff1aSopenharmony_ci int yalpha, int uvalpha, int y, 1540cabdff1aSopenharmony_ci enum AVPixelFormat target) 1541cabdff1aSopenharmony_ci{ 1542cabdff1aSopenharmony_ci const int16_t *buf0 = buf[0], *buf1 = buf[1], 1543cabdff1aSopenharmony_ci *ubuf0 = ubuf[0], *ubuf1 = ubuf[1], 1544cabdff1aSopenharmony_ci *vbuf0 = vbuf[0], *vbuf1 = vbuf[1]; 1545cabdff1aSopenharmony_ci const int16_t yalpha1 = 4096 - yalpha; 1546cabdff1aSopenharmony_ci const int16_t uvalpha1 = 4096 - uvalpha; 1547cabdff1aSopenharmony_ci vec_s16 vy1, vy2, vu, vv; 1548cabdff1aSopenharmony_ci vec_s32 tmp, tmp2, tmp3, tmp4, tmp5, tmp6; 1549cabdff1aSopenharmony_ci const vec_s16 vyalpha1 = vec_splats(yalpha1); 1550cabdff1aSopenharmony_ci const vec_s16 vuvalpha1 = vec_splats(uvalpha1); 1551cabdff1aSopenharmony_ci const vec_u32 shift19 = vec_splats(19U); 1552cabdff1aSopenharmony_ci int i; 1553cabdff1aSopenharmony_ci av_assert2(yalpha <= 4096U); 1554cabdff1aSopenharmony_ci av_assert2(uvalpha <= 4096U); 1555cabdff1aSopenharmony_ci 1556cabdff1aSopenharmony_ci for (i = 0; i < ((dstW + 1) >> 1); i += 8) { 1557cabdff1aSopenharmony_ci 1558cabdff1aSopenharmony_ci SETUP(vy1, &buf0[i * 2], &buf1[i * 2], vyalpha1) 1559cabdff1aSopenharmony_ci SETUP(vy2, &buf0[(i + 4) * 2], &buf1[(i + 4) * 2], vyalpha1) 1560cabdff1aSopenharmony_ci SETUP(vu, &ubuf0[i], &ubuf1[i], vuvalpha1) 1561cabdff1aSopenharmony_ci SETUP(vv, &vbuf0[i], &vbuf1[i], vuvalpha1) 1562cabdff1aSopenharmony_ci 1563cabdff1aSopenharmony_ci write422(vy1, vy2, vu, vv, &dest[i * 4], target); 1564cabdff1aSopenharmony_ci } 1565cabdff1aSopenharmony_ci} 1566cabdff1aSopenharmony_ci 1567cabdff1aSopenharmony_ci#undef SETUP 1568cabdff1aSopenharmony_ci 1569cabdff1aSopenharmony_cistatic av_always_inline void 1570cabdff1aSopenharmony_ciyuv2422_1_vsx_template(SwsContext *c, const int16_t *buf0, 1571cabdff1aSopenharmony_ci const int16_t *ubuf[2], const int16_t *vbuf[2], 1572cabdff1aSopenharmony_ci const int16_t *abuf0, uint8_t *dest, int dstW, 1573cabdff1aSopenharmony_ci int uvalpha, int y, enum AVPixelFormat target) 1574cabdff1aSopenharmony_ci{ 1575cabdff1aSopenharmony_ci const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0]; 1576cabdff1aSopenharmony_ci vec_s16 vy1, vy2, vu, vv, tmp; 1577cabdff1aSopenharmony_ci const vec_s16 add64 = vec_splats((int16_t) 64); 1578cabdff1aSopenharmony_ci const vec_s16 add128 = vec_splats((int16_t) 128); 1579cabdff1aSopenharmony_ci const vec_u16 shift7 = vec_splat_u16(7); 1580cabdff1aSopenharmony_ci const vec_u16 shift8 = vec_splat_u16(8); 1581cabdff1aSopenharmony_ci int i; 1582cabdff1aSopenharmony_ci 1583cabdff1aSopenharmony_ci if (uvalpha < 2048) { 1584cabdff1aSopenharmony_ci for (i = 0; i < ((dstW + 1) >> 1); i += 8) { 1585cabdff1aSopenharmony_ci vy1 = vec_ld(0, &buf0[i * 2]); 1586cabdff1aSopenharmony_ci vy2 = vec_ld(0, &buf0[(i + 4) * 2]); 1587cabdff1aSopenharmony_ci vu = vec_ld(0, &ubuf0[i]); 1588cabdff1aSopenharmony_ci vv = vec_ld(0, &vbuf0[i]); 1589cabdff1aSopenharmony_ci 1590cabdff1aSopenharmony_ci vy1 = vec_add(vy1, add64); 1591cabdff1aSopenharmony_ci vy2 = vec_add(vy2, add64); 1592cabdff1aSopenharmony_ci vu = vec_add(vu, add64); 1593cabdff1aSopenharmony_ci vv = vec_add(vv, add64); 1594cabdff1aSopenharmony_ci 1595cabdff1aSopenharmony_ci vy1 = vec_sra(vy1, shift7); 1596cabdff1aSopenharmony_ci vy2 = vec_sra(vy2, shift7); 1597cabdff1aSopenharmony_ci vu = vec_sra(vu, shift7); 1598cabdff1aSopenharmony_ci vv = vec_sra(vv, shift7); 1599cabdff1aSopenharmony_ci 1600cabdff1aSopenharmony_ci write422(vy1, vy2, vu, vv, &dest[i * 4], target); 1601cabdff1aSopenharmony_ci } 1602cabdff1aSopenharmony_ci } else { 1603cabdff1aSopenharmony_ci const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1]; 1604cabdff1aSopenharmony_ci for (i = 0; i < ((dstW + 1) >> 1); i += 8) { 1605cabdff1aSopenharmony_ci vy1 = vec_ld(0, &buf0[i * 2]); 1606cabdff1aSopenharmony_ci vy2 = vec_ld(0, &buf0[(i + 4) * 2]); 1607cabdff1aSopenharmony_ci vu = vec_ld(0, &ubuf0[i]); 1608cabdff1aSopenharmony_ci tmp = vec_ld(0, &ubuf1[i]); 1609cabdff1aSopenharmony_ci vu = vec_adds(vu, tmp); 1610cabdff1aSopenharmony_ci vv = vec_ld(0, &vbuf0[i]); 1611cabdff1aSopenharmony_ci tmp = vec_ld(0, &vbuf1[i]); 1612cabdff1aSopenharmony_ci vv = vec_adds(vv, tmp); 1613cabdff1aSopenharmony_ci 1614cabdff1aSopenharmony_ci vy1 = vec_add(vy1, add64); 1615cabdff1aSopenharmony_ci vy2 = vec_add(vy2, add64); 1616cabdff1aSopenharmony_ci vu = vec_adds(vu, add128); 1617cabdff1aSopenharmony_ci vv = vec_adds(vv, add128); 1618cabdff1aSopenharmony_ci 1619cabdff1aSopenharmony_ci vy1 = vec_sra(vy1, shift7); 1620cabdff1aSopenharmony_ci vy2 = vec_sra(vy2, shift7); 1621cabdff1aSopenharmony_ci vu = vec_sra(vu, shift8); 1622cabdff1aSopenharmony_ci vv = vec_sra(vv, shift8); 1623cabdff1aSopenharmony_ci 1624cabdff1aSopenharmony_ci write422(vy1, vy2, vu, vv, &dest[i * 4], target); 1625cabdff1aSopenharmony_ci } 1626cabdff1aSopenharmony_ci } 1627cabdff1aSopenharmony_ci} 1628cabdff1aSopenharmony_ci 1629cabdff1aSopenharmony_ci#define YUV2PACKEDWRAPPERX(name, base, ext, fmt) \ 1630cabdff1aSopenharmony_cistatic void name ## ext ## _X_vsx(SwsContext *c, const int16_t *lumFilter, \ 1631cabdff1aSopenharmony_ci const int16_t **lumSrc, int lumFilterSize, \ 1632cabdff1aSopenharmony_ci const int16_t *chrFilter, const int16_t **chrUSrc, \ 1633cabdff1aSopenharmony_ci const int16_t **chrVSrc, int chrFilterSize, \ 1634cabdff1aSopenharmony_ci const int16_t **alpSrc, uint8_t *dest, int dstW, \ 1635cabdff1aSopenharmony_ci int y) \ 1636cabdff1aSopenharmony_ci{ \ 1637cabdff1aSopenharmony_ci name ## base ## _X_vsx_template(c, lumFilter, lumSrc, lumFilterSize, \ 1638cabdff1aSopenharmony_ci chrFilter, chrUSrc, chrVSrc, chrFilterSize, \ 1639cabdff1aSopenharmony_ci alpSrc, dest, dstW, y, fmt); \ 1640cabdff1aSopenharmony_ci} 1641cabdff1aSopenharmony_ci 1642cabdff1aSopenharmony_ci#define YUV2PACKEDWRAPPER2(name, base, ext, fmt) \ 1643cabdff1aSopenharmony_ciYUV2PACKEDWRAPPERX(name, base, ext, fmt) \ 1644cabdff1aSopenharmony_cistatic void name ## ext ## _2_vsx(SwsContext *c, const int16_t *buf[2], \ 1645cabdff1aSopenharmony_ci const int16_t *ubuf[2], const int16_t *vbuf[2], \ 1646cabdff1aSopenharmony_ci const int16_t *abuf[2], uint8_t *dest, int dstW, \ 1647cabdff1aSopenharmony_ci int yalpha, int uvalpha, int y) \ 1648cabdff1aSopenharmony_ci{ \ 1649cabdff1aSopenharmony_ci name ## base ## _2_vsx_template(c, buf, ubuf, vbuf, abuf, \ 1650cabdff1aSopenharmony_ci dest, dstW, yalpha, uvalpha, y, fmt); \ 1651cabdff1aSopenharmony_ci} 1652cabdff1aSopenharmony_ci 1653cabdff1aSopenharmony_ci#define YUV2PACKEDWRAPPER(name, base, ext, fmt) \ 1654cabdff1aSopenharmony_ciYUV2PACKEDWRAPPER2(name, base, ext, fmt) \ 1655cabdff1aSopenharmony_cistatic void name ## ext ## _1_vsx(SwsContext *c, const int16_t *buf0, \ 1656cabdff1aSopenharmony_ci const int16_t *ubuf[2], const int16_t *vbuf[2], \ 1657cabdff1aSopenharmony_ci const int16_t *abuf0, uint8_t *dest, int dstW, \ 1658cabdff1aSopenharmony_ci int uvalpha, int y) \ 1659cabdff1aSopenharmony_ci{ \ 1660cabdff1aSopenharmony_ci name ## base ## _1_vsx_template(c, buf0, ubuf, vbuf, \ 1661cabdff1aSopenharmony_ci abuf0, dest, dstW, uvalpha, \ 1662cabdff1aSopenharmony_ci y, fmt); \ 1663cabdff1aSopenharmony_ci} 1664cabdff1aSopenharmony_ci 1665cabdff1aSopenharmony_ciYUV2PACKEDWRAPPER(yuv2, 422, yuyv422, AV_PIX_FMT_YUYV422) 1666cabdff1aSopenharmony_ciYUV2PACKEDWRAPPER(yuv2, 422, yvyu422, AV_PIX_FMT_YVYU422) 1667cabdff1aSopenharmony_ciYUV2PACKEDWRAPPER(yuv2, 422, uyvy422, AV_PIX_FMT_UYVY422) 1668cabdff1aSopenharmony_ci 1669cabdff1aSopenharmony_cistatic void hyscale_fast_vsx(SwsContext *c, int16_t *dst, int dstWidth, 1670cabdff1aSopenharmony_ci const uint8_t *src, int srcW, int xInc) 1671cabdff1aSopenharmony_ci{ 1672cabdff1aSopenharmony_ci int i; 1673cabdff1aSopenharmony_ci unsigned int xpos = 0, xx; 1674cabdff1aSopenharmony_ci vec_u8 vin, vin2, vperm; 1675cabdff1aSopenharmony_ci vec_s8 vmul, valpha; 1676cabdff1aSopenharmony_ci vec_s16 vtmp, vtmp2, vtmp3, vtmp4; 1677cabdff1aSopenharmony_ci vec_u16 vd_l, vd_r, vcoord16[2]; 1678cabdff1aSopenharmony_ci vec_u32 vcoord[4]; 1679cabdff1aSopenharmony_ci const vec_u32 vadd = (vec_u32) { 1680cabdff1aSopenharmony_ci 0, 1681cabdff1aSopenharmony_ci xInc * 1, 1682cabdff1aSopenharmony_ci xInc * 2, 1683cabdff1aSopenharmony_ci xInc * 3, 1684cabdff1aSopenharmony_ci }; 1685cabdff1aSopenharmony_ci const vec_u16 vadd16 = (vec_u16) { // Modulo math 1686cabdff1aSopenharmony_ci 0, 1687cabdff1aSopenharmony_ci xInc * 1, 1688cabdff1aSopenharmony_ci xInc * 2, 1689cabdff1aSopenharmony_ci xInc * 3, 1690cabdff1aSopenharmony_ci xInc * 4, 1691cabdff1aSopenharmony_ci xInc * 5, 1692cabdff1aSopenharmony_ci xInc * 6, 1693cabdff1aSopenharmony_ci xInc * 7, 1694cabdff1aSopenharmony_ci }; 1695cabdff1aSopenharmony_ci const vec_u32 vshift16 = vec_splats((uint32_t) 16); 1696cabdff1aSopenharmony_ci const vec_u16 vshift9 = vec_splat_u16(9); 1697cabdff1aSopenharmony_ci const vec_u8 vzero = vec_splat_u8(0); 1698cabdff1aSopenharmony_ci const vec_u16 vshift = vec_splat_u16(7); 1699cabdff1aSopenharmony_ci 1700cabdff1aSopenharmony_ci for (i = 0; i < dstWidth; i += 16) { 1701cabdff1aSopenharmony_ci vcoord16[0] = vec_splats((uint16_t) xpos); 1702cabdff1aSopenharmony_ci vcoord16[1] = vec_splats((uint16_t) (xpos + xInc * 8)); 1703cabdff1aSopenharmony_ci 1704cabdff1aSopenharmony_ci vcoord16[0] = vec_add(vcoord16[0], vadd16); 1705cabdff1aSopenharmony_ci vcoord16[1] = vec_add(vcoord16[1], vadd16); 1706cabdff1aSopenharmony_ci 1707cabdff1aSopenharmony_ci vcoord16[0] = vec_sr(vcoord16[0], vshift9); 1708cabdff1aSopenharmony_ci vcoord16[1] = vec_sr(vcoord16[1], vshift9); 1709cabdff1aSopenharmony_ci valpha = (vec_s8) vec_pack(vcoord16[0], vcoord16[1]); 1710cabdff1aSopenharmony_ci 1711cabdff1aSopenharmony_ci xx = xpos >> 16; 1712cabdff1aSopenharmony_ci vin = vec_vsx_ld(0, &src[xx]); 1713cabdff1aSopenharmony_ci 1714cabdff1aSopenharmony_ci vcoord[0] = vec_splats(xpos & 0xffff); 1715cabdff1aSopenharmony_ci vcoord[1] = vec_splats((xpos & 0xffff) + xInc * 4); 1716cabdff1aSopenharmony_ci vcoord[2] = vec_splats((xpos & 0xffff) + xInc * 8); 1717cabdff1aSopenharmony_ci vcoord[3] = vec_splats((xpos & 0xffff) + xInc * 12); 1718cabdff1aSopenharmony_ci 1719cabdff1aSopenharmony_ci vcoord[0] = vec_add(vcoord[0], vadd); 1720cabdff1aSopenharmony_ci vcoord[1] = vec_add(vcoord[1], vadd); 1721cabdff1aSopenharmony_ci vcoord[2] = vec_add(vcoord[2], vadd); 1722cabdff1aSopenharmony_ci vcoord[3] = vec_add(vcoord[3], vadd); 1723cabdff1aSopenharmony_ci 1724cabdff1aSopenharmony_ci vcoord[0] = vec_sr(vcoord[0], vshift16); 1725cabdff1aSopenharmony_ci vcoord[1] = vec_sr(vcoord[1], vshift16); 1726cabdff1aSopenharmony_ci vcoord[2] = vec_sr(vcoord[2], vshift16); 1727cabdff1aSopenharmony_ci vcoord[3] = vec_sr(vcoord[3], vshift16); 1728cabdff1aSopenharmony_ci 1729cabdff1aSopenharmony_ci vcoord16[0] = vec_pack(vcoord[0], vcoord[1]); 1730cabdff1aSopenharmony_ci vcoord16[1] = vec_pack(vcoord[2], vcoord[3]); 1731cabdff1aSopenharmony_ci vperm = vec_pack(vcoord16[0], vcoord16[1]); 1732cabdff1aSopenharmony_ci 1733cabdff1aSopenharmony_ci vin = vec_perm(vin, vin, vperm); 1734cabdff1aSopenharmony_ci 1735cabdff1aSopenharmony_ci vin2 = vec_vsx_ld(1, &src[xx]); 1736cabdff1aSopenharmony_ci vin2 = vec_perm(vin2, vin2, vperm); 1737cabdff1aSopenharmony_ci 1738cabdff1aSopenharmony_ci vmul = (vec_s8) vec_sub(vin2, vin); 1739cabdff1aSopenharmony_ci vtmp = vec_mule(vmul, valpha); 1740cabdff1aSopenharmony_ci vtmp2 = vec_mulo(vmul, valpha); 1741cabdff1aSopenharmony_ci vtmp3 = vec_mergeh(vtmp, vtmp2); 1742cabdff1aSopenharmony_ci vtmp4 = vec_mergel(vtmp, vtmp2); 1743cabdff1aSopenharmony_ci 1744cabdff1aSopenharmony_ci vd_l = (vec_u16) vec_mergeh(vin, vzero); 1745cabdff1aSopenharmony_ci vd_r = (vec_u16) vec_mergel(vin, vzero); 1746cabdff1aSopenharmony_ci vd_l = vec_sl(vd_l, vshift); 1747cabdff1aSopenharmony_ci vd_r = vec_sl(vd_r, vshift); 1748cabdff1aSopenharmony_ci 1749cabdff1aSopenharmony_ci vd_l = vec_add(vd_l, (vec_u16) vtmp3); 1750cabdff1aSopenharmony_ci vd_r = vec_add(vd_r, (vec_u16) vtmp4); 1751cabdff1aSopenharmony_ci 1752cabdff1aSopenharmony_ci vec_st((vec_s16) vd_l, 0, &dst[i]); 1753cabdff1aSopenharmony_ci vec_st((vec_s16) vd_r, 0, &dst[i + 8]); 1754cabdff1aSopenharmony_ci 1755cabdff1aSopenharmony_ci xpos += xInc * 16; 1756cabdff1aSopenharmony_ci } 1757cabdff1aSopenharmony_ci for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) 1758cabdff1aSopenharmony_ci dst[i] = src[srcW-1]*128; 1759cabdff1aSopenharmony_ci} 1760cabdff1aSopenharmony_ci 1761cabdff1aSopenharmony_ci#define HCSCALE(in, out) \ 1762cabdff1aSopenharmony_ci vin = vec_vsx_ld(0, &in[xx]); \ 1763cabdff1aSopenharmony_ci vin = vec_perm(vin, vin, vperm); \ 1764cabdff1aSopenharmony_ci\ 1765cabdff1aSopenharmony_ci vin2 = vec_vsx_ld(1, &in[xx]); \ 1766cabdff1aSopenharmony_ci vin2 = vec_perm(vin2, vin2, vperm); \ 1767cabdff1aSopenharmony_ci\ 1768cabdff1aSopenharmony_ci vtmp = vec_mule(vin, valphaxor); \ 1769cabdff1aSopenharmony_ci vtmp2 = vec_mulo(vin, valphaxor); \ 1770cabdff1aSopenharmony_ci vtmp3 = vec_mergeh(vtmp, vtmp2); \ 1771cabdff1aSopenharmony_ci vtmp4 = vec_mergel(vtmp, vtmp2); \ 1772cabdff1aSopenharmony_ci\ 1773cabdff1aSopenharmony_ci vtmp = vec_mule(vin2, valpha); \ 1774cabdff1aSopenharmony_ci vtmp2 = vec_mulo(vin2, valpha); \ 1775cabdff1aSopenharmony_ci vd_l = vec_mergeh(vtmp, vtmp2); \ 1776cabdff1aSopenharmony_ci vd_r = vec_mergel(vtmp, vtmp2); \ 1777cabdff1aSopenharmony_ci\ 1778cabdff1aSopenharmony_ci vd_l = vec_add(vd_l, vtmp3); \ 1779cabdff1aSopenharmony_ci vd_r = vec_add(vd_r, vtmp4); \ 1780cabdff1aSopenharmony_ci\ 1781cabdff1aSopenharmony_ci vec_st((vec_s16) vd_l, 0, &out[i]); \ 1782cabdff1aSopenharmony_ci vec_st((vec_s16) vd_r, 0, &out[i + 8]) 1783cabdff1aSopenharmony_ci 1784cabdff1aSopenharmony_cistatic void hcscale_fast_vsx(SwsContext *c, int16_t *dst1, int16_t *dst2, 1785cabdff1aSopenharmony_ci int dstWidth, const uint8_t *src1, 1786cabdff1aSopenharmony_ci const uint8_t *src2, int srcW, int xInc) 1787cabdff1aSopenharmony_ci{ 1788cabdff1aSopenharmony_ci int i; 1789cabdff1aSopenharmony_ci unsigned int xpos = 0, xx; 1790cabdff1aSopenharmony_ci vec_u8 vin, vin2, vperm; 1791cabdff1aSopenharmony_ci vec_u8 valpha, valphaxor; 1792cabdff1aSopenharmony_ci vec_u16 vtmp, vtmp2, vtmp3, vtmp4; 1793cabdff1aSopenharmony_ci vec_u16 vd_l, vd_r, vcoord16[2]; 1794cabdff1aSopenharmony_ci vec_u32 vcoord[4]; 1795cabdff1aSopenharmony_ci const vec_u8 vxor = vec_splats((uint8_t) 127); 1796cabdff1aSopenharmony_ci const vec_u32 vadd = (vec_u32) { 1797cabdff1aSopenharmony_ci 0, 1798cabdff1aSopenharmony_ci xInc * 1, 1799cabdff1aSopenharmony_ci xInc * 2, 1800cabdff1aSopenharmony_ci xInc * 3, 1801cabdff1aSopenharmony_ci }; 1802cabdff1aSopenharmony_ci const vec_u16 vadd16 = (vec_u16) { // Modulo math 1803cabdff1aSopenharmony_ci 0, 1804cabdff1aSopenharmony_ci xInc * 1, 1805cabdff1aSopenharmony_ci xInc * 2, 1806cabdff1aSopenharmony_ci xInc * 3, 1807cabdff1aSopenharmony_ci xInc * 4, 1808cabdff1aSopenharmony_ci xInc * 5, 1809cabdff1aSopenharmony_ci xInc * 6, 1810cabdff1aSopenharmony_ci xInc * 7, 1811cabdff1aSopenharmony_ci }; 1812cabdff1aSopenharmony_ci const vec_u32 vshift16 = vec_splats((uint32_t) 16); 1813cabdff1aSopenharmony_ci const vec_u16 vshift9 = vec_splat_u16(9); 1814cabdff1aSopenharmony_ci 1815cabdff1aSopenharmony_ci for (i = 0; i < dstWidth; i += 16) { 1816cabdff1aSopenharmony_ci vcoord16[0] = vec_splats((uint16_t) xpos); 1817cabdff1aSopenharmony_ci vcoord16[1] = vec_splats((uint16_t) (xpos + xInc * 8)); 1818cabdff1aSopenharmony_ci 1819cabdff1aSopenharmony_ci vcoord16[0] = vec_add(vcoord16[0], vadd16); 1820cabdff1aSopenharmony_ci vcoord16[1] = vec_add(vcoord16[1], vadd16); 1821cabdff1aSopenharmony_ci 1822cabdff1aSopenharmony_ci vcoord16[0] = vec_sr(vcoord16[0], vshift9); 1823cabdff1aSopenharmony_ci vcoord16[1] = vec_sr(vcoord16[1], vshift9); 1824cabdff1aSopenharmony_ci valpha = vec_pack(vcoord16[0], vcoord16[1]); 1825cabdff1aSopenharmony_ci valphaxor = vec_xor(valpha, vxor); 1826cabdff1aSopenharmony_ci 1827cabdff1aSopenharmony_ci xx = xpos >> 16; 1828cabdff1aSopenharmony_ci 1829cabdff1aSopenharmony_ci vcoord[0] = vec_splats(xpos & 0xffff); 1830cabdff1aSopenharmony_ci vcoord[1] = vec_splats((xpos & 0xffff) + xInc * 4); 1831cabdff1aSopenharmony_ci vcoord[2] = vec_splats((xpos & 0xffff) + xInc * 8); 1832cabdff1aSopenharmony_ci vcoord[3] = vec_splats((xpos & 0xffff) + xInc * 12); 1833cabdff1aSopenharmony_ci 1834cabdff1aSopenharmony_ci vcoord[0] = vec_add(vcoord[0], vadd); 1835cabdff1aSopenharmony_ci vcoord[1] = vec_add(vcoord[1], vadd); 1836cabdff1aSopenharmony_ci vcoord[2] = vec_add(vcoord[2], vadd); 1837cabdff1aSopenharmony_ci vcoord[3] = vec_add(vcoord[3], vadd); 1838cabdff1aSopenharmony_ci 1839cabdff1aSopenharmony_ci vcoord[0] = vec_sr(vcoord[0], vshift16); 1840cabdff1aSopenharmony_ci vcoord[1] = vec_sr(vcoord[1], vshift16); 1841cabdff1aSopenharmony_ci vcoord[2] = vec_sr(vcoord[2], vshift16); 1842cabdff1aSopenharmony_ci vcoord[3] = vec_sr(vcoord[3], vshift16); 1843cabdff1aSopenharmony_ci 1844cabdff1aSopenharmony_ci vcoord16[0] = vec_pack(vcoord[0], vcoord[1]); 1845cabdff1aSopenharmony_ci vcoord16[1] = vec_pack(vcoord[2], vcoord[3]); 1846cabdff1aSopenharmony_ci vperm = vec_pack(vcoord16[0], vcoord16[1]); 1847cabdff1aSopenharmony_ci 1848cabdff1aSopenharmony_ci HCSCALE(src1, dst1); 1849cabdff1aSopenharmony_ci HCSCALE(src2, dst2); 1850cabdff1aSopenharmony_ci 1851cabdff1aSopenharmony_ci xpos += xInc * 16; 1852cabdff1aSopenharmony_ci } 1853cabdff1aSopenharmony_ci for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) { 1854cabdff1aSopenharmony_ci dst1[i] = src1[srcW-1]*128; 1855cabdff1aSopenharmony_ci dst2[i] = src2[srcW-1]*128; 1856cabdff1aSopenharmony_ci } 1857cabdff1aSopenharmony_ci} 1858cabdff1aSopenharmony_ci 1859cabdff1aSopenharmony_ci#undef HCSCALE 1860cabdff1aSopenharmony_ci 1861cabdff1aSopenharmony_cistatic void hScale8To19_vsx(SwsContext *c, int16_t *_dst, int dstW, 1862cabdff1aSopenharmony_ci const uint8_t *src, const int16_t *filter, 1863cabdff1aSopenharmony_ci const int32_t *filterPos, int filterSize) 1864cabdff1aSopenharmony_ci{ 1865cabdff1aSopenharmony_ci int i, j; 1866cabdff1aSopenharmony_ci int32_t *dst = (int32_t *) _dst; 1867cabdff1aSopenharmony_ci vec_s16 vfilter, vin; 1868cabdff1aSopenharmony_ci vec_u8 vin8; 1869cabdff1aSopenharmony_ci vec_s32 vout; 1870cabdff1aSopenharmony_ci const vec_u8 vzero = vec_splat_u8(0); 1871cabdff1aSopenharmony_ci const vec_u8 vunusedtab[8] = { 1872cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 1873cabdff1aSopenharmony_ci 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}, 1874cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 1875cabdff1aSopenharmony_ci 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 1876cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x10, 0x10, 0x10, 0x10, 1877cabdff1aSopenharmony_ci 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 1878cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x10, 0x10, 1879cabdff1aSopenharmony_ci 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 1880cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 1881cabdff1aSopenharmony_ci 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 1882cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 1883cabdff1aSopenharmony_ci 0x8, 0x9, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 1884cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 1885cabdff1aSopenharmony_ci 0x8, 0x9, 0xa, 0xb, 0x10, 0x10, 0x10, 0x10}, 1886cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 1887cabdff1aSopenharmony_ci 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0x10, 0x10}, 1888cabdff1aSopenharmony_ci }; 1889cabdff1aSopenharmony_ci const vec_u8 vunused = vunusedtab[filterSize % 8]; 1890cabdff1aSopenharmony_ci 1891cabdff1aSopenharmony_ci if (filterSize == 1) { 1892cabdff1aSopenharmony_ci for (i = 0; i < dstW; i++) { 1893cabdff1aSopenharmony_ci int srcPos = filterPos[i]; 1894cabdff1aSopenharmony_ci int val = 0; 1895cabdff1aSopenharmony_ci for (j = 0; j < filterSize; j++) { 1896cabdff1aSopenharmony_ci val += ((int)src[srcPos + j]) * filter[filterSize * i + j]; 1897cabdff1aSopenharmony_ci } 1898cabdff1aSopenharmony_ci dst[i] = FFMIN(val >> 3, (1 << 19) - 1); // the cubic equation does overflow ... 1899cabdff1aSopenharmony_ci } 1900cabdff1aSopenharmony_ci } else { 1901cabdff1aSopenharmony_ci for (i = 0; i < dstW; i++) { 1902cabdff1aSopenharmony_ci const int srcPos = filterPos[i]; 1903cabdff1aSopenharmony_ci vout = vec_splat_s32(0); 1904cabdff1aSopenharmony_ci for (j = 0; j < filterSize; j += 8) { 1905cabdff1aSopenharmony_ci vin8 = vec_vsx_ld(0, &src[srcPos + j]); 1906cabdff1aSopenharmony_ci vin = (vec_s16) vec_mergeh(vin8, vzero); 1907cabdff1aSopenharmony_ci if (j + 8 > filterSize) // Remove the unused elements on the last round 1908cabdff1aSopenharmony_ci vin = vec_perm(vin, (vec_s16) vzero, vunused); 1909cabdff1aSopenharmony_ci 1910cabdff1aSopenharmony_ci vfilter = vec_vsx_ld(0, &filter[filterSize * i + j]); 1911cabdff1aSopenharmony_ci vout = vec_msums(vin, vfilter, vout); 1912cabdff1aSopenharmony_ci } 1913cabdff1aSopenharmony_ci vout = vec_sums(vout, (vec_s32) vzero); 1914cabdff1aSopenharmony_ci dst[i] = FFMIN(vout[3] >> 3, (1 << 19) - 1); 1915cabdff1aSopenharmony_ci } 1916cabdff1aSopenharmony_ci } 1917cabdff1aSopenharmony_ci} 1918cabdff1aSopenharmony_ci 1919cabdff1aSopenharmony_cistatic void hScale16To19_vsx(SwsContext *c, int16_t *_dst, int dstW, 1920cabdff1aSopenharmony_ci const uint8_t *_src, const int16_t *filter, 1921cabdff1aSopenharmony_ci const int32_t *filterPos, int filterSize) 1922cabdff1aSopenharmony_ci{ 1923cabdff1aSopenharmony_ci const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat); 1924cabdff1aSopenharmony_ci int i, j; 1925cabdff1aSopenharmony_ci int32_t *dst = (int32_t *) _dst; 1926cabdff1aSopenharmony_ci const uint16_t *src = (const uint16_t *) _src; 1927cabdff1aSopenharmony_ci int bits = desc->comp[0].depth - 1; 1928cabdff1aSopenharmony_ci int sh = bits - 4; 1929cabdff1aSopenharmony_ci vec_s16 vfilter, vin; 1930cabdff1aSopenharmony_ci vec_s32 vout, vtmp, vtmp2, vfilter32_l, vfilter32_r; 1931cabdff1aSopenharmony_ci const vec_u8 vzero = vec_splat_u8(0); 1932cabdff1aSopenharmony_ci const vec_u8 vunusedtab[8] = { 1933cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 1934cabdff1aSopenharmony_ci 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}, 1935cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 1936cabdff1aSopenharmony_ci 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 1937cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x10, 0x10, 0x10, 0x10, 1938cabdff1aSopenharmony_ci 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 1939cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x10, 0x10, 1940cabdff1aSopenharmony_ci 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 1941cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 1942cabdff1aSopenharmony_ci 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 1943cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 1944cabdff1aSopenharmony_ci 0x8, 0x9, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 1945cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 1946cabdff1aSopenharmony_ci 0x8, 0x9, 0xa, 0xb, 0x10, 0x10, 0x10, 0x10}, 1947cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 1948cabdff1aSopenharmony_ci 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0x10, 0x10}, 1949cabdff1aSopenharmony_ci }; 1950cabdff1aSopenharmony_ci const vec_u8 vunused = vunusedtab[filterSize % 8]; 1951cabdff1aSopenharmony_ci 1952cabdff1aSopenharmony_ci if ((isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) { 1953cabdff1aSopenharmony_ci sh = 9; 1954cabdff1aSopenharmony_ci } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */ 1955cabdff1aSopenharmony_ci sh = 16 - 1 - 4; 1956cabdff1aSopenharmony_ci } 1957cabdff1aSopenharmony_ci 1958cabdff1aSopenharmony_ci if (filterSize == 1) { 1959cabdff1aSopenharmony_ci for (i = 0; i < dstW; i++) { 1960cabdff1aSopenharmony_ci int srcPos = filterPos[i]; 1961cabdff1aSopenharmony_ci int val = 0; 1962cabdff1aSopenharmony_ci 1963cabdff1aSopenharmony_ci for (j = 0; j < filterSize; j++) { 1964cabdff1aSopenharmony_ci val += src[srcPos + j] * filter[filterSize * i + j]; 1965cabdff1aSopenharmony_ci } 1966cabdff1aSopenharmony_ci // filter=14 bit, input=16 bit, output=30 bit, >> 11 makes 19 bit 1967cabdff1aSopenharmony_ci dst[i] = FFMIN(val >> sh, (1 << 19) - 1); 1968cabdff1aSopenharmony_ci } 1969cabdff1aSopenharmony_ci } else { 1970cabdff1aSopenharmony_ci for (i = 0; i < dstW; i++) { 1971cabdff1aSopenharmony_ci const int srcPos = filterPos[i]; 1972cabdff1aSopenharmony_ci vout = vec_splat_s32(0); 1973cabdff1aSopenharmony_ci for (j = 0; j < filterSize; j += 8) { 1974cabdff1aSopenharmony_ci vin = (vec_s16) vec_vsx_ld(0, &src[srcPos + j]); 1975cabdff1aSopenharmony_ci if (j + 8 > filterSize) // Remove the unused elements on the last round 1976cabdff1aSopenharmony_ci vin = vec_perm(vin, (vec_s16) vzero, vunused); 1977cabdff1aSopenharmony_ci 1978cabdff1aSopenharmony_ci vfilter = vec_vsx_ld(0, &filter[filterSize * i + j]); 1979cabdff1aSopenharmony_ci vfilter32_l = vec_unpackh(vfilter); 1980cabdff1aSopenharmony_ci vfilter32_r = vec_unpackl(vfilter); 1981cabdff1aSopenharmony_ci 1982cabdff1aSopenharmony_ci vtmp = (vec_s32) vec_mergeh(vin, (vec_s16) vzero); 1983cabdff1aSopenharmony_ci vtmp2 = (vec_s32) vec_mergel(vin, (vec_s16) vzero); 1984cabdff1aSopenharmony_ci 1985cabdff1aSopenharmony_ci vtmp = vec_mul(vtmp, vfilter32_l); 1986cabdff1aSopenharmony_ci vtmp2 = vec_mul(vtmp2, vfilter32_r); 1987cabdff1aSopenharmony_ci 1988cabdff1aSopenharmony_ci vout = vec_adds(vout, vtmp); 1989cabdff1aSopenharmony_ci vout = vec_adds(vout, vtmp2); 1990cabdff1aSopenharmony_ci } 1991cabdff1aSopenharmony_ci vout = vec_sums(vout, (vec_s32) vzero); 1992cabdff1aSopenharmony_ci dst[i] = FFMIN(vout[3] >> sh, (1 << 19) - 1); 1993cabdff1aSopenharmony_ci } 1994cabdff1aSopenharmony_ci } 1995cabdff1aSopenharmony_ci} 1996cabdff1aSopenharmony_ci 1997cabdff1aSopenharmony_cistatic void hScale16To15_vsx(SwsContext *c, int16_t *dst, int dstW, 1998cabdff1aSopenharmony_ci const uint8_t *_src, const int16_t *filter, 1999cabdff1aSopenharmony_ci const int32_t *filterPos, int filterSize) 2000cabdff1aSopenharmony_ci{ 2001cabdff1aSopenharmony_ci const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat); 2002cabdff1aSopenharmony_ci int i, j; 2003cabdff1aSopenharmony_ci const uint16_t *src = (const uint16_t *) _src; 2004cabdff1aSopenharmony_ci int sh = desc->comp[0].depth - 1; 2005cabdff1aSopenharmony_ci vec_s16 vfilter, vin; 2006cabdff1aSopenharmony_ci vec_s32 vout, vtmp, vtmp2, vfilter32_l, vfilter32_r; 2007cabdff1aSopenharmony_ci const vec_u8 vzero = vec_splat_u8(0); 2008cabdff1aSopenharmony_ci const vec_u8 vunusedtab[8] = { 2009cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 2010cabdff1aSopenharmony_ci 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}, 2011cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 2012cabdff1aSopenharmony_ci 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 2013cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x10, 0x10, 0x10, 0x10, 2014cabdff1aSopenharmony_ci 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 2015cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x10, 0x10, 2016cabdff1aSopenharmony_ci 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 2017cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 2018cabdff1aSopenharmony_ci 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 2019cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 2020cabdff1aSopenharmony_ci 0x8, 0x9, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, 2021cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 2022cabdff1aSopenharmony_ci 0x8, 0x9, 0xa, 0xb, 0x10, 0x10, 0x10, 0x10}, 2023cabdff1aSopenharmony_ci (vec_u8) {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 2024cabdff1aSopenharmony_ci 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0x10, 0x10}, 2025cabdff1aSopenharmony_ci }; 2026cabdff1aSopenharmony_ci const vec_u8 vunused = vunusedtab[filterSize % 8]; 2027cabdff1aSopenharmony_ci 2028cabdff1aSopenharmony_ci if (sh<15) { 2029cabdff1aSopenharmony_ci sh = isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8 ? 13 : (desc->comp[0].depth - 1); 2030cabdff1aSopenharmony_ci } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */ 2031cabdff1aSopenharmony_ci sh = 16 - 1; 2032cabdff1aSopenharmony_ci } 2033cabdff1aSopenharmony_ci 2034cabdff1aSopenharmony_ci if (filterSize == 1) { 2035cabdff1aSopenharmony_ci for (i = 0; i < dstW; i++) { 2036cabdff1aSopenharmony_ci int srcPos = filterPos[i]; 2037cabdff1aSopenharmony_ci int val = 0; 2038cabdff1aSopenharmony_ci 2039cabdff1aSopenharmony_ci for (j = 0; j < filterSize; j++) { 2040cabdff1aSopenharmony_ci val += src[srcPos + j] * filter[filterSize * i + j]; 2041cabdff1aSopenharmony_ci } 2042cabdff1aSopenharmony_ci // filter=14 bit, input=16 bit, output=30 bit, >> 15 makes 15 bit 2043cabdff1aSopenharmony_ci dst[i] = FFMIN(val >> sh, (1 << 15) - 1); 2044cabdff1aSopenharmony_ci } 2045cabdff1aSopenharmony_ci } else { 2046cabdff1aSopenharmony_ci for (i = 0; i < dstW; i++) { 2047cabdff1aSopenharmony_ci const int srcPos = filterPos[i]; 2048cabdff1aSopenharmony_ci vout = vec_splat_s32(0); 2049cabdff1aSopenharmony_ci for (j = 0; j < filterSize; j += 8) { 2050cabdff1aSopenharmony_ci vin = (vec_s16) vec_vsx_ld(0, &src[srcPos + j]); 2051cabdff1aSopenharmony_ci if (j + 8 > filterSize) // Remove the unused elements on the last round 2052cabdff1aSopenharmony_ci vin = vec_perm(vin, (vec_s16) vzero, vunused); 2053cabdff1aSopenharmony_ci 2054cabdff1aSopenharmony_ci vfilter = vec_vsx_ld(0, &filter[filterSize * i + j]); 2055cabdff1aSopenharmony_ci vfilter32_l = vec_unpackh(vfilter); 2056cabdff1aSopenharmony_ci vfilter32_r = vec_unpackl(vfilter); 2057cabdff1aSopenharmony_ci 2058cabdff1aSopenharmony_ci vtmp = (vec_s32) vec_mergeh(vin, (vec_s16) vzero); 2059cabdff1aSopenharmony_ci vtmp2 = (vec_s32) vec_mergel(vin, (vec_s16) vzero); 2060cabdff1aSopenharmony_ci 2061cabdff1aSopenharmony_ci vtmp = vec_mul(vtmp, vfilter32_l); 2062cabdff1aSopenharmony_ci vtmp2 = vec_mul(vtmp2, vfilter32_r); 2063cabdff1aSopenharmony_ci 2064cabdff1aSopenharmony_ci vout = vec_adds(vout, vtmp); 2065cabdff1aSopenharmony_ci vout = vec_adds(vout, vtmp2); 2066cabdff1aSopenharmony_ci } 2067cabdff1aSopenharmony_ci vout = vec_sums(vout, (vec_s32) vzero); 2068cabdff1aSopenharmony_ci dst[i] = FFMIN(vout[3] >> sh, (1 << 15) - 1); 2069cabdff1aSopenharmony_ci } 2070cabdff1aSopenharmony_ci } 2071cabdff1aSopenharmony_ci} 2072cabdff1aSopenharmony_ci 2073cabdff1aSopenharmony_ci#endif /* !HAVE_BIGENDIAN */ 2074cabdff1aSopenharmony_ci 2075cabdff1aSopenharmony_ci#endif /* HAVE_VSX */ 2076cabdff1aSopenharmony_ci 2077cabdff1aSopenharmony_ciav_cold void ff_sws_init_swscale_vsx(SwsContext *c) 2078cabdff1aSopenharmony_ci{ 2079cabdff1aSopenharmony_ci#if HAVE_VSX 2080cabdff1aSopenharmony_ci enum AVPixelFormat dstFormat = c->dstFormat; 2081cabdff1aSopenharmony_ci const int cpu_flags = av_get_cpu_flags(); 2082cabdff1aSopenharmony_ci const unsigned char power8 = HAVE_POWER8 && cpu_flags & AV_CPU_FLAG_POWER8; 2083cabdff1aSopenharmony_ci 2084cabdff1aSopenharmony_ci if (!(cpu_flags & AV_CPU_FLAG_VSX)) 2085cabdff1aSopenharmony_ci return; 2086cabdff1aSopenharmony_ci 2087cabdff1aSopenharmony_ci#if !HAVE_BIGENDIAN 2088cabdff1aSopenharmony_ci if (c->srcBpc == 8) { 2089cabdff1aSopenharmony_ci if (c->dstBpc <= 14) { 2090cabdff1aSopenharmony_ci c->hyScale = c->hcScale = hScale_real_vsx; 2091cabdff1aSopenharmony_ci if (c->flags & SWS_FAST_BILINEAR && c->dstW >= c->srcW && c->chrDstW >= c->chrSrcW) { 2092cabdff1aSopenharmony_ci c->hyscale_fast = hyscale_fast_vsx; 2093cabdff1aSopenharmony_ci c->hcscale_fast = hcscale_fast_vsx; 2094cabdff1aSopenharmony_ci } 2095cabdff1aSopenharmony_ci } else { 2096cabdff1aSopenharmony_ci c->hyScale = c->hcScale = hScale8To19_vsx; 2097cabdff1aSopenharmony_ci } 2098cabdff1aSopenharmony_ci } else { 2099cabdff1aSopenharmony_ci if (power8) { 2100cabdff1aSopenharmony_ci c->hyScale = c->hcScale = c->dstBpc > 14 ? hScale16To19_vsx 2101cabdff1aSopenharmony_ci : hScale16To15_vsx; 2102cabdff1aSopenharmony_ci } 2103cabdff1aSopenharmony_ci } 2104cabdff1aSopenharmony_ci if (!is16BPS(dstFormat) && !isNBPS(dstFormat) && !isSemiPlanarYUV(dstFormat) && 2105cabdff1aSopenharmony_ci dstFormat != AV_PIX_FMT_GRAYF32BE && dstFormat != AV_PIX_FMT_GRAYF32LE && 2106cabdff1aSopenharmony_ci !c->needAlpha) { 2107cabdff1aSopenharmony_ci c->yuv2planeX = yuv2planeX_vsx; 2108cabdff1aSopenharmony_ci } 2109cabdff1aSopenharmony_ci#endif 2110cabdff1aSopenharmony_ci 2111cabdff1aSopenharmony_ci if (!(c->flags & (SWS_BITEXACT | SWS_FULL_CHR_H_INT)) && !c->needAlpha) { 2112cabdff1aSopenharmony_ci switch (c->dstBpc) { 2113cabdff1aSopenharmony_ci case 8: 2114cabdff1aSopenharmony_ci c->yuv2plane1 = yuv2plane1_8_vsx; 2115cabdff1aSopenharmony_ci break; 2116cabdff1aSopenharmony_ci#if !HAVE_BIGENDIAN 2117cabdff1aSopenharmony_ci case 9: 2118cabdff1aSopenharmony_ci c->yuv2plane1 = isBE(dstFormat) ? yuv2plane1_9BE_vsx : yuv2plane1_9LE_vsx; 2119cabdff1aSopenharmony_ci c->yuv2planeX = isBE(dstFormat) ? yuv2planeX_9BE_vsx : yuv2planeX_9LE_vsx; 2120cabdff1aSopenharmony_ci break; 2121cabdff1aSopenharmony_ci case 10: 2122cabdff1aSopenharmony_ci c->yuv2plane1 = isBE(dstFormat) ? yuv2plane1_10BE_vsx : yuv2plane1_10LE_vsx; 2123cabdff1aSopenharmony_ci c->yuv2planeX = isBE(dstFormat) ? yuv2planeX_10BE_vsx : yuv2planeX_10LE_vsx; 2124cabdff1aSopenharmony_ci break; 2125cabdff1aSopenharmony_ci case 12: 2126cabdff1aSopenharmony_ci c->yuv2plane1 = isBE(dstFormat) ? yuv2plane1_12BE_vsx : yuv2plane1_12LE_vsx; 2127cabdff1aSopenharmony_ci c->yuv2planeX = isBE(dstFormat) ? yuv2planeX_12BE_vsx : yuv2planeX_12LE_vsx; 2128cabdff1aSopenharmony_ci break; 2129cabdff1aSopenharmony_ci case 14: 2130cabdff1aSopenharmony_ci c->yuv2plane1 = isBE(dstFormat) ? yuv2plane1_14BE_vsx : yuv2plane1_14LE_vsx; 2131cabdff1aSopenharmony_ci c->yuv2planeX = isBE(dstFormat) ? yuv2planeX_14BE_vsx : yuv2planeX_14LE_vsx; 2132cabdff1aSopenharmony_ci break; 2133cabdff1aSopenharmony_ci case 16: 2134cabdff1aSopenharmony_ci c->yuv2plane1 = isBE(dstFormat) ? yuv2plane1_16BE_vsx : yuv2plane1_16LE_vsx; 2135cabdff1aSopenharmony_ci#if HAVE_POWER8 2136cabdff1aSopenharmony_ci if (cpu_flags & AV_CPU_FLAG_POWER8) { 2137cabdff1aSopenharmony_ci c->yuv2planeX = isBE(dstFormat) ? yuv2planeX_16BE_vsx : yuv2planeX_16LE_vsx; 2138cabdff1aSopenharmony_ci } 2139cabdff1aSopenharmony_ci#endif /* HAVE_POWER8 */ 2140cabdff1aSopenharmony_ci break; 2141cabdff1aSopenharmony_ci#endif /* !HAVE_BIGENDIAN */ 2142cabdff1aSopenharmony_ci } 2143cabdff1aSopenharmony_ci } 2144cabdff1aSopenharmony_ci 2145cabdff1aSopenharmony_ci if (c->flags & SWS_BITEXACT) 2146cabdff1aSopenharmony_ci return; 2147cabdff1aSopenharmony_ci 2148cabdff1aSopenharmony_ci#if !HAVE_BIGENDIAN 2149cabdff1aSopenharmony_ci if (c->flags & SWS_FULL_CHR_H_INT) { 2150cabdff1aSopenharmony_ci switch (dstFormat) { 2151cabdff1aSopenharmony_ci case AV_PIX_FMT_RGB24: 2152cabdff1aSopenharmony_ci if (power8) { 2153cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2rgb24_full_1_vsx; 2154cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2rgb24_full_2_vsx; 2155cabdff1aSopenharmony_ci c->yuv2packedX = yuv2rgb24_full_X_vsx; 2156cabdff1aSopenharmony_ci } 2157cabdff1aSopenharmony_ci break; 2158cabdff1aSopenharmony_ci case AV_PIX_FMT_BGR24: 2159cabdff1aSopenharmony_ci if (power8) { 2160cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2bgr24_full_1_vsx; 2161cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2bgr24_full_2_vsx; 2162cabdff1aSopenharmony_ci c->yuv2packedX = yuv2bgr24_full_X_vsx; 2163cabdff1aSopenharmony_ci } 2164cabdff1aSopenharmony_ci break; 2165cabdff1aSopenharmony_ci case AV_PIX_FMT_BGRA: 2166cabdff1aSopenharmony_ci if (power8) { 2167cabdff1aSopenharmony_ci if (!c->needAlpha) { 2168cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2bgrx32_full_1_vsx; 2169cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2bgrx32_full_2_vsx; 2170cabdff1aSopenharmony_ci c->yuv2packedX = yuv2bgrx32_full_X_vsx; 2171cabdff1aSopenharmony_ci } 2172cabdff1aSopenharmony_ci } 2173cabdff1aSopenharmony_ci break; 2174cabdff1aSopenharmony_ci case AV_PIX_FMT_RGBA: 2175cabdff1aSopenharmony_ci if (power8) { 2176cabdff1aSopenharmony_ci if (!c->needAlpha) { 2177cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2rgbx32_full_1_vsx; 2178cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2rgbx32_full_2_vsx; 2179cabdff1aSopenharmony_ci c->yuv2packedX = yuv2rgbx32_full_X_vsx; 2180cabdff1aSopenharmony_ci } 2181cabdff1aSopenharmony_ci } 2182cabdff1aSopenharmony_ci break; 2183cabdff1aSopenharmony_ci case AV_PIX_FMT_ARGB: 2184cabdff1aSopenharmony_ci if (power8) { 2185cabdff1aSopenharmony_ci if (!c->needAlpha) { 2186cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2xrgb32_full_1_vsx; 2187cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2xrgb32_full_2_vsx; 2188cabdff1aSopenharmony_ci c->yuv2packedX = yuv2xrgb32_full_X_vsx; 2189cabdff1aSopenharmony_ci } 2190cabdff1aSopenharmony_ci } 2191cabdff1aSopenharmony_ci break; 2192cabdff1aSopenharmony_ci case AV_PIX_FMT_ABGR: 2193cabdff1aSopenharmony_ci if (power8) { 2194cabdff1aSopenharmony_ci if (!c->needAlpha) { 2195cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2xbgr32_full_1_vsx; 2196cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2xbgr32_full_2_vsx; 2197cabdff1aSopenharmony_ci c->yuv2packedX = yuv2xbgr32_full_X_vsx; 2198cabdff1aSopenharmony_ci } 2199cabdff1aSopenharmony_ci } 2200cabdff1aSopenharmony_ci break; 2201cabdff1aSopenharmony_ci } 2202cabdff1aSopenharmony_ci } else { /* !SWS_FULL_CHR_H_INT */ 2203cabdff1aSopenharmony_ci switch (dstFormat) { 2204cabdff1aSopenharmony_ci case AV_PIX_FMT_YUYV422: 2205cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2yuyv422_1_vsx; 2206cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2yuyv422_2_vsx; 2207cabdff1aSopenharmony_ci c->yuv2packedX = yuv2yuyv422_X_vsx; 2208cabdff1aSopenharmony_ci break; 2209cabdff1aSopenharmony_ci case AV_PIX_FMT_YVYU422: 2210cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2yvyu422_1_vsx; 2211cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2yvyu422_2_vsx; 2212cabdff1aSopenharmony_ci c->yuv2packedX = yuv2yvyu422_X_vsx; 2213cabdff1aSopenharmony_ci break; 2214cabdff1aSopenharmony_ci case AV_PIX_FMT_UYVY422: 2215cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2uyvy422_1_vsx; 2216cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2uyvy422_2_vsx; 2217cabdff1aSopenharmony_ci c->yuv2packedX = yuv2uyvy422_X_vsx; 2218cabdff1aSopenharmony_ci break; 2219cabdff1aSopenharmony_ci case AV_PIX_FMT_BGRA: 2220cabdff1aSopenharmony_ci if (power8) { 2221cabdff1aSopenharmony_ci if (!c->needAlpha) { 2222cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2bgrx32_1_vsx; 2223cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2bgrx32_2_vsx; 2224cabdff1aSopenharmony_ci } 2225cabdff1aSopenharmony_ci } 2226cabdff1aSopenharmony_ci break; 2227cabdff1aSopenharmony_ci case AV_PIX_FMT_RGBA: 2228cabdff1aSopenharmony_ci if (power8) { 2229cabdff1aSopenharmony_ci if (!c->needAlpha) { 2230cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2rgbx32_1_vsx; 2231cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2rgbx32_2_vsx; 2232cabdff1aSopenharmony_ci } 2233cabdff1aSopenharmony_ci } 2234cabdff1aSopenharmony_ci break; 2235cabdff1aSopenharmony_ci case AV_PIX_FMT_ARGB: 2236cabdff1aSopenharmony_ci if (power8) { 2237cabdff1aSopenharmony_ci if (!c->needAlpha) { 2238cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2xrgb32_1_vsx; 2239cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2xrgb32_2_vsx; 2240cabdff1aSopenharmony_ci } 2241cabdff1aSopenharmony_ci } 2242cabdff1aSopenharmony_ci break; 2243cabdff1aSopenharmony_ci case AV_PIX_FMT_ABGR: 2244cabdff1aSopenharmony_ci if (power8) { 2245cabdff1aSopenharmony_ci if (!c->needAlpha) { 2246cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2xbgr32_1_vsx; 2247cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2xbgr32_2_vsx; 2248cabdff1aSopenharmony_ci } 2249cabdff1aSopenharmony_ci } 2250cabdff1aSopenharmony_ci break; 2251cabdff1aSopenharmony_ci case AV_PIX_FMT_RGB24: 2252cabdff1aSopenharmony_ci if (power8) { 2253cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2rgb24_1_vsx; 2254cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2rgb24_2_vsx; 2255cabdff1aSopenharmony_ci } 2256cabdff1aSopenharmony_ci break; 2257cabdff1aSopenharmony_ci case AV_PIX_FMT_BGR24: 2258cabdff1aSopenharmony_ci if (power8) { 2259cabdff1aSopenharmony_ci c->yuv2packed1 = yuv2bgr24_1_vsx; 2260cabdff1aSopenharmony_ci c->yuv2packed2 = yuv2bgr24_2_vsx; 2261cabdff1aSopenharmony_ci } 2262cabdff1aSopenharmony_ci break; 2263cabdff1aSopenharmony_ci } 2264cabdff1aSopenharmony_ci } 2265cabdff1aSopenharmony_ci#endif /* !HAVE_BIGENDIAN */ 2266cabdff1aSopenharmony_ci 2267cabdff1aSopenharmony_ci#endif /* HAVE_VSX */ 2268cabdff1aSopenharmony_ci} 2269