/* * Copyright 2016 The LibYuv Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include <string.h> #include "libyuv/row.h" // This module is for GCC MSA#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)#include "libyuv/macros_msa.h" #ifdef __cplusplusnamespace libyuv {extern "C" {#endif #define ALPHA_VAL (-1) // Fill YUV -> RGB conversion constants into vectors#define YUVTORGB_SETUP(yuvconst, ub, vr, ug, vg, bb, bg, br, yg) \ { \ ub = __msa_fill_w(yuvconst->kUVToB[0]); \ vr = __msa_fill_w(yuvconst->kUVToR[1]); \ ug = __msa_fill_w(yuvconst->kUVToG[0]); \ vg = __msa_fill_w(yuvconst->kUVToG[1]); \ bb = __msa_fill_w(yuvconst->kUVBiasB[0]); \ bg = __msa_fill_w(yuvconst->kUVBiasG[0]); \ br = __msa_fill_w(yuvconst->kUVBiasR[0]); \ yg = __msa_fill_w(yuvconst->kYToRgb[0]); \ } // Load YUV 422 pixel data#define READYUV422(psrc_y, psrc_u, psrc_v, out_y, out_u, out_v) \ { \ uint64_t y_m; \ uint32_t u_m, v_m; \ v4i32 zero_m = {0}; \ y_m = LD(psrc_y); \ u_m = LW(psrc_u); \ v_m = LW(psrc_v); \ out_y = (v16u8)__msa_insert_d((v2i64)zero_m, 0, (int64_t)y_m); \ out_u = (v16u8)__msa_insert_w(zero_m, 0, (int32_t)u_m); \ out_v = (v16u8)__msa_insert_w(zero_m, 0, (int32_t)v_m); \ } // Clip input vector elements between 0 to 255#define CLIP_0TO255(in0, in1, in2, in3, in4, in5) \ { \ v4i32 max_m = __msa_ldi_w(0xFF); \ \ in0 = __msa_maxi_s_w(in0, 0); \ in1 = __msa_maxi_s_w(in1, 0); \ in2 = __msa_maxi_s_w(in2, 0); \ in3 = __msa_maxi_s_w(in3, 0); \ in4 = __msa_maxi_s_w(in4, 0); \ in5 = __msa_maxi_s_w(in5, 0); \ in0 = __msa_min_s_w(max_m, in0); \ in1 = __msa_min_s_w(max_m, in1); \ in2 = __msa_min_s_w(max_m, in2); \ in3 = __msa_min_s_w(max_m, in3); \ in4 = __msa_min_s_w(max_m, in4); \ in5 = __msa_min_s_w(max_m, in5); \ } // Convert 8 pixels of YUV 420 to RGB.#define YUVTORGB(in_y, in_uv, ubvr, ugvg, bb, bg, br, yg, out_b, out_g, out_r) \ { \ v8i16 vec0_m, vec1_m; \ v4i32 reg0_m, reg1_m, reg2_m, reg3_m, reg4_m; \ v4i32 reg5_m, reg6_m, reg7_m; \ v16i8 zero_m = {0}; \ \ vec0_m = (v8i16)__msa_ilvr_b((v16i8)in_y, (v16i8)in_y); \ vec1_m = (v8i16)__msa_ilvr_b((v16i8)zero_m, (v16i8)in_uv); \ reg0_m = (v4i32)__msa_ilvr_h((v8i16)zero_m, (v8i16)vec0_m); \ reg1_m = (v4i32)__msa_ilvl_h((v8i16)zero_m, (v8i16)vec0_m); \ reg2_m = (v4i32)__msa_ilvr_h((v8i16)zero_m, (v8i16)vec1_m); \ reg3_m = (v4i32)__msa_ilvl_h((v8i16)zero_m, (v8i16)vec1_m); \ reg0_m *= yg; \ reg1_m *= yg; \ reg2_m *= ubvr; \ reg3_m *= ubvr; \ reg0_m = __msa_srai_w(reg0_m, 16); \ reg1_m = __msa_srai_w(reg1_m, 16); \ reg4_m = __msa_dotp_s_w((v8i16)vec1_m, (v8i16)ugvg); \ reg5_m = __msa_ilvev_w(reg2_m, reg2_m); \ reg6_m = __msa_ilvev_w(reg3_m, reg3_m); \ reg7_m = __msa_ilvr_w(reg4_m, reg4_m); \ reg2_m = __msa_ilvod_w(reg2_m, reg2_m); \ reg3_m = __msa_ilvod_w(reg3_m, reg3_m); \ reg4_m = __msa_ilvl_w(reg4_m, reg4_m); \ reg5_m = reg0_m - reg5_m; \ reg6_m = reg1_m - reg6_m; \ reg2_m = reg0_m - reg2_m; \ reg3_m = reg1_m - reg3_m; \ reg7_m = reg0_m - reg7_m; \ reg4_m = reg1_m - reg4_m; \ reg5_m += bb; \ reg6_m += bb; \ reg7_m += bg; \ reg4_m += bg; \ reg2_m += br; \ reg3_m += br; \ reg5_m = __msa_srai_w(reg5_m, 6); \ reg6_m = __msa_srai_w(reg6_m, 6); \ reg7_m = __msa_srai_w(reg7_m, 6); \ reg4_m = __msa_srai_w(reg4_m, 6); \ reg2_m = __msa_srai_w(reg2_m, 6); \ reg3_m = __msa_srai_w(reg3_m, 6); \ CLIP_0TO255(reg5_m, reg6_m, reg7_m, reg4_m, reg2_m, reg3_m); \ out_b = __msa_pckev_h((v8i16)reg6_m, (v8i16)reg5_m); \ out_g = __msa_pckev_h((v8i16)reg4_m, (v8i16)reg7_m); \ out_r = __msa_pckev_h((v8i16)reg3_m, (v8i16)reg2_m); \ } // Pack and Store 8 ARGB values.#define STOREARGB(in0, in1, in2, in3, pdst_argb) \ { \ v8i16 vec0_m, vec1_m; \ v16u8 dst0_m, dst1_m; \ vec0_m = (v8i16)__msa_ilvev_b((v16i8)in1, (v16i8)in0); \ vec1_m = (v8i16)__msa_ilvev_b((v16i8)in3, (v16i8)in2); \ dst0_m = (v16u8)__msa_ilvr_h(vec1_m, vec0_m); \ dst1_m = (v16u8)__msa_ilvl_h(vec1_m, vec0_m); \ ST_UB2(dst0_m, dst1_m, pdst_argb, 16); \ } // Takes ARGB input and calculates Y.#define ARGBTOY(argb0, argb1, argb2, argb3, const0, const1, const2, shift, \ y_out) \ { \ v16u8 vec0_m, vec1_m, vec2_m, vec3_m; \ v8u16 reg0_m, reg1_m; \ \ vec0_m = (v16u8)__msa_pckev_h((v8i16)argb1, (v8i16)argb0); \ vec1_m = (v16u8)__msa_pckev_h((v8i16)argb3, (v8i16)argb2); \ vec2_m = (v16u8)__msa_pckod_h((v8i16)argb1, (v8i16)argb0); \ vec3_m = (v16u8)__msa_pckod_h((v8i16)argb3, (v8i16)argb2); \ reg0_m = __msa_dotp_u_h(vec0_m, const0); \ reg1_m = __msa_dotp_u_h(vec1_m, const0); \ reg0_m = __msa_dpadd_u_h(reg0_m, vec2_m, const1); \ reg1_m = __msa_dpadd_u_h(reg1_m, vec3_m, const1); \ reg0_m += const2; \ reg1_m += const2; \ reg0_m = (v8u16)__msa_srai_h((v8i16)reg0_m, shift); \ reg1_m = (v8u16)__msa_srai_h((v8i16)reg1_m, shift); \ y_out = (v16u8)__msa_pckev_b((v16i8)reg1_m, (v16i8)reg0_m); \ } // Loads current and next row of ARGB input and averages it to calculate U and V#define READ_ARGB(s_ptr, t_ptr, argb0, argb1, argb2, argb3) \ { \ v16u8 src0_m, src1_m, src2_m, src3_m, src4_m, src5_m, src6_m, src7_m; \ v16u8 vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ v16u8 vec8_m, vec9_m; \ v8u16 reg0_m, reg1_m, reg2_m, reg3_m, reg4_m, reg5_m, reg6_m, reg7_m; \ v8u16 reg8_m, reg9_m; \ \ src0_m = (v16u8)__msa_ld_b((v16i8*)s, 0); \ src1_m = (v16u8)__msa_ld_b((v16i8*)s, 16); \ src2_m = (v16u8)__msa_ld_b((v16i8*)s, 32); \ src3_m = (v16u8)__msa_ld_b((v16i8*)s, 48); \ src4_m = (v16u8)__msa_ld_b((v16i8*)t, 0); \ src5_m = (v16u8)__msa_ld_b((v16i8*)t, 16); \ src6_m = (v16u8)__msa_ld_b((v16i8*)t, 32); \ src7_m = (v16u8)__msa_ld_b((v16i8*)t, 48); \ vec0_m = (v16u8)__msa_ilvr_b((v16i8)src0_m, (v16i8)src4_m); \ vec1_m = (v16u8)__msa_ilvr_b((v16i8)src1_m, (v16i8)src5_m); \ vec2_m = (v16u8)__msa_ilvr_b((v16i8)src2_m, (v16i8)src6_m); \ vec3_m = (v16u8)__msa_ilvr_b((v16i8)src3_m, (v16i8)src7_m); \ vec4_m = (v16u8)__msa_ilvl_b((v16i8)src0_m, (v16i8)src4_m); \ vec5_m = (v16u8)__msa_ilvl_b((v16i8)src1_m, (v16i8)src5_m); \ vec6_m = (v16u8)__msa_ilvl_b((v16i8)src2_m, (v16i8)src6_m); \ vec7_m = (v16u8)__msa_ilvl_b((v16i8)src3_m, (v16i8)src7_m); \ reg0_m = __msa_hadd_u_h(vec0_m, vec0_m); \ reg1_m = __msa_hadd_u_h(vec1_m, vec1_m); \ reg2_m = __msa_hadd_u_h(vec2_m, vec2_m); \ reg3_m = __msa_hadd_u_h(vec3_m, vec3_m); \ reg4_m = __msa_hadd_u_h(vec4_m, vec4_m); \ reg5_m = __msa_hadd_u_h(vec5_m, vec5_m); \ reg6_m = __msa_hadd_u_h(vec6_m, vec6_m); \ reg7_m = __msa_hadd_u_h(vec7_m, vec7_m); \ reg8_m = (v8u16)__msa_pckev_d((v2i64)reg4_m, (v2i64)reg0_m); \ reg9_m = (v8u16)__msa_pckev_d((v2i64)reg5_m, (v2i64)reg1_m); \ reg8_m += (v8u16)__msa_pckod_d((v2i64)reg4_m, (v2i64)reg0_m); \ reg9_m += (v8u16)__msa_pckod_d((v2i64)reg5_m, (v2i64)reg1_m); \ reg0_m = (v8u16)__msa_pckev_d((v2i64)reg6_m, (v2i64)reg2_m); \ reg1_m = (v8u16)__msa_pckev_d((v2i64)reg7_m, (v2i64)reg3_m); \ reg0_m += (v8u16)__msa_pckod_d((v2i64)reg6_m, (v2i64)reg2_m); \ reg1_m += (v8u16)__msa_pckod_d((v2i64)reg7_m, (v2i64)reg3_m); \ reg8_m = (v8u16)__msa_srai_h((v8i16)reg8_m, 2); \ reg9_m = (v8u16)__msa_srai_h((v8i16)reg9_m, 2); \ reg0_m = (v8u16)__msa_srai_h((v8i16)reg0_m, 2); \ reg1_m = (v8u16)__msa_srai_h((v8i16)reg1_m, 2); \ argb0 = (v16u8)__msa_pckev_b((v16i8)reg9_m, (v16i8)reg8_m); \ argb1 = (v16u8)__msa_pckev_b((v16i8)reg1_m, (v16i8)reg0_m); \ src0_m = (v16u8)__msa_ld_b((v16i8*)s, 64); \ src1_m = (v16u8)__msa_ld_b((v16i8*)s, 80); \ src2_m = (v16u8)__msa_ld_b((v16i8*)s, 96); \ src3_m = (v16u8)__msa_ld_b((v16i8*)s, 112); \ src4_m = (v16u8)__msa_ld_b((v16i8*)t, 64); \ src5_m = (v16u8)__msa_ld_b((v16i8*)t, 80); \ src6_m = (v16u8)__msa_ld_b((v16i8*)t, 96); \ src7_m = (v16u8)__msa_ld_b((v16i8*)t, 112); \ vec2_m = (v16u8)__msa_ilvr_b((v16i8)src0_m, (v16i8)src4_m); \ vec3_m = (v16u8)__msa_ilvr_b((v16i8)src1_m, (v16i8)src5_m); \ vec4_m = (v16u8)__msa_ilvr_b((v16i8)src2_m, (v16i8)src6_m); \ vec5_m = (v16u8)__msa_ilvr_b((v16i8)src3_m, (v16i8)src7_m); \ vec6_m = (v16u8)__msa_ilvl_b((v16i8)src0_m, (v16i8)src4_m); \ vec7_m = (v16u8)__msa_ilvl_b((v16i8)src1_m, (v16i8)src5_m); \ vec8_m = (v16u8)__msa_ilvl_b((v16i8)src2_m, (v16i8)src6_m); \ vec9_m = (v16u8)__msa_ilvl_b((v16i8)src3_m, (v16i8)src7_m); \ reg0_m = __msa_hadd_u_h(vec2_m, vec2_m); \ reg1_m = __msa_hadd_u_h(vec3_m, vec3_m); \ reg2_m = __msa_hadd_u_h(vec4_m, vec4_m); \ reg3_m = __msa_hadd_u_h(vec5_m, vec5_m); \ reg4_m = __msa_hadd_u_h(vec6_m, vec6_m); \ reg5_m = __msa_hadd_u_h(vec7_m, vec7_m); \ reg6_m = __msa_hadd_u_h(vec8_m, vec8_m); \ reg7_m = __msa_hadd_u_h(vec9_m, vec9_m); \ reg8_m = (v8u16)__msa_pckev_d((v2i64)reg4_m, (v2i64)reg0_m); \ reg9_m = (v8u16)__msa_pckev_d((v2i64)reg5_m, (v2i64)reg1_m); \ reg8_m += (v8u16)__msa_pckod_d((v2i64)reg4_m, (v2i64)reg0_m); \ reg9_m += (v8u16)__msa_pckod_d((v2i64)reg5_m, (v2i64)reg1_m); \ reg0_m = (v8u16)__msa_pckev_d((v2i64)reg6_m, (v2i64)reg2_m); \ reg1_m = (v8u16)__msa_pckev_d((v2i64)reg7_m, (v2i64)reg3_m); \ reg0_m += (v8u16)__msa_pckod_d((v2i64)reg6_m, (v2i64)reg2_m); \ reg1_m += (v8u16)__msa_pckod_d((v2i64)reg7_m, (v2i64)reg3_m); \ reg8_m = (v8u16)__msa_srai_h((v8i16)reg8_m, 2); \ reg9_m = (v8u16)__msa_srai_h((v8i16)reg9_m, 2); \ reg0_m = (v8u16)__msa_srai_h((v8i16)reg0_m, 2); \ reg1_m = (v8u16)__msa_srai_h((v8i16)reg1_m, 2); \ argb2 = (v16u8)__msa_pckev_b((v16i8)reg9_m, (v16i8)reg8_m); \ argb3 = (v16u8)__msa_pckev_b((v16i8)reg1_m, (v16i8)reg0_m); \ } // Takes ARGB input and calculates U and V.#define ARGBTOUV(argb0, argb1, argb2, argb3, const0, const1, const2, const3, \ shf0, shf1, shf2, shf3, v_out, u_out) \ { \ v16u8 vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ v8u16 reg0_m, reg1_m, reg2_m, reg3_m; \ \ vec0_m = (v16u8)__msa_vshf_b(shf0, (v16i8)argb1, (v16i8)argb0); \ vec1_m = (v16u8)__msa_vshf_b(shf0, (v16i8)argb3, (v16i8)argb2); \ vec2_m = (v16u8)__msa_vshf_b(shf1, (v16i8)argb1, (v16i8)argb0); \ vec3_m = (v16u8)__msa_vshf_b(shf1, (v16i8)argb3, (v16i8)argb2); \ vec4_m = (v16u8)__msa_vshf_b(shf2, (v16i8)argb1, (v16i8)argb0); \ vec5_m = (v16u8)__msa_vshf_b(shf2, (v16i8)argb3, (v16i8)argb2); \ vec6_m = (v16u8)__msa_vshf_b(shf3, (v16i8)argb1, (v16i8)argb0); \ vec7_m = (v16u8)__msa_vshf_b(shf3, (v16i8)argb3, (v16i8)argb2); \ reg0_m = __msa_dotp_u_h(vec0_m, const1); \ reg1_m = __msa_dotp_u_h(vec1_m, const1); \ reg2_m = __msa_dotp_u_h(vec4_m, const1); \ reg3_m = __msa_dotp_u_h(vec5_m, const1); \ reg0_m += const3; \ reg1_m += const3; \ reg2_m += const3; \ reg3_m += const3; \ reg0_m -= __msa_dotp_u_h(vec2_m, const0); \ reg1_m -= __msa_dotp_u_h(vec3_m, const0); \ reg2_m -= __msa_dotp_u_h(vec6_m, const2); \ reg3_m -= __msa_dotp_u_h(vec7_m, const2); \ v_out = (v16u8)__msa_pckod_b((v16i8)reg1_m, (v16i8)reg0_m); \ u_out = (v16u8)__msa_pckod_b((v16i8)reg3_m, (v16i8)reg2_m); \ } // Load I444 pixel data#define READI444(psrc_y, psrc_u, psrc_v, out_y, out_u, out_v) \ { \ uint64_t y_m, u_m, v_m; \ v2i64 zero_m = {0}; \ y_m = LD(psrc_y); \ u_m = LD(psrc_u); \ v_m = LD(psrc_v); \ out_y = (v16u8)__msa_insert_d(zero_m, 0, (int64_t)y_m); \ out_u = (v16u8)__msa_insert_d(zero_m, 0, (int64_t)u_m); \ out_v = (v16u8)__msa_insert_d(zero_m, 0, (int64_t)v_m); \ } void MirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width) { int x; v16u8 src0, src1, src2, src3; v16u8 dst0, dst1, dst2, dst3; v16i8 shuffler = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; src += width - 64; for (x = 0; x < width; x += 64) { LD_UB4(src, 16, src3, src2, src1, src0); VSHF_B2_UB(src3, src3, src2, src2, shuffler, shuffler, dst3, dst2); VSHF_B2_UB(src1, src1, src0, src0, shuffler, shuffler, dst1, dst0); ST_UB4(dst0, dst1, dst2, dst3, dst, 16); dst += 64; src -= 64; }} void ARGBMirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width) { int x; v16u8 src0, src1, src2, src3; v16u8 dst0, dst1, dst2, dst3; v16i8 shuffler = {12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3}; src += width * 4 - 64; for (x = 0; x < width; x += 16) { LD_UB4(src, 16, src3, src2, src1, src0); VSHF_B2_UB(src3, src3, src2, src2, shuffler, shuffler, dst3, dst2); VSHF_B2_UB(src1, src1, src0, src0, shuffler, shuffler, dst1, dst0); ST_UB4(dst0, dst1, dst2, dst3, dst, 16); dst += 64; src -= 64; }} void I422ToYUY2Row_MSA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, uint8_t* dst_yuy2, int width) { int x; v16u8 src_u0, src_v0, src_y0, src_y1, vec_uv0, vec_uv1; v16u8 dst_yuy2_0, dst_yuy2_1, dst_yuy2_2, dst_yuy2_3; for (x = 0; x < width; x += 32) { src_u0 = LD_UB(src_u); src_v0 = LD_UB(src_v); LD_UB2(src_y, 16, src_y0, src_y1); ILVRL_B2_UB(src_v0, src_u0, vec_uv0, vec_uv1); ILVRL_B2_UB(vec_uv0, src_y0, dst_yuy2_0, dst_yuy2_1); ILVRL_B2_UB(vec_uv1, src_y1, dst_yuy2_2, dst_yuy2_3); ST_UB4(dst_yuy2_0, dst_yuy2_1, dst_yuy2_2, dst_yuy2_3, dst_yuy2, 16); src_u += 16; src_v += 16; src_y += 32; dst_yuy2 += 64; }} void I422ToUYVYRow_MSA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, uint8_t* dst_uyvy, int width) { int x; v16u8 src_u0, src_v0, src_y0, src_y1, vec_uv0, vec_uv1; v16u8 dst_uyvy0, dst_uyvy1, dst_uyvy2, dst_uyvy3; for (x = 0; x < width; x += 32) { src_u0 = LD_UB(src_u); src_v0 = LD_UB(src_v); LD_UB2(src_y, 16, src_y0, src_y1); ILVRL_B2_UB(src_v0, src_u0, vec_uv0, vec_uv1); ILVRL_B2_UB(src_y0, vec_uv0, dst_uyvy0, dst_uyvy1); ILVRL_B2_UB(src_y1, vec_uv1, dst_uyvy2, dst_uyvy3); ST_UB4(dst_uyvy0, dst_uyvy1, dst_uyvy2, dst_uyvy3, dst_uyvy, 16); src_u += 16; src_v += 16; src_y += 32; dst_uyvy += 64; }} void I422ToARGBRow_MSA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, uint8_t* dst_argb, const struct YuvConstants* yuvconstants, int width) { int x; v16u8 src0, src1, src2; v8i16 vec0, vec1, vec2; v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; v4i32 vec_ubvr, vec_ugvg; v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg); vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); for (x = 0; x < width; x += 8) { READYUV422(src_y, src_u, src_v, src0, src1, src2); src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, vec0, vec1, vec2); STOREARGB(vec0, vec1, vec2, alpha, dst_argb); src_y += 8; src_u += 4; src_v += 4; dst_argb += 32; }} void I422ToRGBARow_MSA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, uint8_t* dst_argb, const struct YuvConstants* yuvconstants, int width) { int x; v16u8 src0, src1, src2; v8i16 vec0, vec1, vec2; v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; v4i32 vec_ubvr, vec_ugvg; v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg); vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); for (x = 0; x < width; x += 8) { READYUV422(src_y, src_u, src_v, src0, src1, src2); src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, vec0, vec1, vec2); STOREARGB(alpha, vec0, vec1, vec2, dst_argb); src_y += 8; src_u += 4; src_v += 4; dst_argb += 32; }} void I422AlphaToARGBRow_MSA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, const uint8_t* src_a, uint8_t* dst_argb, const struct YuvConstants* yuvconstants, int width) { int x; int64_t data_a; v16u8 src0, src1, src2, src3; v8i16 vec0, vec1, vec2; v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; v4i32 vec_ubvr, vec_ugvg; v4i32 zero = {0}; YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg); vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); for (x = 0; x < width; x += 8) { data_a = LD(src_a); READYUV422(src_y, src_u, src_v, src0, src1, src2); src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); src3 = (v16u8)__msa_insert_d((v2i64)zero, 0, data_a); YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, vec0, vec1, vec2); src3 = (v16u8)__msa_ilvr_b((v16i8)src3, (v16i8)src3); STOREARGB(vec0, vec1, vec2, src3, dst_argb); src_y += 8; src_u += 4; src_v += 4; src_a += 8; dst_argb += 32; }} void I422ToRGB24Row_MSA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, uint8_t* dst_argb, const struct YuvConstants* yuvconstants, int32_t width) { int x; int64_t data_u, data_v; v16u8 src0, src1, src2, src3, src4, dst0, dst1, dst2; v8i16 vec0, vec1, vec2, vec3, vec4, vec5; v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; v4i32 vec_ubvr, vec_ugvg; v16u8 reg0, reg1, reg2, reg3; v2i64 zero = {0}; v16i8 shuffler0 = {0, 1, 16, 2, 3, 17, 4, 5, 18, 6, 7, 19, 8, 9, 20, 10}; v16i8 shuffler1 = {0, 21, 1, 2, 22, 3, 4, 23, 5, 6, 24, 7, 8, 25, 9, 10}; v16i8 shuffler2 = {26, 6, 7, 27, 8, 9, 28, 10, 11, 29, 12, 13, 30, 14, 15, 31}; YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg); vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); for (x = 0; x < width; x += 16) { src0 = (v16u8)__msa_ld_b((v16u8*)src_y, 0); data_u = LD(src_u); data_v = LD(src_v); src1 = (v16u8)__msa_insert_d(zero, 0, data_u); src2 = (v16u8)__msa_insert_d(zero, 0, data_v); src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); src3 = (v16u8)__msa_sldi_b((v16i8)src0, (v16i8)src0, 8);Lines 1–500 of 3512. Load more
/* * Copyright 2016 The LibYuv Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include <string.h> #include "libyuv/row.h" // This module is for GCC MSA #if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) #include "libyuv/macros_msa.h" #ifdef __cplusplus namespace libyuv { extern "C" { #endif #define ALPHA_VAL (-1) // Fill YUV -> RGB conversion constants into vectors #define YUVTORGB_SETUP(yuvconst, ub, vr, ug, vg, bb, bg, br, yg) \ { \ ub = __msa_fill_w(yuvconst->kUVToB[0]); \ vr = __msa_fill_w(yuvconst->kUVToR[1]); \ ug = __msa_fill_w(yuvconst->kUVToG[0]); \ vg = __msa_fill_w(yuvconst->kUVToG[1]); \ bb = __msa_fill_w(yuvconst->kUVBiasB[0]); \ bg = __msa_fill_w(yuvconst->kUVBiasG[0]); \ br = __msa_fill_w(yuvconst->kUVBiasR[0]); \ yg = __msa_fill_w(yuvconst->kYToRgb[0]); \ } // Load YUV 422 pixel data #define READYUV422(psrc_y, psrc_u, psrc_v, out_y, out_u, out_v) \ { \ uint64_t y_m; \ uint32_t u_m, v_m; \ v4i32 zero_m = {0}; \ y_m = LD(psrc_y); \ u_m = LW(psrc_u); \ v_m = LW(psrc_v); \ out_y = (v16u8)__msa_insert_d((v2i64)zero_m, 0, (int64_t)y_m); \ out_u = (v16u8)__msa_insert_w(zero_m, 0, (int32_t)u_m); \ out_v = (v16u8)__msa_insert_w(zero_m, 0, (int32_t)v_m); \ } // Clip input vector elements between 0 to 255 #define CLIP_0TO255(in0, in1, in2, in3, in4, in5) \ { \ v4i32 max_m = __msa_ldi_w(0xFF); \ \ in0 = __msa_maxi_s_w(in0, 0); \ in1 = __msa_maxi_s_w(in1, 0); \ in2 = __msa_maxi_s_w(in2, 0); \ in3 = __msa_maxi_s_w(in3, 0); \ in4 = __msa_maxi_s_w(in4, 0); \ in5 = __msa_maxi_s_w(in5, 0); \ in0 = __msa_min_s_w(max_m, in0); \ in1 = __msa_min_s_w(max_m, in1); \ in2 = __msa_min_s_w(max_m, in2); \ in3 = __msa_min_s_w(max_m, in3); \ in4 = __msa_min_s_w(max_m, in4); \ in5 = __msa_min_s_w(max_m, in5); \ } // Convert 8 pixels of YUV 420 to RGB. #define YUVTORGB(in_y, in_uv, ubvr, ugvg, bb, bg, br, yg, out_b, out_g, out_r) \ { \ v8i16 vec0_m, vec1_m; \ v4i32 reg0_m, reg1_m, reg2_m, reg3_m, reg4_m; \ v4i32 reg5_m, reg6_m, reg7_m; \ v16i8 zero_m = {0}; \ \ vec0_m = (v8i16)__msa_ilvr_b((v16i8)in_y, (v16i8)in_y); \ vec1_m = (v8i16)__msa_ilvr_b((v16i8)zero_m, (v16i8)in_uv); \ reg0_m = (v4i32)__msa_ilvr_h((v8i16)zero_m, (v8i16)vec0_m); \ reg1_m = (v4i32)__msa_ilvl_h((v8i16)zero_m, (v8i16)vec0_m); \ reg2_m = (v4i32)__msa_ilvr_h((v8i16)zero_m, (v8i16)vec1_m); \ reg3_m = (v4i32)__msa_ilvl_h((v8i16)zero_m, (v8i16)vec1_m); \ reg0_m *= yg; \ reg1_m *= yg; \ reg2_m *= ubvr; \ reg3_m *= ubvr; \ reg0_m = __msa_srai_w(reg0_m, 16); \ reg1_m = __msa_srai_w(reg1_m, 16); \ reg4_m = __msa_dotp_s_w((v8i16)vec1_m, (v8i16)ugvg); \ reg5_m = __msa_ilvev_w(reg2_m, reg2_m); \ reg6_m = __msa_ilvev_w(reg3_m, reg3_m); \ reg7_m = __msa_ilvr_w(reg4_m, reg4_m); \ reg2_m = __msa_ilvod_w(reg2_m, reg2_m); \ reg3_m = __msa_ilvod_w(reg3_m, reg3_m); \ reg4_m = __msa_ilvl_w(reg4_m, reg4_m); \ reg5_m = reg0_m - reg5_m; \ reg6_m = reg1_m - reg6_m; \ reg2_m = reg0_m - reg2_m; \ reg3_m = reg1_m - reg3_m; \ reg7_m = reg0_m - reg7_m; \ reg4_m = reg1_m - reg4_m; \ reg5_m += bb; \ reg6_m += bb; \ reg7_m += bg; \ reg4_m += bg; \ reg2_m += br; \ reg3_m += br; \ reg5_m = __msa_srai_w(reg5_m, 6); \ reg6_m = __msa_srai_w(reg6_m, 6); \ reg7_m = __msa_srai_w(reg7_m, 6); \ reg4_m = __msa_srai_w(reg4_m, 6); \ reg2_m = __msa_srai_w(reg2_m, 6); \ reg3_m = __msa_srai_w(reg3_m, 6); \ CLIP_0TO255(reg5_m, reg6_m, reg7_m, reg4_m, reg2_m, reg3_m); \ out_b = __msa_pckev_h((v8i16)reg6_m, (v8i16)reg5_m); \ out_g = __msa_pckev_h((v8i16)reg4_m, (v8i16)reg7_m); \ out_r = __msa_pckev_h((v8i16)reg3_m, (v8i16)reg2_m); \ } // Pack and Store 8 ARGB values. #define STOREARGB(in0, in1, in2, in3, pdst_argb) \ { \ v8i16 vec0_m, vec1_m; \ v16u8 dst0_m, dst1_m; \ vec0_m = (v8i16)__msa_ilvev_b((v16i8)in1, (v16i8)in0); \ vec1_m = (v8i16)__msa_ilvev_b((v16i8)in3, (v16i8)in2); \ dst0_m = (v16u8)__msa_ilvr_h(vec1_m, vec0_m); \ dst1_m = (v16u8)__msa_ilvl_h(vec1_m, vec0_m); \ ST_UB2(dst0_m, dst1_m, pdst_argb, 16); \ } // Takes ARGB input and calculates Y. #define ARGBTOY(argb0, argb1, argb2, argb3, const0, const1, const2, shift, \ y_out) \ { \ v16u8 vec0_m, vec1_m, vec2_m, vec3_m; \ v8u16 reg0_m, reg1_m; \ \ vec0_m = (v16u8)__msa_pckev_h((v8i16)argb1, (v8i16)argb0); \ vec1_m = (v16u8)__msa_pckev_h((v8i16)argb3, (v8i16)argb2); \ vec2_m = (v16u8)__msa_pckod_h((v8i16)argb1, (v8i16)argb0); \ vec3_m = (v16u8)__msa_pckod_h((v8i16)argb3, (v8i16)argb2); \ reg0_m = __msa_dotp_u_h(vec0_m, const0); \ reg1_m = __msa_dotp_u_h(vec1_m, const0); \ reg0_m = __msa_dpadd_u_h(reg0_m, vec2_m, const1); \ reg1_m = __msa_dpadd_u_h(reg1_m, vec3_m, const1); \ reg0_m += const2; \ reg1_m += const2; \ reg0_m = (v8u16)__msa_srai_h((v8i16)reg0_m, shift); \ reg1_m = (v8u16)__msa_srai_h((v8i16)reg1_m, shift); \ y_out = (v16u8)__msa_pckev_b((v16i8)reg1_m, (v16i8)reg0_m); \ } // Loads current and next row of ARGB input and averages it to calculate U and V #define READ_ARGB(s_ptr, t_ptr, argb0, argb1, argb2, argb3) \ { \ v16u8 src0_m, src1_m, src2_m, src3_m, src4_m, src5_m, src6_m, src7_m; \ v16u8 vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ v16u8 vec8_m, vec9_m; \ v8u16 reg0_m, reg1_m, reg2_m, reg3_m, reg4_m, reg5_m, reg6_m, reg7_m; \ v8u16 reg8_m, reg9_m; \ \ src0_m = (v16u8)__msa_ld_b((v16i8*)s, 0); \ src1_m = (v16u8)__msa_ld_b((v16i8*)s, 16); \ src2_m = (v16u8)__msa_ld_b((v16i8*)s, 32); \ src3_m = (v16u8)__msa_ld_b((v16i8*)s, 48); \ src4_m = (v16u8)__msa_ld_b((v16i8*)t, 0); \ src5_m = (v16u8)__msa_ld_b((v16i8*)t, 16); \ src6_m = (v16u8)__msa_ld_b((v16i8*)t, 32); \ src7_m = (v16u8)__msa_ld_b((v16i8*)t, 48); \ vec0_m = (v16u8)__msa_ilvr_b((v16i8)src0_m, (v16i8)src4_m); \ vec1_m = (v16u8)__msa_ilvr_b((v16i8)src1_m, (v16i8)src5_m); \ vec2_m = (v16u8)__msa_ilvr_b((v16i8)src2_m, (v16i8)src6_m); \ vec3_m = (v16u8)__msa_ilvr_b((v16i8)src3_m, (v16i8)src7_m); \ vec4_m = (v16u8)__msa_ilvl_b((v16i8)src0_m, (v16i8)src4_m); \ vec5_m = (v16u8)__msa_ilvl_b((v16i8)src1_m, (v16i8)src5_m); \ vec6_m = (v16u8)__msa_ilvl_b((v16i8)src2_m, (v16i8)src6_m); \ vec7_m = (v16u8)__msa_ilvl_b((v16i8)src3_m, (v16i8)src7_m); \ reg0_m = __msa_hadd_u_h(vec0_m, vec0_m); \ reg1_m = __msa_hadd_u_h(vec1_m, vec1_m); \ reg2_m = __msa_hadd_u_h(vec2_m, vec2_m); \ reg3_m = __msa_hadd_u_h(vec3_m, vec3_m); \ reg4_m = __msa_hadd_u_h(vec4_m, vec4_m); \ reg5_m = __msa_hadd_u_h(vec5_m, vec5_m); \ reg6_m = __msa_hadd_u_h(vec6_m, vec6_m); \ reg7_m = __msa_hadd_u_h(vec7_m, vec7_m); \ reg8_m = (v8u16)__msa_pckev_d((v2i64)reg4_m, (v2i64)reg0_m); \ reg9_m = (v8u16)__msa_pckev_d((v2i64)reg5_m, (v2i64)reg1_m); \ reg8_m += (v8u16)__msa_pckod_d((v2i64)reg4_m, (v2i64)reg0_m); \ reg9_m += (v8u16)__msa_pckod_d((v2i64)reg5_m, (v2i64)reg1_m); \ reg0_m = (v8u16)__msa_pckev_d((v2i64)reg6_m, (v2i64)reg2_m); \ reg1_m = (v8u16)__msa_pckev_d((v2i64)reg7_m, (v2i64)reg3_m); \ reg0_m += (v8u16)__msa_pckod_d((v2i64)reg6_m, (v2i64)reg2_m); \ reg1_m += (v8u16)__msa_pckod_d((v2i64)reg7_m, (v2i64)reg3_m); \ reg8_m = (v8u16)__msa_srai_h((v8i16)reg8_m, 2); \ reg9_m = (v8u16)__msa_srai_h((v8i16)reg9_m, 2); \ reg0_m = (v8u16)__msa_srai_h((v8i16)reg0_m, 2); \ reg1_m = (v8u16)__msa_srai_h((v8i16)reg1_m, 2); \ argb0 = (v16u8)__msa_pckev_b((v16i8)reg9_m, (v16i8)reg8_m); \ argb1 = (v16u8)__msa_pckev_b((v16i8)reg1_m, (v16i8)reg0_m); \ src0_m = (v16u8)__msa_ld_b((v16i8*)s, 64); \ src1_m = (v16u8)__msa_ld_b((v16i8*)s, 80); \ src2_m = (v16u8)__msa_ld_b((v16i8*)s, 96); \ src3_m = (v16u8)__msa_ld_b((v16i8*)s, 112); \ src4_m = (v16u8)__msa_ld_b((v16i8*)t, 64); \ src5_m = (v16u8)__msa_ld_b((v16i8*)t, 80); \ src6_m = (v16u8)__msa_ld_b((v16i8*)t, 96); \ src7_m = (v16u8)__msa_ld_b((v16i8*)t, 112); \ vec2_m = (v16u8)__msa_ilvr_b((v16i8)src0_m, (v16i8)src4_m); \ vec3_m = (v16u8)__msa_ilvr_b((v16i8)src1_m, (v16i8)src5_m); \ vec4_m = (v16u8)__msa_ilvr_b((v16i8)src2_m, (v16i8)src6_m); \ vec5_m = (v16u8)__msa_ilvr_b((v16i8)src3_m, (v16i8)src7_m); \ vec6_m = (v16u8)__msa_ilvl_b((v16i8)src0_m, (v16i8)src4_m); \ vec7_m = (v16u8)__msa_ilvl_b((v16i8)src1_m, (v16i8)src5_m); \ vec8_m = (v16u8)__msa_ilvl_b((v16i8)src2_m, (v16i8)src6_m); \ vec9_m = (v16u8)__msa_ilvl_b((v16i8)src3_m, (v16i8)src7_m); \ reg0_m = __msa_hadd_u_h(vec2_m, vec2_m); \ reg1_m = __msa_hadd_u_h(vec3_m, vec3_m); \ reg2_m = __msa_hadd_u_h(vec4_m, vec4_m); \ reg3_m = __msa_hadd_u_h(vec5_m, vec5_m); \ reg4_m = __msa_hadd_u_h(vec6_m, vec6_m); \ reg5_m = __msa_hadd_u_h(vec7_m, vec7_m); \ reg6_m = __msa_hadd_u_h(vec8_m, vec8_m); \ reg7_m = __msa_hadd_u_h(vec9_m, vec9_m); \ reg8_m = (v8u16)__msa_pckev_d((v2i64)reg4_m, (v2i64)reg0_m); \ reg9_m = (v8u16)__msa_pckev_d((v2i64)reg5_m, (v2i64)reg1_m); \ reg8_m += (v8u16)__msa_pckod_d((v2i64)reg4_m, (v2i64)reg0_m); \ reg9_m += (v8u16)__msa_pckod_d((v2i64)reg5_m, (v2i64)reg1_m); \ reg0_m = (v8u16)__msa_pckev_d((v2i64)reg6_m, (v2i64)reg2_m); \ reg1_m = (v8u16)__msa_pckev_d((v2i64)reg7_m, (v2i64)reg3_m); \ reg0_m += (v8u16)__msa_pckod_d((v2i64)reg6_m, (v2i64)reg2_m); \ reg1_m += (v8u16)__msa_pckod_d((v2i64)reg7_m, (v2i64)reg3_m); \ reg8_m = (v8u16)__msa_srai_h((v8i16)reg8_m, 2); \ reg9_m = (v8u16)__msa_srai_h((v8i16)reg9_m, 2); \ reg0_m = (v8u16)__msa_srai_h((v8i16)reg0_m, 2); \ reg1_m = (v8u16)__msa_srai_h((v8i16)reg1_m, 2); \ argb2 = (v16u8)__msa_pckev_b((v16i8)reg9_m, (v16i8)reg8_m); \ argb3 = (v16u8)__msa_pckev_b((v16i8)reg1_m, (v16i8)reg0_m); \ } // Takes ARGB input and calculates U and V. #define ARGBTOUV(argb0, argb1, argb2, argb3, const0, const1, const2, const3, \ shf0, shf1, shf2, shf3, v_out, u_out) \ { \ v16u8 vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ v8u16 reg0_m, reg1_m, reg2_m, reg3_m; \ \ vec0_m = (v16u8)__msa_vshf_b(shf0, (v16i8)argb1, (v16i8)argb0); \ vec1_m = (v16u8)__msa_vshf_b(shf0, (v16i8)argb3, (v16i8)argb2); \ vec2_m = (v16u8)__msa_vshf_b(shf1, (v16i8)argb1, (v16i8)argb0); \ vec3_m = (v16u8)__msa_vshf_b(shf1, (v16i8)argb3, (v16i8)argb2); \ vec4_m = (v16u8)__msa_vshf_b(shf2, (v16i8)argb1, (v16i8)argb0); \ vec5_m = (v16u8)__msa_vshf_b(shf2, (v16i8)argb3, (v16i8)argb2); \ vec6_m = (v16u8)__msa_vshf_b(shf3, (v16i8)argb1, (v16i8)argb0); \ vec7_m = (v16u8)__msa_vshf_b(shf3, (v16i8)argb3, (v16i8)argb2); \ reg0_m = __msa_dotp_u_h(vec0_m, const1); \ reg1_m = __msa_dotp_u_h(vec1_m, const1); \ reg2_m = __msa_dotp_u_h(vec4_m, const1); \ reg3_m = __msa_dotp_u_h(vec5_m, const1); \ reg0_m += const3; \ reg1_m += const3; \ reg2_m += const3; \ reg3_m += const3; \ reg0_m -= __msa_dotp_u_h(vec2_m, const0); \ reg1_m -= __msa_dotp_u_h(vec3_m, const0); \ reg2_m -= __msa_dotp_u_h(vec6_m, const2); \ reg3_m -= __msa_dotp_u_h(vec7_m, const2); \ v_out = (v16u8)__msa_pckod_b((v16i8)reg1_m, (v16i8)reg0_m); \ u_out = (v16u8)__msa_pckod_b((v16i8)reg3_m, (v16i8)reg2_m); \ } // Load I444 pixel data #define READI444(psrc_y, psrc_u, psrc_v, out_y, out_u, out_v) \ { \ uint64_t y_m, u_m, v_m; \ v2i64 zero_m = {0}; \ y_m = LD(psrc_y); \ u_m = LD(psrc_u); \ v_m = LD(psrc_v); \ out_y = (v16u8)__msa_insert_d(zero_m, 0, (int64_t)y_m); \ out_u = (v16u8)__msa_insert_d(zero_m, 0, (int64_t)u_m); \ out_v = (v16u8)__msa_insert_d(zero_m, 0, (int64_t)v_m); \ } void MirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width) { int x; v16u8 src0, src1, src2, src3; v16u8 dst0, dst1, dst2, dst3; v16i8 shuffler = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; src += width - 64; for (x = 0; x < width; x += 64) { LD_UB4(src, 16, src3, src2, src1, src0); VSHF_B2_UB(src3, src3, src2, src2, shuffler, shuffler, dst3, dst2); VSHF_B2_UB(src1, src1, src0, src0, shuffler, shuffler, dst1, dst0); ST_UB4(dst0, dst1, dst2, dst3, dst, 16); dst += 64; src -= 64; } } void ARGBMirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width) { int x; v16u8 src0, src1, src2, src3; v16u8 dst0, dst1, dst2, dst3; v16i8 shuffler = {12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3}; src += width * 4 - 64; for (x = 0; x < width; x += 16) { LD_UB4(src, 16, src3, src2, src1, src0); VSHF_B2_UB(src3, src3, src2, src2, shuffler, shuffler, dst3, dst2); VSHF_B2_UB(src1, src1, src0, src0, shuffler, shuffler, dst1, dst0); ST_UB4(dst0, dst1, dst2, dst3, dst, 16); dst += 64; src -= 64; } } void I422ToYUY2Row_MSA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, uint8_t* dst_yuy2, int width) { int x; v16u8 src_u0, src_v0, src_y0, src_y1, vec_uv0, vec_uv1; v16u8 dst_yuy2_0, dst_yuy2_1, dst_yuy2_2, dst_yuy2_3; for (x = 0; x < width; x += 32) { src_u0 = LD_UB(src_u); src_v0 = LD_UB(src_v); LD_UB2(src_y, 16, src_y0, src_y1); ILVRL_B2_UB(src_v0, src_u0, vec_uv0, vec_uv1); ILVRL_B2_UB(vec_uv0, src_y0, dst_yuy2_0, dst_yuy2_1); ILVRL_B2_UB(vec_uv1, src_y1, dst_yuy2_2, dst_yuy2_3); ST_UB4(dst_yuy2_0, dst_yuy2_1, dst_yuy2_2, dst_yuy2_3, dst_yuy2, 16); src_u += 16; src_v += 16; src_y += 32; dst_yuy2 += 64; } } void I422ToUYVYRow_MSA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, uint8_t* dst_uyvy, int width) { int x; v16u8 src_u0, src_v0, src_y0, src_y1, vec_uv0, vec_uv1; v16u8 dst_uyvy0, dst_uyvy1, dst_uyvy2, dst_uyvy3; for (x = 0; x < width; x += 32) { src_u0 = LD_UB(src_u); src_v0 = LD_UB(src_v); LD_UB2(src_y, 16, src_y0, src_y1); ILVRL_B2_UB(src_v0, src_u0, vec_uv0, vec_uv1); ILVRL_B2_UB(src_y0, vec_uv0, dst_uyvy0, dst_uyvy1); ILVRL_B2_UB(src_y1, vec_uv1, dst_uyvy2, dst_uyvy3); ST_UB4(dst_uyvy0, dst_uyvy1, dst_uyvy2, dst_uyvy3, dst_uyvy, 16); src_u += 16; src_v += 16; src_y += 32; dst_uyvy += 64; } } void I422ToARGBRow_MSA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, uint8_t* dst_argb, const struct YuvConstants* yuvconstants, int width) { int x; v16u8 src0, src1, src2; v8i16 vec0, vec1, vec2; v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; v4i32 vec_ubvr, vec_ugvg; v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg); vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); for (x = 0; x < width; x += 8) { READYUV422(src_y, src_u, src_v, src0, src1, src2); src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, vec0, vec1, vec2); STOREARGB(vec0, vec1, vec2, alpha, dst_argb); src_y += 8; src_u += 4; src_v += 4; dst_argb += 32; } } void I422ToRGBARow_MSA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, uint8_t* dst_argb, const struct YuvConstants* yuvconstants, int width) { int x; v16u8 src0, src1, src2; v8i16 vec0, vec1, vec2; v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; v4i32 vec_ubvr, vec_ugvg; v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg); vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); for (x = 0; x < width; x += 8) { READYUV422(src_y, src_u, src_v, src0, src1, src2); src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, vec0, vec1, vec2); STOREARGB(alpha, vec0, vec1, vec2, dst_argb); src_y += 8; src_u += 4; src_v += 4; dst_argb += 32; } } void I422AlphaToARGBRow_MSA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, const uint8_t* src_a, uint8_t* dst_argb, const struct YuvConstants* yuvconstants, int width) { int x; int64_t data_a; v16u8 src0, src1, src2, src3; v8i16 vec0, vec1, vec2; v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; v4i32 vec_ubvr, vec_ugvg; v4i32 zero = {0}; YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg); vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); for (x = 0; x < width; x += 8) { data_a = LD(src_a); READYUV422(src_y, src_u, src_v, src0, src1, src2); src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); src3 = (v16u8)__msa_insert_d((v2i64)zero, 0, data_a); YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, vec0, vec1, vec2); src3 = (v16u8)__msa_ilvr_b((v16i8)src3, (v16i8)src3); STOREARGB(vec0, vec1, vec2, src3, dst_argb); src_y += 8; src_u += 4; src_v += 4; src_a += 8; dst_argb += 32; } } void I422ToRGB24Row_MSA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, uint8_t* dst_argb, const struct YuvConstants* yuvconstants, int32_t width) { int x; int64_t data_u, data_v; v16u8 src0, src1, src2, src3, src4, dst0, dst1, dst2; v8i16 vec0, vec1, vec2, vec3, vec4, vec5; v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; v4i32 vec_ubvr, vec_ugvg; v16u8 reg0, reg1, reg2, reg3; v2i64 zero = {0}; v16i8 shuffler0 = {0, 1, 16, 2, 3, 17, 4, 5, 18, 6, 7, 19, 8, 9, 20, 10}; v16i8 shuffler1 = {0, 21, 1, 2, 22, 3, 4, 23, 5, 6, 24, 7, 8, 25, 9, 10}; v16i8 shuffler2 = {26, 6, 7, 27, 8, 9, 28, 10, 11, 29, 12, 13, 30, 14, 15, 31}; YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg); vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); for (x = 0; x < width; x += 16) { src0 = (v16u8)__msa_ld_b((v16u8*)src_y, 0); data_u = LD(src_u); data_v = LD(src_v); src1 = (v16u8)__msa_insert_d(zero, 0, data_u); src2 = (v16u8)__msa_insert_d(zero, 0, data_v); src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); src3 = (v16u8)__msa_sldi_b((v16i8)src0, (v16i8)src0, 8);