1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2015 Matthieu Bouron <matthieu.bouron stupeflix.com> 3cabdff1aSopenharmony_ci * Copyright (c) 2015 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/arm/asm.S" 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci 25cabdff1aSopenharmony_ci.macro compute_premult 26cabdff1aSopenharmony_ci vsub.u16 q14,q11 @ q14 = U * (1 << 3) - 128 * (1 << 3) 27cabdff1aSopenharmony_ci vsub.u16 q15,q11 @ q15 = V * (1 << 3) - 128 * (1 << 3) 28cabdff1aSopenharmony_ci vqdmulh.s16 q8, q15, d1[0] @ q8 = V * v2r 29cabdff1aSopenharmony_ci vqdmulh.s16 q9, q14, d1[1] @ q9 = U * u2g 30cabdff1aSopenharmony_ci vqdmulh.s16 q5, q15, d1[2] @ q5 = V * v2g 31cabdff1aSopenharmony_ci vadd.s16 q9, q5 @ q9 = U * u2g + V * v2g 32cabdff1aSopenharmony_ci vqdmulh.s16 q10,q14, d1[3] @ q10 = U * u2b 33cabdff1aSopenharmony_ci.endm 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_ci.macro compute_color dst_comp1 dst_comp2 pre 36cabdff1aSopenharmony_ci vadd.s16 q1, q14, \pre 37cabdff1aSopenharmony_ci vadd.s16 q2, q15, \pre 38cabdff1aSopenharmony_ci vqrshrun.s16 \dst_comp1, q1, #1 39cabdff1aSopenharmony_ci vqrshrun.s16 \dst_comp2, q2, #1 40cabdff1aSopenharmony_ci.endm 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_ci.macro compute_rgba r1 g1 b1 a1 r2 g2 b2 a2 43cabdff1aSopenharmony_ci compute_color \r1, \r2, q8 44cabdff1aSopenharmony_ci compute_color \g1, \g2, q9 45cabdff1aSopenharmony_ci compute_color \b1, \b2, q10 46cabdff1aSopenharmony_ci vmov.u8 \a1, #255 47cabdff1aSopenharmony_ci vmov.u8 \a2, #255 48cabdff1aSopenharmony_ci.endm 49cabdff1aSopenharmony_ci 50cabdff1aSopenharmony_ci.macro compute dst ofmt 51cabdff1aSopenharmony_ci vshll.u8 q14, d14, #3 @ q14 = Y * (1 << 3) 52cabdff1aSopenharmony_ci vshll.u8 q15, d15, #3 @ q15 = Y * (1 << 3) 53cabdff1aSopenharmony_ci vsub.s16 q14, q12 @ q14 = (Y - y_offset) 54cabdff1aSopenharmony_ci vsub.s16 q15, q12 @ q15 = (Y - y_offset) 55cabdff1aSopenharmony_ci vqdmulh.s16 q14, q13 @ q14 = (Y - y_offset) * y_coeff 56cabdff1aSopenharmony_ci vqdmulh.s16 q15, q13 @ q15 = (Y - y_offset) * y_coeff 57cabdff1aSopenharmony_ci 58cabdff1aSopenharmony_ci.ifc \ofmt,argb 59cabdff1aSopenharmony_ci compute_rgba d7, d8, d9, d6, d11, d12, d13, d10 60cabdff1aSopenharmony_ci.endif 61cabdff1aSopenharmony_ci 62cabdff1aSopenharmony_ci.ifc \ofmt,rgba 63cabdff1aSopenharmony_ci compute_rgba d6, d7, d8, d9, d10, d11, d12, d13 64cabdff1aSopenharmony_ci.endif 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_ci.ifc \ofmt,abgr 67cabdff1aSopenharmony_ci compute_rgba d9, d8, d7, d6, d13, d12, d11, d10 68cabdff1aSopenharmony_ci.endif 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci.ifc \ofmt,bgra 71cabdff1aSopenharmony_ci compute_rgba d8, d7, d6, d9, d12, d11, d10, d13 72cabdff1aSopenharmony_ci.endif 73cabdff1aSopenharmony_ci 74cabdff1aSopenharmony_ci vzip.8 d6, d10 @ d6 = R1R2R3R4R5R6R7R8 d10 = R9R10R11R12R13R14R15R16 75cabdff1aSopenharmony_ci vzip.8 d7, d11 @ d7 = G1G2G3G4G5G6G7G8 d11 = G9G10G11G12G13G14G15G16 76cabdff1aSopenharmony_ci vzip.8 d8, d12 @ d8 = B1B2B3B4B5B6B7B8 d12 = B9B10B11B12B13B14B15B16 77cabdff1aSopenharmony_ci vzip.8 d9, d13 @ d9 = A1A2A3A4A5A6A7A8 d13 = A9A10A11A12A13A14A15A16 78cabdff1aSopenharmony_ci vst4.8 {q3, q4}, [\dst,:128]! 79cabdff1aSopenharmony_ci vst4.8 {q5, q6}, [\dst,:128]! 80cabdff1aSopenharmony_ci.endm 81cabdff1aSopenharmony_ci 82cabdff1aSopenharmony_ci.macro process_1l_internal dst src ofmt 83cabdff1aSopenharmony_ci vld2.8 {d14, d15}, [\src]! @ q7 = Y (interleaved) 84cabdff1aSopenharmony_ci compute \dst, \ofmt 85cabdff1aSopenharmony_ci.endm 86cabdff1aSopenharmony_ci 87cabdff1aSopenharmony_ci.macro process_1l ofmt 88cabdff1aSopenharmony_ci compute_premult 89cabdff1aSopenharmony_ci process_1l_internal r2, r4, \ofmt 90cabdff1aSopenharmony_ci.endm 91cabdff1aSopenharmony_ci 92cabdff1aSopenharmony_ci.macro process_2l ofmt 93cabdff1aSopenharmony_ci compute_premult 94cabdff1aSopenharmony_ci process_1l_internal r2, r4, \ofmt 95cabdff1aSopenharmony_ci process_1l_internal r11,r12,\ofmt 96cabdff1aSopenharmony_ci.endm 97cabdff1aSopenharmony_ci 98cabdff1aSopenharmony_ci.macro load_args_nv12 99cabdff1aSopenharmony_ci push {r4-r12, lr} 100cabdff1aSopenharmony_ci vpush {q4-q7} 101cabdff1aSopenharmony_ci ldr r4, [sp, #104] @ r4 = srcY 102cabdff1aSopenharmony_ci ldr r5, [sp, #108] @ r5 = linesizeY 103cabdff1aSopenharmony_ci ldr r6, [sp, #112] @ r6 = srcC 104cabdff1aSopenharmony_ci ldr r7, [sp, #116] @ r7 = linesizeC 105cabdff1aSopenharmony_ci ldr r8, [sp, #120] @ r8 = table 106cabdff1aSopenharmony_ci ldr r9, [sp, #124] @ r9 = y_offset 107cabdff1aSopenharmony_ci ldr r10,[sp, #128] @ r10 = y_coeff 108cabdff1aSopenharmony_ci vdup.16 d0, r10 @ d0 = y_coeff 109cabdff1aSopenharmony_ci vld1.16 {d1}, [r8] @ d1 = *table 110cabdff1aSopenharmony_ci add r11, r2, r3 @ r11 = dst + linesize (dst2) 111cabdff1aSopenharmony_ci add r12, r4, r5 @ r12 = srcY + linesizeY (srcY2) 112cabdff1aSopenharmony_ci lsl r3, r3, #1 113cabdff1aSopenharmony_ci lsl r5, r5, #1 114cabdff1aSopenharmony_ci sub r3, r3, r0, lsl #2 @ r3 = linesize * 2 - width * 4 (padding) 115cabdff1aSopenharmony_ci sub r5, r5, r0 @ r5 = linesizeY * 2 - width (paddingY) 116cabdff1aSopenharmony_ci sub r7, r7, r0 @ r7 = linesizeC - width (paddingC) 117cabdff1aSopenharmony_ci.endm 118cabdff1aSopenharmony_ci 119cabdff1aSopenharmony_ci.macro load_args_nv21 120cabdff1aSopenharmony_ci load_args_nv12 121cabdff1aSopenharmony_ci.endm 122cabdff1aSopenharmony_ci 123cabdff1aSopenharmony_ci.macro load_args_yuv420p 124cabdff1aSopenharmony_ci push {r4-r12, lr} 125cabdff1aSopenharmony_ci vpush {q4-q7} 126cabdff1aSopenharmony_ci ldr r4, [sp, #104] @ r4 = srcY 127cabdff1aSopenharmony_ci ldr r5, [sp, #108] @ r5 = linesizeY 128cabdff1aSopenharmony_ci ldr r6, [sp, #112] @ r6 = srcU 129cabdff1aSopenharmony_ci ldr r8, [sp, #128] @ r8 = table 130cabdff1aSopenharmony_ci ldr r9, [sp, #132] @ r9 = y_offset 131cabdff1aSopenharmony_ci ldr r10,[sp, #136] @ r10 = y_coeff 132cabdff1aSopenharmony_ci vdup.16 d0, r10 @ d0 = y_coeff 133cabdff1aSopenharmony_ci vld1.16 {d1}, [r8] @ d1 = *table 134cabdff1aSopenharmony_ci add r11, r2, r3 @ r11 = dst + linesize (dst2) 135cabdff1aSopenharmony_ci add r12, r4, r5 @ r12 = srcY + linesizeY (srcY2) 136cabdff1aSopenharmony_ci lsl r3, r3, #1 137cabdff1aSopenharmony_ci lsl r5, r5, #1 138cabdff1aSopenharmony_ci sub r3, r3, r0, lsl #2 @ r3 = linesize * 2 - width * 4 (padding) 139cabdff1aSopenharmony_ci sub r5, r5, r0 @ r5 = linesizeY * 2 - width (paddingY) 140cabdff1aSopenharmony_ci ldr r10,[sp, #120] @ r10 = srcV 141cabdff1aSopenharmony_ci.endm 142cabdff1aSopenharmony_ci 143cabdff1aSopenharmony_ci.macro load_args_yuv422p 144cabdff1aSopenharmony_ci push {r4-r12, lr} 145cabdff1aSopenharmony_ci vpush {q4-q7} 146cabdff1aSopenharmony_ci ldr r4, [sp, #104] @ r4 = srcY 147cabdff1aSopenharmony_ci ldr r5, [sp, #108] @ r5 = linesizeY 148cabdff1aSopenharmony_ci ldr r6, [sp, #112] @ r6 = srcU 149cabdff1aSopenharmony_ci ldr r7, [sp, #116] @ r7 = linesizeU 150cabdff1aSopenharmony_ci ldr r12,[sp, #124] @ r12 = linesizeV 151cabdff1aSopenharmony_ci ldr r8, [sp, #128] @ r8 = table 152cabdff1aSopenharmony_ci ldr r9, [sp, #132] @ r9 = y_offset 153cabdff1aSopenharmony_ci ldr r10,[sp, #136] @ r10 = y_coeff 154cabdff1aSopenharmony_ci vdup.16 d0, r10 @ d0 = y_coeff 155cabdff1aSopenharmony_ci vld1.16 {d1}, [r8] @ d1 = *table 156cabdff1aSopenharmony_ci sub r3, r3, r0, lsl #2 @ r3 = linesize - width * 4 (padding) 157cabdff1aSopenharmony_ci sub r5, r5, r0 @ r5 = linesizeY - width (paddingY) 158cabdff1aSopenharmony_ci sub r7, r7, r0, lsr #1 @ r7 = linesizeU - width / 2 (paddingU) 159cabdff1aSopenharmony_ci sub r12,r12,r0, lsr #1 @ r12 = linesizeV - width / 2 (paddingV) 160cabdff1aSopenharmony_ci ldr r10,[sp, #120] @ r10 = srcV 161cabdff1aSopenharmony_ci.endm 162cabdff1aSopenharmony_ci 163cabdff1aSopenharmony_ci.macro load_chroma_nv12 164cabdff1aSopenharmony_ci pld [r12, #64*3] 165cabdff1aSopenharmony_ci 166cabdff1aSopenharmony_ci vld2.8 {d2, d3}, [r6]! @ q1: interleaved chroma line 167cabdff1aSopenharmony_ci vshll.u8 q14, d2, #3 @ q14 = U * (1 << 3) 168cabdff1aSopenharmony_ci vshll.u8 q15, d3, #3 @ q15 = V * (1 << 3) 169cabdff1aSopenharmony_ci.endm 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci.macro load_chroma_nv21 172cabdff1aSopenharmony_ci pld [r12, #64*3] 173cabdff1aSopenharmony_ci 174cabdff1aSopenharmony_ci vld2.8 {d2, d3}, [r6]! @ q1: interleaved chroma line 175cabdff1aSopenharmony_ci vshll.u8 q14, d3, #3 @ q14 = U * (1 << 3) 176cabdff1aSopenharmony_ci vshll.u8 q15, d2, #3 @ q15 = V * (1 << 3) 177cabdff1aSopenharmony_ci.endm 178cabdff1aSopenharmony_ci 179cabdff1aSopenharmony_ci.macro load_chroma_yuv420p 180cabdff1aSopenharmony_ci pld [r10, #64*3] 181cabdff1aSopenharmony_ci pld [r12, #64*3] 182cabdff1aSopenharmony_ci 183cabdff1aSopenharmony_ci vld1.8 d2, [r6]! @ d2: chroma red line 184cabdff1aSopenharmony_ci vld1.8 d3, [r10]! @ d3: chroma blue line 185cabdff1aSopenharmony_ci vshll.u8 q14, d2, #3 @ q14 = U * (1 << 3) 186cabdff1aSopenharmony_ci vshll.u8 q15, d3, #3 @ q15 = V * (1 << 3) 187cabdff1aSopenharmony_ci.endm 188cabdff1aSopenharmony_ci 189cabdff1aSopenharmony_ci.macro load_chroma_yuv422p 190cabdff1aSopenharmony_ci pld [r10, #64*3] 191cabdff1aSopenharmony_ci 192cabdff1aSopenharmony_ci vld1.8 d2, [r6]! @ d2: chroma red line 193cabdff1aSopenharmony_ci vld1.8 d3, [r10]! @ d3: chroma blue line 194cabdff1aSopenharmony_ci vshll.u8 q14, d2, #3 @ q14 = U * (1 << 3) 195cabdff1aSopenharmony_ci vshll.u8 q15, d3, #3 @ q15 = V * (1 << 3) 196cabdff1aSopenharmony_ci.endm 197cabdff1aSopenharmony_ci 198cabdff1aSopenharmony_ci.macro increment_and_test_nv12 199cabdff1aSopenharmony_ci add r11, r11, r3 @ dst2 += padding 200cabdff1aSopenharmony_ci add r12, r12, r5 @ srcY2 += paddingY 201cabdff1aSopenharmony_ci add r6, r6, r7 @ srcC += paddingC 202cabdff1aSopenharmony_ci subs r1, r1, #2 @ height -= 2 203cabdff1aSopenharmony_ci.endm 204cabdff1aSopenharmony_ci 205cabdff1aSopenharmony_ci.macro increment_and_test_nv21 206cabdff1aSopenharmony_ci increment_and_test_nv12 207cabdff1aSopenharmony_ci.endm 208cabdff1aSopenharmony_ci 209cabdff1aSopenharmony_ci.macro increment_and_test_yuv420p 210cabdff1aSopenharmony_ci add r11, r11, r3 @ dst2 += padding 211cabdff1aSopenharmony_ci add r12, r12, r5 @ srcY2 += paddingY 212cabdff1aSopenharmony_ci ldr r7, [sp, #116] @ r7 = linesizeU 213cabdff1aSopenharmony_ci sub r7, r7, r0, lsr #1 @ r7 = linesizeU - width / 2 (paddingU) 214cabdff1aSopenharmony_ci add r6, r6, r7 @ srcU += paddingU 215cabdff1aSopenharmony_ci ldr r7, [sp, #124] @ r7 = linesizeV 216cabdff1aSopenharmony_ci sub r7, r7, r0, lsr #1 @ r7 = linesizeV - width / 2 (paddingV) 217cabdff1aSopenharmony_ci add r10, r10, r7 @ srcV += paddingV 218cabdff1aSopenharmony_ci subs r1, r1, #2 @ height -= 2 219cabdff1aSopenharmony_ci.endm 220cabdff1aSopenharmony_ci 221cabdff1aSopenharmony_ci.macro increment_and_test_yuv422p 222cabdff1aSopenharmony_ci add r6, r6, r7 @ srcU += paddingU 223cabdff1aSopenharmony_ci add r10,r10,r12 @ srcV += paddingV 224cabdff1aSopenharmony_ci subs r1, r1, #1 @ height -= 1 225cabdff1aSopenharmony_ci.endm 226cabdff1aSopenharmony_ci 227cabdff1aSopenharmony_ci.macro process_nv12 ofmt 228cabdff1aSopenharmony_ci process_2l \ofmt 229cabdff1aSopenharmony_ci.endm 230cabdff1aSopenharmony_ci 231cabdff1aSopenharmony_ci.macro process_nv21 ofmt 232cabdff1aSopenharmony_ci process_2l \ofmt 233cabdff1aSopenharmony_ci.endm 234cabdff1aSopenharmony_ci 235cabdff1aSopenharmony_ci.macro process_yuv420p ofmt 236cabdff1aSopenharmony_ci process_2l \ofmt 237cabdff1aSopenharmony_ci.endm 238cabdff1aSopenharmony_ci 239cabdff1aSopenharmony_ci.macro process_yuv422p ofmt 240cabdff1aSopenharmony_ci process_1l \ofmt 241cabdff1aSopenharmony_ci.endm 242cabdff1aSopenharmony_ci 243cabdff1aSopenharmony_ci.macro declare_func ifmt ofmt 244cabdff1aSopenharmony_cifunction ff_\ifmt\()_to_\ofmt\()_neon, export=1 245cabdff1aSopenharmony_ci load_args_\ifmt 246cabdff1aSopenharmony_ci vmov.u16 q11, #1024 @ q11 = 128 * (1 << 3) 247cabdff1aSopenharmony_ci vdup.16 q12, r9 @ q12 = y_offset 248cabdff1aSopenharmony_ci vmov d26, d0 @ q13 = y_coeff 249cabdff1aSopenharmony_ci vmov d27, d0 @ q13 = y_coeff 250cabdff1aSopenharmony_ci1: 251cabdff1aSopenharmony_ci mov r8, r0 @ r8 = width 252cabdff1aSopenharmony_ci2: 253cabdff1aSopenharmony_ci pld [r6, #64*3] 254cabdff1aSopenharmony_ci pld [r4, #64*3] 255cabdff1aSopenharmony_ci vmov.i8 d10, #128 256cabdff1aSopenharmony_ci load_chroma_\ifmt 257cabdff1aSopenharmony_ci process_\ifmt \ofmt 258cabdff1aSopenharmony_ci subs r8, r8, #16 @ width -= 16 259cabdff1aSopenharmony_ci bgt 2b 260cabdff1aSopenharmony_ci add r2, r2, r3 @ dst += padding 261cabdff1aSopenharmony_ci add r4, r4, r5 @ srcY += paddingY 262cabdff1aSopenharmony_ci increment_and_test_\ifmt 263cabdff1aSopenharmony_ci bgt 1b 264cabdff1aSopenharmony_ci vpop {q4-q7} 265cabdff1aSopenharmony_ci pop {r4-r12, lr} 266cabdff1aSopenharmony_ci mov pc, lr 267cabdff1aSopenharmony_ciendfunc 268cabdff1aSopenharmony_ci.endm 269cabdff1aSopenharmony_ci 270cabdff1aSopenharmony_ci.macro declare_rgb_funcs ifmt 271cabdff1aSopenharmony_ci declare_func \ifmt, argb 272cabdff1aSopenharmony_ci declare_func \ifmt, rgba 273cabdff1aSopenharmony_ci declare_func \ifmt, abgr 274cabdff1aSopenharmony_ci declare_func \ifmt, bgra 275cabdff1aSopenharmony_ci.endm 276cabdff1aSopenharmony_ci 277cabdff1aSopenharmony_cideclare_rgb_funcs nv12 278cabdff1aSopenharmony_cideclare_rgb_funcs nv21 279cabdff1aSopenharmony_cideclare_rgb_funcs yuv420p 280cabdff1aSopenharmony_cideclare_rgb_funcs yuv422p 281