1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2016 Matthieu Bouron <matthieu.bouron stupeflix.com> 3cabdff1aSopenharmony_ci * Copyright (c) 2016 Clément Bœsch <clement stupeflix.com> 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include "libavutil/aarch64/asm.S" 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci.macro load_yoff_ycoeff yoff ycoeff 25cabdff1aSopenharmony_ci#if defined(__APPLE__) 26cabdff1aSopenharmony_ci ldp w9, w10, [sp, #\yoff] 27cabdff1aSopenharmony_ci#else 28cabdff1aSopenharmony_ci ldr w9, [sp, #\yoff] 29cabdff1aSopenharmony_ci ldr w10, [sp, #\ycoeff] 30cabdff1aSopenharmony_ci#endif 31cabdff1aSopenharmony_ci.endm 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci.macro load_args_nv12 34cabdff1aSopenharmony_ci ldr x8, [sp] // table 35cabdff1aSopenharmony_ci load_yoff_ycoeff 8, 16 // y_offset, y_coeff 36cabdff1aSopenharmony_ci ld1 {v1.1D}, [x8] 37cabdff1aSopenharmony_ci dup v0.8H, w10 38cabdff1aSopenharmony_ci dup v3.8H, w9 39cabdff1aSopenharmony_ci sub w3, w3, w0, lsl #2 // w3 = linesize - width * 4 (padding) 40cabdff1aSopenharmony_ci sub w5, w5, w0 // w5 = linesizeY - width (paddingY) 41cabdff1aSopenharmony_ci sub w7, w7, w0 // w7 = linesizeC - width (paddingC) 42cabdff1aSopenharmony_ci neg w11, w0 43cabdff1aSopenharmony_ci.endm 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci.macro load_args_nv21 46cabdff1aSopenharmony_ci load_args_nv12 47cabdff1aSopenharmony_ci.endm 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_ci.macro load_args_yuv420p 50cabdff1aSopenharmony_ci ldr x13, [sp] // srcV 51cabdff1aSopenharmony_ci ldr w14, [sp, #8] // linesizeV 52cabdff1aSopenharmony_ci ldr x8, [sp, #16] // table 53cabdff1aSopenharmony_ci load_yoff_ycoeff 24, 32 // y_offset, y_coeff 54cabdff1aSopenharmony_ci ld1 {v1.1D}, [x8] 55cabdff1aSopenharmony_ci dup v0.8H, w10 56cabdff1aSopenharmony_ci dup v3.8H, w9 57cabdff1aSopenharmony_ci sub w3, w3, w0, lsl #2 // w3 = linesize - width * 4 (padding) 58cabdff1aSopenharmony_ci sub w5, w5, w0 // w5 = linesizeY - width (paddingY) 59cabdff1aSopenharmony_ci sub w7, w7, w0, lsr #1 // w7 = linesizeU - width / 2 (paddingU) 60cabdff1aSopenharmony_ci sub w14, w14, w0, lsr #1 // w14 = linesizeV - width / 2 (paddingV) 61cabdff1aSopenharmony_ci lsr w11, w0, #1 62cabdff1aSopenharmony_ci neg w11, w11 63cabdff1aSopenharmony_ci.endm 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_ci.macro load_args_yuv422p 66cabdff1aSopenharmony_ci ldr x13, [sp] // srcV 67cabdff1aSopenharmony_ci ldr w14, [sp, #8] // linesizeV 68cabdff1aSopenharmony_ci ldr x8, [sp, #16] // table 69cabdff1aSopenharmony_ci load_yoff_ycoeff 24, 32 // y_offset, y_coeff 70cabdff1aSopenharmony_ci ld1 {v1.1D}, [x8] 71cabdff1aSopenharmony_ci dup v0.8H, w10 72cabdff1aSopenharmony_ci dup v3.8H, w9 73cabdff1aSopenharmony_ci sub w3, w3, w0, lsl #2 // w3 = linesize - width * 4 (padding) 74cabdff1aSopenharmony_ci sub w5, w5, w0 // w5 = linesizeY - width (paddingY) 75cabdff1aSopenharmony_ci sub w7, w7, w0, lsr #1 // w7 = linesizeU - width / 2 (paddingU) 76cabdff1aSopenharmony_ci sub w14, w14, w0, lsr #1 // w14 = linesizeV - width / 2 (paddingV) 77cabdff1aSopenharmony_ci.endm 78cabdff1aSopenharmony_ci 79cabdff1aSopenharmony_ci.macro load_chroma_nv12 80cabdff1aSopenharmony_ci ld2 {v16.8B, v17.8B}, [x6], #16 81cabdff1aSopenharmony_ci ushll v18.8H, v16.8B, #3 82cabdff1aSopenharmony_ci ushll v19.8H, v17.8B, #3 83cabdff1aSopenharmony_ci.endm 84cabdff1aSopenharmony_ci 85cabdff1aSopenharmony_ci.macro load_chroma_nv21 86cabdff1aSopenharmony_ci ld2 {v16.8B, v17.8B}, [x6], #16 87cabdff1aSopenharmony_ci ushll v19.8H, v16.8B, #3 88cabdff1aSopenharmony_ci ushll v18.8H, v17.8B, #3 89cabdff1aSopenharmony_ci.endm 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_ci.macro load_chroma_yuv420p 92cabdff1aSopenharmony_ci ld1 {v16.8B}, [ x6], #8 93cabdff1aSopenharmony_ci ld1 {v17.8B}, [x13], #8 94cabdff1aSopenharmony_ci ushll v18.8H, v16.8B, #3 95cabdff1aSopenharmony_ci ushll v19.8H, v17.8B, #3 96cabdff1aSopenharmony_ci.endm 97cabdff1aSopenharmony_ci 98cabdff1aSopenharmony_ci.macro load_chroma_yuv422p 99cabdff1aSopenharmony_ci load_chroma_yuv420p 100cabdff1aSopenharmony_ci.endm 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_ci.macro increment_nv12 103cabdff1aSopenharmony_ci ands w15, w1, #1 104cabdff1aSopenharmony_ci csel w16, w7, w11, ne // incC = (h & 1) ? paddincC : -width 105cabdff1aSopenharmony_ci add x6, x6, w16, SXTW // srcC += incC 106cabdff1aSopenharmony_ci.endm 107cabdff1aSopenharmony_ci 108cabdff1aSopenharmony_ci.macro increment_nv21 109cabdff1aSopenharmony_ci increment_nv12 110cabdff1aSopenharmony_ci.endm 111cabdff1aSopenharmony_ci 112cabdff1aSopenharmony_ci.macro increment_yuv420p 113cabdff1aSopenharmony_ci ands w15, w1, #1 114cabdff1aSopenharmony_ci csel w16, w7, w11, ne // incU = (h & 1) ? paddincU : -width/2 115cabdff1aSopenharmony_ci csel w17, w14, w11, ne // incV = (h & 1) ? paddincV : -width/2 116cabdff1aSopenharmony_ci add x6, x6, w16, SXTW // srcU += incU 117cabdff1aSopenharmony_ci add x13, x13, w17, SXTW // srcV += incV 118cabdff1aSopenharmony_ci.endm 119cabdff1aSopenharmony_ci 120cabdff1aSopenharmony_ci.macro increment_yuv422p 121cabdff1aSopenharmony_ci add x6, x6, w7, SXTW // srcU += incU 122cabdff1aSopenharmony_ci add x13, x13, w14, SXTW // srcV += incV 123cabdff1aSopenharmony_ci.endm 124cabdff1aSopenharmony_ci 125cabdff1aSopenharmony_ci.macro compute_rgba r1 g1 b1 a1 r2 g2 b2 a2 126cabdff1aSopenharmony_ci add v20.8H, v26.8H, v20.8H // Y1 + R1 127cabdff1aSopenharmony_ci add v21.8H, v27.8H, v21.8H // Y2 + R2 128cabdff1aSopenharmony_ci add v22.8H, v26.8H, v22.8H // Y1 + G1 129cabdff1aSopenharmony_ci add v23.8H, v27.8H, v23.8H // Y2 + G2 130cabdff1aSopenharmony_ci add v24.8H, v26.8H, v24.8H // Y1 + B1 131cabdff1aSopenharmony_ci add v25.8H, v27.8H, v25.8H // Y2 + B2 132cabdff1aSopenharmony_ci sqrshrun \r1, v20.8H, #1 // clip_u8((Y1 + R1) >> 1) 133cabdff1aSopenharmony_ci sqrshrun \r2, v21.8H, #1 // clip_u8((Y2 + R1) >> 1) 134cabdff1aSopenharmony_ci sqrshrun \g1, v22.8H, #1 // clip_u8((Y1 + G1) >> 1) 135cabdff1aSopenharmony_ci sqrshrun \g2, v23.8H, #1 // clip_u8((Y2 + G1) >> 1) 136cabdff1aSopenharmony_ci sqrshrun \b1, v24.8H, #1 // clip_u8((Y1 + B1) >> 1) 137cabdff1aSopenharmony_ci sqrshrun \b2, v25.8H, #1 // clip_u8((Y2 + B1) >> 1) 138cabdff1aSopenharmony_ci movi \a1, #255 139cabdff1aSopenharmony_ci movi \a2, #255 140cabdff1aSopenharmony_ci.endm 141cabdff1aSopenharmony_ci 142cabdff1aSopenharmony_ci.macro declare_func ifmt ofmt 143cabdff1aSopenharmony_cifunction ff_\ifmt\()_to_\ofmt\()_neon, export=1 144cabdff1aSopenharmony_ci load_args_\ifmt 145cabdff1aSopenharmony_ci mov w9, w1 146cabdff1aSopenharmony_ci1: 147cabdff1aSopenharmony_ci mov w8, w0 // w8 = width 148cabdff1aSopenharmony_ci2: 149cabdff1aSopenharmony_ci movi v5.8H, #4, lsl #8 // 128 * (1<<3) 150cabdff1aSopenharmony_ci load_chroma_\ifmt 151cabdff1aSopenharmony_ci sub v18.8H, v18.8H, v5.8H // U*(1<<3) - 128*(1<<3) 152cabdff1aSopenharmony_ci sub v19.8H, v19.8H, v5.8H // V*(1<<3) - 128*(1<<3) 153cabdff1aSopenharmony_ci sqdmulh v20.8H, v19.8H, v1.H[0] // V * v2r (R) 154cabdff1aSopenharmony_ci sqdmulh v22.8H, v18.8H, v1.H[1] // U * u2g 155cabdff1aSopenharmony_ci sqdmulh v19.8H, v19.8H, v1.H[2] // V * v2g 156cabdff1aSopenharmony_ci add v22.8H, v22.8H, v19.8H // U * u2g + V * v2g (G) 157cabdff1aSopenharmony_ci sqdmulh v24.8H, v18.8H, v1.H[3] // U * u2b (B) 158cabdff1aSopenharmony_ci zip2 v21.8H, v20.8H, v20.8H // R2 159cabdff1aSopenharmony_ci zip1 v20.8H, v20.8H, v20.8H // R1 160cabdff1aSopenharmony_ci zip2 v23.8H, v22.8H, v22.8H // G2 161cabdff1aSopenharmony_ci zip1 v22.8H, v22.8H, v22.8H // G1 162cabdff1aSopenharmony_ci zip2 v25.8H, v24.8H, v24.8H // B2 163cabdff1aSopenharmony_ci zip1 v24.8H, v24.8H, v24.8H // B1 164cabdff1aSopenharmony_ci ld1 {v2.16B}, [x4], #16 // load luma 165cabdff1aSopenharmony_ci ushll v26.8H, v2.8B, #3 // Y1*(1<<3) 166cabdff1aSopenharmony_ci ushll2 v27.8H, v2.16B, #3 // Y2*(1<<3) 167cabdff1aSopenharmony_ci sub v26.8H, v26.8H, v3.8H // Y1*(1<<3) - y_offset 168cabdff1aSopenharmony_ci sub v27.8H, v27.8H, v3.8H // Y2*(1<<3) - y_offset 169cabdff1aSopenharmony_ci sqdmulh v26.8H, v26.8H, v0.8H // ((Y1*(1<<3) - y_offset) * y_coeff) >> 15 170cabdff1aSopenharmony_ci sqdmulh v27.8H, v27.8H, v0.8H // ((Y2*(1<<3) - y_offset) * y_coeff) >> 15 171cabdff1aSopenharmony_ci 172cabdff1aSopenharmony_ci.ifc \ofmt,argb // 1 2 3 0 173cabdff1aSopenharmony_ci compute_rgba v5.8B,v6.8B,v7.8B,v4.8B, v17.8B,v18.8B,v19.8B,v16.8B 174cabdff1aSopenharmony_ci.endif 175cabdff1aSopenharmony_ci 176cabdff1aSopenharmony_ci.ifc \ofmt,rgba // 0 1 2 3 177cabdff1aSopenharmony_ci compute_rgba v4.8B,v5.8B,v6.8B,v7.8B, v16.8B,v17.8B,v18.8B,v19.8B 178cabdff1aSopenharmony_ci.endif 179cabdff1aSopenharmony_ci 180cabdff1aSopenharmony_ci.ifc \ofmt,abgr // 3 2 1 0 181cabdff1aSopenharmony_ci compute_rgba v7.8B,v6.8B,v5.8B,v4.8B, v19.8B,v18.8B,v17.8B,v16.8B 182cabdff1aSopenharmony_ci.endif 183cabdff1aSopenharmony_ci 184cabdff1aSopenharmony_ci.ifc \ofmt,bgra // 2 1 0 3 185cabdff1aSopenharmony_ci compute_rgba v6.8B,v5.8B,v4.8B,v7.8B, v18.8B,v17.8B,v16.8B,v19.8B 186cabdff1aSopenharmony_ci.endif 187cabdff1aSopenharmony_ci 188cabdff1aSopenharmony_ci st4 { v4.8B, v5.8B, v6.8B, v7.8B}, [x2], #32 189cabdff1aSopenharmony_ci st4 {v16.8B,v17.8B,v18.8B,v19.8B}, [x2], #32 190cabdff1aSopenharmony_ci subs w8, w8, #16 // width -= 16 191cabdff1aSopenharmony_ci b.gt 2b 192cabdff1aSopenharmony_ci add x2, x2, w3, SXTW // dst += padding 193cabdff1aSopenharmony_ci add x4, x4, w5, SXTW // srcY += paddingY 194cabdff1aSopenharmony_ci increment_\ifmt 195cabdff1aSopenharmony_ci subs w1, w1, #1 // height -= 1 196cabdff1aSopenharmony_ci b.gt 1b 197cabdff1aSopenharmony_ci mov w0, w9 198cabdff1aSopenharmony_ci ret 199cabdff1aSopenharmony_ciendfunc 200cabdff1aSopenharmony_ci.endm 201cabdff1aSopenharmony_ci 202cabdff1aSopenharmony_ci.macro declare_rgb_funcs ifmt 203cabdff1aSopenharmony_ci declare_func \ifmt, argb 204cabdff1aSopenharmony_ci declare_func \ifmt, rgba 205cabdff1aSopenharmony_ci declare_func \ifmt, abgr 206cabdff1aSopenharmony_ci declare_func \ifmt, bgra 207cabdff1aSopenharmony_ci.endm 208cabdff1aSopenharmony_ci 209cabdff1aSopenharmony_cideclare_rgb_funcs nv12 210cabdff1aSopenharmony_cideclare_rgb_funcs nv21 211cabdff1aSopenharmony_cideclare_rgb_funcs yuv420p 212cabdff1aSopenharmony_cideclare_rgb_funcs yuv422p 213