History

mv mc_neon.S to common,add MC arm code to encoder

Licai Guo committed 12 years ago

Commit 71467f91 parent 14f55186 files · +727 −8Browse files

Unified · Split

6 files
  1. codec/build/iOS/common/common.xcodeproj/project.pbxproj +4 −0
  2. codec/build/iOS/dec/welsdec/welsdec.xcodeproj/project.pbxproj +0 −4
  3. codec/build/iOS/enc/welsenc/welsenc.xcodeproj/project.pbxproj +0 −4
  4. codec/common/mc_common.h +12 −0
  5. codec/common/mc_neon.S +598 −0
  6. codec/encoder/core/src/mc.cpp +113 −0
codec/build/iOS/common/common.xcodeproj/project.pbxproj+4−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
88
99 /* Begin PBXBuildFile section */
1010 4C34067D18C5C94C00DFA14A /* expand_picture_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4C34067C18C5C94C00DFA14A /* expand_picture_neon.S */; };
11+ 4C34069B18C96CB000DFA14A /* mc_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4C34069A18C96CB000DFA14A /* mc_neon.S */; };
1112 4CE443D918B722CD0017DF25 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CE443D818B722CD0017DF25 /* Foundation.framework */; };
1213 4CE443E718B722CD0017DF25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CE443E618B722CD0017DF25 /* XCTest.framework */; };
1314 4CE443E818B722CD0017DF25 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CE443D818B722CD0017DF25 /* Foundation.framework */; };
@@ -48,6 +49,7 @@ · 34 unmodified lines
4849
4950 /* Begin PBXFileReference section */
5051 4C34067C18C5C94C00DFA14A /* expand_picture_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = expand_picture_neon.S; sourceTree = "<group>"; };
52+ 4C34069A18C96CB000DFA14A /* mc_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = mc_neon.S; sourceTree = "<group>"; };
5153 4CE443D518B722CD0017DF25 /* libcommon.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libcommon.a; sourceTree = BUILT_PRODUCTS_DIR; };
5254 4CE443D818B722CD0017DF25 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
5355 4CE443E518B722CD0017DF25 /* commonTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = commonTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -150,6 +152,7 @@ · 96 unmodified lines
150152 4CE4472F18BC61650017DF25 /* common */ = {
151153 isa = PBXGroup;
152154 children = (
155+ 4C34069A18C96CB000DFA14A /* mc_neon.S */,
153156 4C34067C18C5C94C00DFA14A /* expand_picture_neon.S */,
154157 4CE447BE18C085900017DF25 /* arm_arch_common_macro.S */,
155158 4CE447BC18C085320017DF25 /* deblocking_neon.S */,
@@ -256,6 +259,7 @@ · 100 unmodified lines
256259 isa = PBXSourcesBuildPhase;
257260 buildActionMask = 2147483647;
258261 files = (
262+ 4C34069B18C96CB000DFA14A /* mc_neon.S in Sources */,
259263 4CE447BF18C085900017DF25 /* arm_arch_common_macro.S in Sources */,
260264 4CE4475018BC61650017DF25 /* deblocking_common.cpp in Sources */,
261265 4CE4474C18BC61650017DF25 /* cpu.cpp in Sources */,
codec/build/iOS/dec/welsdec/welsdec.xcodeproj/project.pbxproj+0−4
@@ -38,7 +38,6 @@ · 37 unmodified lines
3838 4CE4469F18BC5EAB0017DF25 /* welsDecoderExt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4468518BC5EAB0017DF25 /* welsDecoderExt.cpp */; };
3939 4CE447AC18BC6BE90017DF25 /* block_add_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4CE447A718BC6BE90017DF25 /* block_add_neon.S */; };
4040 4CE447AE18BC6BE90017DF25 /* intra_pred_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4CE447A918BC6BE90017DF25 /* intra_pred_neon.S */; };
41− 4CE447AF18BC6BE90017DF25 /* mc_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4CE447AA18BC6BE90017DF25 /* mc_neon.S */; };
4241 /* End PBXBuildFile section */
4342
4443 /* Begin PBXContainerItemProxy section */
@@ -132,7 +131,6 @@ · 87 unmodified lines
132131 4CE4468518BC5EAB0017DF25 /* welsDecoderExt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = welsDecoderExt.cpp; sourceTree = "<group>"; };
133132 4CE447A718BC6BE90017DF25 /* block_add_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = block_add_neon.S; sourceTree = "<group>"; };
134133 4CE447A918BC6BE90017DF25 /* intra_pred_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = intra_pred_neon.S; sourceTree = "<group>"; };
135− 4CE447AA18BC6BE90017DF25 /* mc_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = mc_neon.S; sourceTree = "<group>"; };
136134 /* End PBXFileReference section */
137135
138136 /* Begin PBXFrameworksBuildPhase section */
@@ -325,7 +323,6 @@ · 186 unmodified lines
325323 children = (
326324 4CE447A718BC6BE90017DF25 /* block_add_neon.S */,
327325 4CE447A918BC6BE90017DF25 /* intra_pred_neon.S */,
328− 4CE447AA18BC6BE90017DF25 /* mc_neon.S */,
329326 );
330327 path = arm;
331328 sourceTree = "<group>";
@@ -411,7 +408,6 @@ · 79 unmodified lines
411408 isa = PBXSourcesBuildPhase;
412409 buildActionMask = 2147483647;
413410 files = (
414− 4CE447AF18BC6BE90017DF25 /* mc_neon.S in Sources */,
415411 4CE4469B18BC5EAB0017DF25 /* pic_queue.cpp in Sources */,
416412 4CE4469F18BC5EAB0017DF25 /* welsDecoderExt.cpp in Sources */,
417413 4CE4469318BC5EAB0017DF25 /* fmo.cpp in Sources */,
codec/build/iOS/enc/welsenc/welsenc.xcodeproj/project.pbxproj+0−4
@@ -9,7 +9,6 @@ · 8 unmodified lines
99 /* Begin PBXBuildFile section */
1010 4C34066D18C57D0400DFA14A /* intra_pred_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4C34066618C57D0400DFA14A /* intra_pred_neon.S */; };
1111 4C34066E18C57D0400DFA14A /* intra_pred_sad_3_opt_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4C34066718C57D0400DFA14A /* intra_pred_sad_3_opt_neon.S */; };
12− 4C34066F18C57D0400DFA14A /* mc_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4C34066818C57D0400DFA14A /* mc_neon.S */; };
1312 4C34067018C57D0400DFA14A /* memory_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4C34066918C57D0400DFA14A /* memory_neon.S */; };
1413 4C34067118C57D0400DFA14A /* pixel_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4C34066A18C57D0400DFA14A /* pixel_neon.S */; };
1514 4C34067218C57D0400DFA14A /* reconstruct_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4C34066B18C57D0400DFA14A /* reconstruct_neon.S */; };
@@ -79,7 +78,6 @@ · 63 unmodified lines
7978 /* Begin PBXFileReference section */
8079 4C34066618C57D0400DFA14A /* intra_pred_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = intra_pred_neon.S; sourceTree = "<group>"; };
8180 4C34066718C57D0400DFA14A /* intra_pred_sad_3_opt_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = intra_pred_sad_3_opt_neon.S; sourceTree = "<group>"; };
82− 4C34066818C57D0400DFA14A /* mc_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = mc_neon.S; sourceTree = "<group>"; };
8381 4C34066918C57D0400DFA14A /* memory_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = memory_neon.S; sourceTree = "<group>"; };
8482 4C34066A18C57D0400DFA14A /* pixel_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = pixel_neon.S; sourceTree = "<group>"; };
8583 4C34066B18C57D0400DFA14A /* reconstruct_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = reconstruct_neon.S; sourceTree = "<group>"; };
@@ -206,7 +204,6 @@ · 120 unmodified lines
206204 children = (
207205 4C34066618C57D0400DFA14A /* intra_pred_neon.S */,
208206 4C34066718C57D0400DFA14A /* intra_pred_sad_3_opt_neon.S */,
209− 4C34066818C57D0400DFA14A /* mc_neon.S */,
210207 4C34066918C57D0400DFA14A /* memory_neon.S */,
211208 4C34066A18C57D0400DFA14A /* pixel_neon.S */,
212209 4C34066B18C57D0400DFA14A /* reconstruct_neon.S */,
@@ -492,7 +489,6 @@ · 279 unmodified lines
492489 4CE4472A18BC605C0017DF25 /* utils.cpp in Sources */,
493490 4CE4471018BC605C0017DF25 /* decode_mb_aux.cpp in Sources */,
494491 4CE4472018BC605C0017DF25 /* sample.cpp in Sources */,
495− 4C34066F18C57D0400DFA14A /* mc_neon.S in Sources */,
496492 4CE4472D18BC605C0017DF25 /* welsCodecTrace.cpp in Sources */,
497493 4CE4471318BC605C0017DF25 /* encoder_data_tables.cpp in Sources */,
498494 4C34067118C57D0400DFA14A /* pixel_neon.S in Sources */,
codec/common/mc_common.h+12−0
@@ -82,6 +82,18 @@ void McHorVer02WidthEq4_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* p · 81 unmodified lines
8282 void McHorVer22WidthEq16_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight);
8383 void McHorVer22WidthEq8_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight);
8484 void McHorVer22WidthEq4_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight);
85+
86+void PixStrideAvgWidthEq16_neon(uint8_t* pDst, int32_t iDstStride, const uint8_t* pSrcA, int32_t iSrcStrideA, const uint8_t* pSrcB, int32_t iSrcStrideB, int32_t iHeight);
87+void PixStrideAvgWidthEq8_neon(uint8_t* pDst, int32_t iDstStride, const uint8_t* pSrcA, int32_t iSrcStrideA, const uint8_t* pSrcB, int32_t iSrcStrideB, int32_t iHeight);
88+
89+void McHorVer20Width17_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight);// width+1
90+void McHorVer20Width9_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight);// width+1
91+
92+void McHorVer02Height17_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight);// height+1
93+void McHorVer02Height9_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight);// height+1
94+
95+void McHorVer22Width17_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight);//width+1&&height+1
96+void McHorVer22Width9_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight);//width+1&&height+1
8597 #endif
8698
8799 #if defined(X86_ASM)
codec/common/mc_neon.Srenamed from codec/decoder/core/arm/mc_neon.S+598−0
@@ -53,6 +53,17 @@ · 52 unmodified lines
5353 // }
5454 .endm
5555
56+.macro FILTER_SINGLE_TAG_8BITS // when width=17/9, used
57+// { // input: src_d{Y[0][1][2][3][4][5]X, the even of working_q2},
58+ vrev64.8 $2, $0 // X[5][4][3][2][1][0]O
59+ vaddl.u8 $3, $0, $2 // each 16bits, *[50][41][32][23][14][05]*
60+ vmul.s16 $0, $2, $1 // 0+1*[50]-5*[41]+20[32]
61+ vpadd.s16 $0, $0, $0
62+ vpadd.s16 $0, $0, $0
63+ vqrshrun.s16 $0, $4, #5
64+// }
65+.endm
66+
5667 .macro FILTER_6TAG_8BITS_AVERAGE_WITH_0
5768 // { // input:src[-2], src[-1], src[0], src[1], src[2], src[3], dst_d, multiplier a/b; working: q12, q13
5869 vaddl.u8 q12, $0, $5 //q12=src[-2]+src[3]
@@ -115,6 +126,24 @@ · 56 unmodified lines
115126 vadd.s16 $2, $0 //a=src[-2]+src[3]
116127 // }
117128 .endm
129+
130+.macro UNPACK_1_IN_8x16BITS_TO_8BITS
131+// { // each 16bits; input: d_dst, d_src[0:3] (even), d_src[4:5]+%% (odd)
132+ vext.16 $3, $3, $3, #7 // 0x????, [0][1][2][3][4][5],
133+ vrev64.16 $1, $1
134+ vadd.u16 $2, $1 // C[2+3],B[1+4],A[0+5],
135+ vshr.s64 $1, $2, #16
136+ vshr.s64 $0, $2, #32 // Output: C $2, B $1, A $0
137+
138+ vsub.s16 $0, $0, $1 //a-b
139+ vshr.s16 $0, $0, #2 //(a-b)/4
140+ vsub.s16 $0, $0, $1 //(a-b)/4-b
141+ vadd.s16 $0, $0, $2 //(a-b)/4-b+c
142+ vshr.s16 $0, $0, #2 //((a-b)/4-b+c)/4
143+ vadd.s16 $1, $0, $2 //((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16
144+ vqrshrun.s16 $0, $3, #6 //(+32)>>6
145+// }
146+.endm
118147 #else
119148 .macro AVERAGE_TWO_8BITS arg0, arg1, arg2
120149 // { // input:dst_d, src_d A and B; working: q13
@@ -134,6 +163,17 @@ · 13 unmodified lines
134163 // }
135164 .endm
136165
166+.macro FILTER_SINGLE_TAG_8BITS arg0, arg1,arg2, arg3, arg4,arg5 // when width=17/9, used
167+// { // input: src_d{Y[0][1][2][3][4][5]X, the even of working_q2}
168+ vrev64.8 \arg2, \arg0 // X[5][4][3][2][1][0]O
169+ vaddl.u8 \arg3, \arg0, \arg2 // each 16bits, *[50][41][32][23][14][05]*
170+ vmul.s16 \arg0, \arg2, \arg1 // 0+1*[50]-5*[41]+20[32]
171+ vpadd.s16 \arg0, \arg0, \arg0
172+ vpadd.s16 \arg0, \arg0, \arg0
173+ vqrshrun.s16 \arg0, \arg4, #5
174+// }
175+.endm
176+
137177 .macro FILTER_6TAG_8BITS_AVERAGE_WITH_0 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
138178 // { // input:src[-2], src[-1], src[0], src[1], src[2], src[3], dst_d, multiplier a/b; working: q12, q13
139179 vaddl.u8 q12, \arg0, \arg5 //q12=src[-2]+src[3]
@@ -196,6 +236,24 @@ · 56 unmodified lines
196236 vadd.s16 \arg2, \arg0 //a=src[-2]+src[3]
197237 // }
198238 .endm
239+
240+.macro UNPACK_1_IN_8x16BITS_TO_8BITS arg0, arg1,arg2, arg3
241+// { // each 16bits; input: d_dst, d_src[0:3] (even), d_src[4:5]+%% (odd)
242+ vext.16 \arg3, \arg3, \arg3, #7 // 0x????, [0][1][2][3][4][5]
243+ vrev64.16 \arg1, \arg1
244+ vadd.u16 \arg2, \arg1 // C[2+3],B[1+4],A[0+5]
245+ vshr.s64 \arg1, \arg2, #16
246+ vshr.s64 \arg0, \arg2, #32 // Output: C \arg2, B \arg1, A \arg0
247+
248+ vsub.s16 \arg0, \arg0, \arg1 //a-b
249+ vshr.s16 \arg0, \arg0, #2 //(a-b)/4
250+ vsub.s16 \arg0, \arg0, \arg1 //(a-b)/4-b
251+ vadd.s16 \arg0, \arg0, \arg2 //(a-b)/4-b+c
252+ vshr.s16 \arg0, \arg0, #2 //((a-b)/4-b+c)/4
253+ vadd.s16 \arg1, \arg0, \arg2 //((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16
254+ vqrshrun.s16 \arg0, \arg3, #6 //(+32)>>6
255+// }
256+.endm
199257 #endif
200258
201259 WELS_ASM_FUNC_BEGIN McHorVer20WidthEq16_neon
@@ -1599,4 +1657,544 @@ w4_mc_chroma_loop: // each two pxl row · 1397 unmodified lines
15991657
16001658 pop {r4, r5, r6}
16011659 WELS_ASM_FUNC_END
1660+
1661+WELS_ASM_FUNC_BEGIN McHorVer20Width17_neon
1662+ push {r4-r5}
1663+ mov r4, #20
1664+ mov r5, #1
1665+ sub r4, r4, r4, lsl #(16-2)
1666+ lsl r5, #16
1667+ ror r4, #16
1668+ vmov d3, r5, r4 // 0x0014FFFB00010000
1669+
1670+ sub r3, #16
1671+ ldr r4, [sp, #8]
1672+
1673+ sub r0, #2
1674+ vmov.u16 q14, #0x0014 // 20
1675+ vshr.u16 q15, q14, #2 // 5
1676+
1677+w17_h_mc_luma_loop:
1678+ vld1.u8 {d0,d1,d2}, [r0], r1 //only use 22(17+5); q0=src[-2]
1679+
1680+ vext.8 q2, q0, q1, #1 //q2=src[-1]
1681+ vext.8 q3, q0, q1, #2 //q3=src[0]
1682+ vext.8 q4, q0, q1, #3 //q4=src[1]
1683+ vext.8 q5, q0, q1, #4 //q5=src[2]
1684+ vext.8 q6, q0, q1, #5 //q6=src[3]
1685+
1686+ FILTER_6TAG_8BITS d0, d4, d6, d8, d10, d12, d14, q14, q15
1687+
1688+ FILTER_6TAG_8BITS d1, d5, d7, d9, d11, d13, d15, q14, q15
1689+
1690+ vst1.u8 {d14, d15}, [r2]! //write [0:15] Byte
1691+
1692+ vsli.64 d2, d2, #8 // [0][1][2][3][4][5]XO-->O[0][1][2][3][4][5]X
1693+ FILTER_SINGLE_TAG_8BITS d2, d3, d14, q7, q1
1694+
1695+ vst1.u8 {d2[0]}, [r2], r3 //write 16th Byte
1696+
1697+ sub r4, #1
1698+ cmp r4, #0
1699+ bne w17_h_mc_luma_loop
1700+ pop {r4-r5}
1701+WELS_ASM_FUNC_END
1702+
1703+
1704+WELS_ASM_FUNC_BEGIN McHorVer20Width9_neon
1705+ push {r4-r5}
1706+ mov r4, #20
1707+ mov r5, #1
1708+ sub r4, r4, r4, lsl #(16-2)
1709+ lsl r5, #16
1710+ ror r4, #16
1711+ vmov d7, r5, r4 // 0x0014FFFB00010000
1712+
1713+ sub r3, #8
1714+ ldr r4, [sp, #8]
1715+
1716+ sub r0, #2
1717+ vmov.u16 q14, #0x0014 // 20
1718+ vshr.u16 q15, q14, #2 // 5
1719+
1720+w9_h_mc_luma_loop:
1721+ vld1.u8 {d0,d1}, [r0], r1 //only use 14(9+5); q0=src[-2]
1722+ pld [r0]
1723+
1724+ vext.8 d2, d0, d1, #1 //d2=src[-1]
1725+ vext.8 d3, d0, d1, #2 //d3=src[0]
1726+ vext.8 d4, d0, d1, #3 //d4=src[1]
1727+ vext.8 d5, d0, d1, #4 //d5=src[2]
1728+ vext.8 d6, d0, d1, #5 //d6=src[3]
1729+
1730+ FILTER_6TAG_8BITS d0, d2, d3, d4, d5, d6, d8, q14, q15
1731+
1732+ sub r4, #1
1733+ vst1.u8 {d8}, [r2]! //write [0:7] Byte
1734+
1735+ vsli.64 d2, d1, #8 // [0][1][2][3][4][5]XO-->O[0][1][2][3][4][5]X
1736+ FILTER_SINGLE_TAG_8BITS d2, d7, d14, q7, q1
1737+ vst1.u8 {d2[0]}, [r2], r3 //write 8th Byte
1738+
1739+ cmp r4, #0
1740+ bne w9_h_mc_luma_loop
1741+ pop {r4-r5}
1742+WELS_ASM_FUNC_END
1743+
1744+
1745+ WELS_ASM_FUNC_BEGIN McHorVer02Height17_neon
1746+ push {r4}
1747+ ldr r4, [sp, #4]
1748+
1749+ sub r0, r0, r1, lsl #1 //src[-2*src_stride]
1750+ pld [r0]
1751+ pld [r0, r1]
1752+ vmov.u16 q14, #0x0014 // 20
1753+ vld1.u8 {q0}, [r0], r1 //q0=src[-2]
1754+ vld1.u8 {q1}, [r0], r1 //q1=src[-1]
1755+
1756+ pld [r0]
1757+ pld [r0, r1]
1758+ vshr.u16 q15, q14, #2 // 5
1759+ vld1.u8 {q2}, [r0], r1 //q2=src[0]
1760+ vld1.u8 {q3}, [r0], r1 //q3=src[1]
1761+ vld1.u8 {q4}, [r0], r1 //q4=src[2]
1762+
1763+w17_v_mc_luma_loop:
1764+
1765+ vld1.u8 {q5}, [r0], r1 //q5=src[3]
1766+
1767+ FILTER_6TAG_8BITS d0, d2, d4, d6, d8, d10, d12, q14, q15
1768+ pld [r0]
1769+ FILTER_6TAG_8BITS d1, d3, d5, d7, d9, d11, d13, q14, q15
1770+ vld1.u8 {q0}, [r0], r1 //read 2nd row
1771+ vst1.u8 {q6}, [r2], r3 //write 1st 16Byte
1772+
1773+ FILTER_6TAG_8BITS d2, d4, d6, d8, d10, d0, d12, q14, q15
1774+ pld [r0]
1775+ FILTER_6TAG_8BITS d3, d5, d7, d9, d11, d1, d13, q14, q15
1776+ vld1.u8 {q1}, [r0], r1 //read 3rd row
1777+ vst1.u8 {q6}, [r2], r3 //write 2nd 16Byte
1778+
1779+ FILTER_6TAG_8BITS d4, d6, d8, d10, d0, d2, d12, q14, q15
1780+ pld [r0]
1781+ FILTER_6TAG_8BITS d5, d7, d9, d11, d1, d3, d13, q14, q15
1782+ vld1.u8 {q2}, [r0], r1 //read 4th row
1783+ vst1.u8 {q6}, [r2], r3 //write 3rd 16Byte
1784+
1785+ FILTER_6TAG_8BITS d6, d8, d10, d0, d2, d4, d12, q14, q15
1786+ pld [r0]
1787+ FILTER_6TAG_8BITS d7, d9, d11, d1, d3, d5, d13, q14, q15
1788+ vld1.u8 {q3}, [r0], r1 //read 5th row
1789+ vst1.u8 {q6}, [r2], r3 //write 4th 16Byte
1790+
1791+ FILTER_6TAG_8BITS d8, d10, d0, d2, d4, d6, d12, q14, q15
1792+ pld [r0]
1793+ FILTER_6TAG_8BITS d9, d11, d1, d3, d5, d7, d13, q14, q15
1794+ vld1.u8 {q4}, [r0], r1 //read 6th row
1795+ vst1.u8 {q6}, [r2], r3 //write 5th 16Byte
1796+
1797+ FILTER_6TAG_8BITS d10, d0, d2, d4, d6, d8, d12, q14, q15
1798+ pld [r0]
1799+ FILTER_6TAG_8BITS d11, d1, d3, d5, d7, d9, d13, q14, q15
1800+ vld1.u8 {q5}, [r0], r1 //read 7th row
1801+ vst1.u8 {q6}, [r2], r3 //write 6th 16Byte
1802+
1803+ FILTER_6TAG_8BITS d0, d2, d4, d6, d8, d10, d12, q14, q15
1804+ pld [r0]
1805+ FILTER_6TAG_8BITS d1, d3, d5, d7, d9, d11, d13, q14, q15
1806+ vld1.u8 {q0}, [r0], r1 //read 8th row
1807+ vst1.u8 {q6}, [r2], r3 //write 7th 16Byte
1808+
1809+ FILTER_6TAG_8BITS d2, d4, d6, d8, d10, d0, d12, q14, q15
1810+ pld [r0]
1811+ FILTER_6TAG_8BITS d3, d5, d7, d9, d11, d1, d13, q14, q15
1812+ vst1.u8 {q6}, [r2], r3 //write 8th 16Byte
1813+
1814+ //q2, q3, q4, q5, q0 --> q0~q4
1815+ vswp q0, q4
1816+ vswp q0, q2
1817+ vmov q1, q3
1818+ vmov q3, q5 //q0~q4
1819+
1820+ sub r4, #8
1821+ cmp r4, #1
1822+ bne w17_v_mc_luma_loop
1823+ // the last 16Bytes
1824+ vld1.u8 {q5}, [r0], r1 //q5=src[3]
1825+ FILTER_6TAG_8BITS d0, d2, d4, d6, d8, d10, d12, q14, q15
1826+ FILTER_6TAG_8BITS d1, d3, d5, d7, d9, d11, d13, q14, q15
1827+ vst1.u8 {q6}, [r2], r3 //write 1st 16Byte
1828+
1829+ pop {r4}
1830+WELS_ASM_FUNC_END
1831+
1832+
1833+WELS_ASM_FUNC_BEGIN McHorVer02Height9_neon
1834+ push {r4}
1835+ ldr r4, [sp, #4]
1836+
1837+ sub r0, r0, r1, lsl #1 //src[-2*src_stride]
1838+ pld [r0]
1839+ pld [r0, r1]
1840+ vmov.u16 q14, #0x0014 // 20
1841+ vld1.u8 {d0}, [r0], r1 //d0=src[-2]
1842+ vld1.u8 {d1}, [r0], r1 //d1=src[-1]
1843+
1844+ pld [r0]
1845+ pld [r0, r1]
1846+ vshr.u16 q15, q14, #2 // 5
1847+ vld1.u8 {d2}, [r0], r1 //d2=src[0]
1848+ vld1.u8 {d3}, [r0], r1 //d3=src[1]
1849+
1850+ vld1.u8 {d4}, [r0], r1 //d4=src[2]
1851+ vld1.u8 {d5}, [r0], r1 //d5=src[3]
1852+
1853+w9_v_mc_luma_loop:
1854+
1855+ pld [r0]
1856+ FILTER_6TAG_8BITS d0, d1, d2, d3, d4, d5, d12, q14, q15
1857+ vld1.u8 {d0}, [r0], r1 //read 2nd row
1858+ vst1.u8 {d12}, [r2], r3 //write 1st 8Byte
1859+
1860+ pld [r0]
1861+ FILTER_6TAG_8BITS d1, d2, d3, d4, d5, d0, d12, q14, q15
1862+ vld1.u8 {d1}, [r0], r1 //read 3rd row
1863+ vst1.u8 {d12}, [r2], r3 //write 2nd 8Byte
1864+
1865+ pld [r0]
1866+ FILTER_6TAG_8BITS d2, d3, d4, d5, d0, d1, d12, q14, q15
1867+ vld1.u8 {d2}, [r0], r1 //read 4th row
1868+ vst1.u8 {d12}, [r2], r3 //write 3rd 8Byte
1869+
1870+ pld [r0]
1871+ FILTER_6TAG_8BITS d3, d4, d5, d0, d1, d2, d12, q14, q15
1872+ vld1.u8 {d3}, [r0], r1 //read 5th row
1873+ vst1.u8 {d12}, [r2], r3 //write 4th 8Byte
1874+
1875+ //d4, d5, d0, d1, d2, d3 --> d0, d1, d2, d3, d4, d5
1876+ vswp q0, q2
1877+ vswp q1, q2
1878+
1879+ sub r4, #4
1880+ cmp r4, #1
1881+ bne w9_v_mc_luma_loop
1882+
1883+ FILTER_6TAG_8BITS d0, d1, d2, d3, d4, d5, d12, q14, q15
1884+ vst1.u8 {d12}, [r2], r3 //write last 8Byte
1885+
1886+ pop {r4}
1887+WELS_ASM_FUNC_END
1888+
1889+
1890+WELS_ASM_FUNC_BEGIN McHorVer22Width17_neon
1891+ push {r4}
1892+ ldr r4, [sp, #4]
1893+
1894+ sub r0, #2 //src[-2]
1895+ sub r0, r0, r1, lsl #1 //src[-2*src_stride-2]
1896+ pld [r0]
1897+ pld [r0, r1]
1898+
1899+ vmov.u16 q14, #0x0014 // 20
1900+ vld1.u8 {d0-d2}, [r0], r1 //use 21(17+5), =src[-2]
1901+ vld1.u8 {d3-d5}, [r0], r1 //use 21(17+5), =src[-1]
1902+
1903+ pld [r0]
1904+ pld [r0, r1]
1905+ vshr.u16 q15, q14, #2 // 5
1906+
1907+ vld1.u8 {d6-d8}, [r0], r1 //use 21(17+5), =src[0]
1908+ vld1.u8 {d9-d11}, [r0], r1 //use 21(17+5), =src[1]
1909+ pld [r0]
1910+ pld [r0, r1]
1911+ vld1.u8 {d12-d14}, [r0], r1 //use 21(17+5), =src[2]
1912+ sub r3, #16
1913+
1914+w17_hv_mc_luma_loop:
1915+
1916+ vld1.u8 {d15-d17}, [r0], r1 //use 21(17+5), =src[3]
1917+ //the 1st row
1918+ pld [r0]
1919+ // vertical filtered into q9/q10
1920+ FILTER_6TAG_8BITS_TO_16BITS d0, d3, d6, d9, d12, d15, q9, q14, q15 // 8 avail
1921+ FILTER_6TAG_8BITS_TO_16BITS d1, d4, d7,d10, d13, d16,q10, q14, q15 // 8 avail
1922+ // horizon filtered
1923+ UNPACK_2_16BITS_TO_ABC q9, q10, q11, q12, q13
1924+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d0 //output to q0[0]
1925+ // vertical filtered into q10/q11
1926+ FILTER_6TAG_8BITS_TO_16BITS d2, d5, d8,d11, d14, d17,q11, q14, q15 // only 6 avail
1927+ // horizon filtered
1928+ UNPACK_2_16BITS_TO_ABC q10, q11, q9, q12, q13
1929+ FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d1 //output to q0[1]
1930+ vst1.u8 {d0, d1}, [r2]! //write 16Byte
1931+ UNPACK_1_IN_8x16BITS_TO_8BITS d2, d22, d23, q11 //output to d2[0]
1932+ vst1.u8 {d2[0]}, [r2], r3 //write 16th Byte
1933+
1934+ vld1.u8 {d0-d2}, [r0], r1 //read 2nd row
1935+ //the 2nd row
1936+ pld [r0]
1937+ // vertical filtered into q9/q10
1938+ FILTER_6TAG_8BITS_TO_16BITS d3, d6, d9, d12, d15, d0, q9, q14, q15 // 8 avail
1939+ FILTER_6TAG_8BITS_TO_16BITS d4, d7,d10, d13, d16, d1,q10, q14, q15 // 8 avail
1940+ // horizon filtered
1941+ UNPACK_2_16BITS_TO_ABC q9, q10, q11, q12, q13
1942+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d3 //output to d3
1943+ // vertical filtered into q10/q11
1944+ FILTER_6TAG_8BITS_TO_16BITS d5, d8,d11, d14, d17, d2,q11, q14, q15 // only 6 avail
1945+ // horizon filtered
1946+ UNPACK_2_16BITS_TO_ABC q10, q11, q9, q12, q13
1947+ FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d4 //output to d4
1948+ vst1.u8 {d3, d4}, [r2]! //write 16Byte
1949+ UNPACK_1_IN_8x16BITS_TO_8BITS d5, d22, d23, q11 //output to d5[0]
1950+ vst1.u8 {d5[0]}, [r2], r3 //write 16th Byte
1951+
1952+ vld1.u8 {d3-d5}, [r0], r1 //read 3rd row
1953+ //the 3rd row
1954+ pld [r0]
1955+ // vertical filtered into q9/q10
1956+ FILTER_6TAG_8BITS_TO_16BITS d6, d9, d12, d15, d0, d3, q9, q14, q15 // 8 avail
1957+ FILTER_6TAG_8BITS_TO_16BITS d7,d10, d13, d16, d1, d4,q10, q14, q15 // 8 avail
1958+ // horizon filtered
1959+ UNPACK_2_16BITS_TO_ABC q9, q10, q11, q12, q13
1960+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d6 //output to d6
1961+ // vertical filtered into q10/q11
1962+ FILTER_6TAG_8BITS_TO_16BITS d8,d11, d14, d17, d2, d5,q11, q14, q15 // only 6 avail
1963+ // horizon filtered
1964+ UNPACK_2_16BITS_TO_ABC q10, q11, q9, q12, q13
1965+ FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d7 //output to d7
1966+ vst1.u8 {d6, d7}, [r2]! //write 16Byte
1967+ UNPACK_1_IN_8x16BITS_TO_8BITS d8, d22, d23, q11 //output to d8[0]
1968+ vst1.u8 {d8[0]}, [r2], r3 //write 16th Byte
1969+
1970+ vld1.u8 {d6-d8}, [r0], r1 //read 4th row
1971+ //the 4th row
1972+ pld [r0]
1973+ // vertical filtered into q9/q10
1974+ FILTER_6TAG_8BITS_TO_16BITS d9, d12, d15, d0, d3, d6, q9, q14, q15 // 8 avail
1975+ FILTER_6TAG_8BITS_TO_16BITS d10, d13, d16, d1, d4, d7,q10, q14, q15 // 8 avail
1976+ // horizon filtered
1977+ UNPACK_2_16BITS_TO_ABC q9, q10, q11, q12, q13
1978+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d9 //output to d9
1979+ // vertical filtered into q10/q11
1980+ FILTER_6TAG_8BITS_TO_16BITS d11, d14, d17, d2, d5, d8,q11, q14, q15 // only 6 avail
1981+ // horizon filtered
1982+ UNPACK_2_16BITS_TO_ABC q10, q11, q9, q12, q13
1983+ FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d10 //output to d10
1984+ vst1.u8 {d9, d10}, [r2], r3 //write 16Byte
1985+ UNPACK_1_IN_8x16BITS_TO_8BITS d11, d22, d23, q11 //output to d11[0]
1986+ vst1.u8 {d11[0]}, [r2], r3 //write 16th Byte
1987+
1988+ //d12~d17(q6~q8), d0~d8(q0~q3+d8), --> d0~d14
1989+ vswp q0, q6
1990+ vswp q6, q3
1991+ vmov q5, q2
1992+ vmov q2, q8
1993+
1994+ vmov d20,d8
1995+ vmov q4, q1
1996+ vmov q1, q7
1997+ vmov d14,d20
1998+
1999+ sub r4, #4
2000+ cmp r4, #1
2001+ bne w17_hv_mc_luma_loop
2002+ //the last row
2003+ vld1.u8 {d15-d17}, [r0], r1 //use 21(17+5), =src[3]
2004+ // vertical filtered into q9/q10
2005+ FILTER_6TAG_8BITS_TO_16BITS d0, d3, d6, d9, d12, d15, q9, q14, q15 // 8 avail
2006+ FILTER_6TAG_8BITS_TO_16BITS d1, d4, d7,d10, d13, d16,q10, q14, q15 // 8 avail
2007+ // horizon filtered
2008+ UNPACK_2_16BITS_TO_ABC q9, q10, q11, q12, q13
2009+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d0 //output to q0[0]
2010+ // vertical filtered into q10/q11
2011+ FILTER_6TAG_8BITS_TO_16BITS d2, d5, d8,d11, d14, d17,q11, q14, q15 // only 6 avail
2012+ // horizon filtered
2013+ UNPACK_2_16BITS_TO_ABC q10, q11, q9, q12, q13
2014+ FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d1 //output to q0[1]
2015+ vst1.u8 {q0}, [r2]! //write 16Byte
2016+ UNPACK_1_IN_8x16BITS_TO_8BITS d2, d22, d23, q11 //output to d2[0]
2017+ vst1.u8 {d2[0]}, [r2], r3 //write 16th Byte
2018+
2019+ pop {r4}
2020+WELS_ASM_FUNC_END
2021+
2022+
2023+WELS_ASM_FUNC_BEGIN McHorVer22Width9_neon
2024+ push {r4}
2025+ ldr r4, [sp, #4]
2026+
2027+ sub r0, #2 //src[-2]
2028+ sub r0, r0, r1, lsl #1 //src[-2*src_stride-2]
2029+ pld [r0]
2030+ pld [r0, r1]
2031+
2032+ vmov.u16 q14, #0x0014 // 20
2033+ vld1.u8 {q0}, [r0], r1 //use 14(9+5), =src[-2]
2034+ vld1.u8 {q1}, [r0], r1 //use 14(9+5), =src[-1]
2035+
2036+ pld [r0]
2037+ pld [r0, r1]
2038+ vshr.u16 q15, q14, #2 // 5
2039+
2040+ vld1.u8 {q2}, [r0], r1 //use 14(9+5), =src[0]
2041+ vld1.u8 {q3}, [r0], r1 //use 14(9+5), =src[1]
2042+ pld [r0]
2043+ pld [r0, r1]
2044+ vld1.u8 {q4}, [r0], r1 //use 14(9+5), =src[2]
2045+ sub r3, #8
2046+
2047+w9_hv_mc_luma_loop:
2048+
2049+ vld1.u8 {q5}, [r0], r1 //use 14(9+5), =src[3]
2050+ //the 1st row
2051+ pld [r0]
2052+ // vertical filtered into q6/q7
2053+ FILTER_6TAG_8BITS_TO_16BITS d0, d2, d4, d6, d8, d10, q6, q14, q15 // 8 avail
2054+ FILTER_6TAG_8BITS_TO_16BITS d1, d3, d5, d7, d9, d11, q7, q14, q15 // 6 avail
2055+ // horizon filtered
2056+ UNPACK_2_16BITS_TO_ABC q6, q7, q11, q12, q13
2057+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12 //output to q6[0]
2058+ vst1.u8 d12, [r2]! //write 8Byte
2059+ UNPACK_1_IN_8x16BITS_TO_8BITS d13, d14, d15, q7 //output to d13[0]
2060+ vst1.u8 {d13[0]}, [r2], r3 //write 8th Byte
2061+
2062+ vld1.u8 {q0}, [r0], r1 //read 2nd row
2063+ //the 2nd row
2064+ pld [r0]
2065+ // vertical filtered into q6/q7
2066+ FILTER_6TAG_8BITS_TO_16BITS d2, d4, d6, d8, d10, d0, q6, q14, q15 // 8 avail
2067+ FILTER_6TAG_8BITS_TO_16BITS d3, d5, d7, d9, d11, d1, q7, q14, q15 // 6 avail
2068+ // horizon filtered
2069+ UNPACK_2_16BITS_TO_ABC q6, q7, q11, q12, q13
2070+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12 //output to q6[0]
2071+ vst1.u8 d12, [r2]! //write 8Byte
2072+ UNPACK_1_IN_8x16BITS_TO_8BITS d13, d14, d15, q7 //output to d13[0]
2073+ vst1.u8 {d13[0]}, [r2], r3 //write 8th Byte
2074+
2075+ vld1.u8 {q1}, [r0], r1 //read 3rd row
2076+ //the 3rd row
2077+ pld [r0]
2078+ // vertical filtered into q6/q7
2079+ FILTER_6TAG_8BITS_TO_16BITS d4, d6, d8, d10, d0, d2, q6, q14, q15 // 8 avail
2080+ FILTER_6TAG_8BITS_TO_16BITS d5, d7, d9, d11, d1, d3, q7, q14, q15 // 6 avail
2081+ // horizon filtered
2082+ UNPACK_2_16BITS_TO_ABC q6, q7, q11, q12, q13
2083+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12 //output to q6[0]
2084+ vst1.u8 d12, [r2]! //write 8Byte
2085+ UNPACK_1_IN_8x16BITS_TO_8BITS d13, d14, d15, q7 //output to d13[0]
2086+ vst1.u8 {d13[0]}, [r2], r3 //write 8th Byte
2087+
2088+ vld1.u8 {q2}, [r0], r1 //read 4th row
2089+ //the 4th row
2090+ pld [r0]
2091+ // vertical filtered into q6/q7
2092+ FILTER_6TAG_8BITS_TO_16BITS d6, d8, d10, d0, d2, d4, q6, q14, q15 // 8 avail
2093+ FILTER_6TAG_8BITS_TO_16BITS d7, d9, d11, d1, d3, d5, q7, q14, q15 // 6 avail
2094+ // horizon filtered
2095+ UNPACK_2_16BITS_TO_ABC q6, q7, q11, q12, q13
2096+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12 //output to q6[0]
2097+ vst1.u8 d12, [r2]! //write 8Byte
2098+ UNPACK_1_IN_8x16BITS_TO_8BITS d13, d14, d15, q7 //output to d13[0]
2099+ vst1.u8 {d13[0]}, [r2], r3 //write 8th Byte
2100+
2101+ //q4~q5, q0~q2, --> q0~q4
2102+ vswp q0, q4
2103+ vswp q2, q4
2104+ vmov q3, q1
2105+ vmov q1, q5
2106+
2107+ sub r4, #4
2108+ cmp r4, #1
2109+ bne w9_hv_mc_luma_loop
2110+ //the last row
2111+ vld1.u8 {q5}, [r0], r1 //use 14(9+5), =src[3]
2112+ // vertical filtered into q6/q7
2113+ FILTER_6TAG_8BITS_TO_16BITS d0, d2, d4, d6, d8, d10, q6, q14, q15 // 8 avail
2114+ FILTER_6TAG_8BITS_TO_16BITS d1, d3, d5, d7, d9, d11, q7, q14, q15 // 6 avail
2115+ // horizon filtered
2116+ UNPACK_2_16BITS_TO_ABC q6, q7, q11, q12, q13
2117+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12 //output to q6[0]
2118+ vst1.u8 d12, [r2]! //write 8Byte
2119+ UNPACK_1_IN_8x16BITS_TO_8BITS d13, d14, d15, q7 //output to d13[0]
2120+ vst1.u8 {d13[0]}, [r2], r3 //write 8th Byte
2121+ pop {r4}
2122+WELS_ASM_FUNC_END
2123+
2124+
2125+WELS_ASM_FUNC_BEGIN PixStrideAvgWidthEq16_neon
2126+ push {r4, r5, r6}
2127+ ldr r4, [sp, #12]
2128+ ldr r5, [sp, #16]
2129+ ldr r6, [sp, #20]
2130+
2131+enc_w16_pix_avg_loop:
2132+ vld1.u8 {q0}, [r2], r3
2133+ vld1.u8 {q1}, [r4], r5
2134+ vld1.u8 {q2}, [r2], r3
2135+ vld1.u8 {q3}, [r4], r5
2136+
2137+ vld1.u8 {q4}, [r2], r3
2138+ vld1.u8 {q5}, [r4], r5
2139+ vld1.u8 {q6}, [r2], r3
2140+ vld1.u8 {q7}, [r4], r5
2141+
2142+ AVERAGE_TWO_8BITS d0, d0, d2
2143+ AVERAGE_TWO_8BITS d1, d1, d3
2144+ vst1.u8 {q0}, [r0], r1
2145+
2146+ AVERAGE_TWO_8BITS d4, d4, d6
2147+ AVERAGE_TWO_8BITS d5, d5, d7
2148+ vst1.u8 {q2}, [r0], r1
2149+
2150+ AVERAGE_TWO_8BITS d8, d8, d10
2151+ AVERAGE_TWO_8BITS d9, d9, d11
2152+ vst1.u8 {q4}, [r0], r1
2153+
2154+ AVERAGE_TWO_8BITS d12, d12, d14
2155+ AVERAGE_TWO_8BITS d13, d13, d15
2156+ vst1.u8 {q6}, [r0], r1
2157+
2158+ sub r6, #4
2159+ cmp r6, #0
2160+ bne enc_w16_pix_avg_loop
2161+
2162+ pop {r4, r5, r6}
2163+WELS_ASM_FUNC_END
2164+
2165+
2166+WELS_ASM_FUNC_BEGIN PixStrideAvgWidthEq8_neon
2167+ push {r4, r5, r6}
2168+ ldr r4, [sp, #12]
2169+ ldr r5, [sp, #16]
2170+ ldr r6, [sp, #20]
2171+enc_w8_pix_avg_loop:
2172+
2173+ vld1.u8 {d0}, [r2], r3
2174+ vld1.u8 {d2}, [r4], r5
2175+ vld1.u8 {d1}, [r2], r3
2176+ vld1.u8 {d3}, [r4], r5
2177+
2178+ AVERAGE_TWO_8BITS d0, d0, d2
2179+ AVERAGE_TWO_8BITS d1, d1, d3
2180+ vst1.u8 {d0}, [r0], r1
2181+ vst1.u8 {d1}, [r0], r1
2182+
2183+ vld1.u8 {d4}, [r2], r3
2184+ vld1.u8 {d6}, [r4], r5
2185+ vld1.u8 {d5}, [r2], r3
2186+ vld1.u8 {d7}, [r4], r5
2187+
2188+ AVERAGE_TWO_8BITS d4, d4, d6
2189+ AVERAGE_TWO_8BITS d5, d5, d7
2190+ vst1.u8 {d4}, [r0], r1
2191+ vst1.u8 {d5}, [r0], r1
2192+
2193+ sub r6, #4
2194+ cmp r6, #0
2195+ bne enc_w8_pix_avg_loop
2196+
2197+ pop {r4, r5, r6}
2198+WELS_ASM_FUNC_END
2199+
16022200 #endif
codec/encoder/core/src/mc.cpp+113−0
@@ -480,6 +480,99 @@ void McChroma_ssse3 (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int · 479 unmodified lines
480480 }
481481
482482 #endif //X86_ASM
483+
484+ //***************************************************************************//
485+ // NEON implementation //
486+ //***************************************************************************//
487+#if defined(HAVE_NEON)
488+void McHorVer20Width9Or17_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
489+ int32_t iWidth, int32_t iHeight) {
490+ if (iWidth == 17)
491+ McHorVer20Width17_neon(pSrc, iSrcStride, pDst, iDstStride, iHeight);
492+ else //if (iWidth == 9)
493+ McHorVer20Width9_neon(pSrc, iSrcStride, pDst, iDstStride, iHeight);
494+}
495+void McHorVer02Height9Or17_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
496+ int32_t iWidth, int32_t iHeight){
497+ if (iWidth == 16)
498+ McHorVer02Height17_neon(pSrc, iSrcStride, pDst, iDstStride, iHeight);
499+ else //if (iWidth == 8)
500+ McHorVer02Height9_neon(pSrc, iSrcStride, pDst, iDstStride, iHeight);
501+}
502+void McHorVer22Width9Or17Height9Or17_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
503+ int32_t iWidth, int32_t iHeight){
504+ if (iWidth == 17)
505+ McHorVer22Width17_neon(pSrc, iSrcStride, pDst, iDstStride, iHeight);
506+ else //if (iWidth == 9)
507+ McHorVer22Width9_neon(pSrc, iSrcStride, pDst, iDstStride, iHeight);
508+}
509+void EncMcHorVer11_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight) {
510+ ENFORCE_STACK_ALIGN_1D(uint8_t, pTmp, 512, 16)
511+ McHorVer20WidthEq16_neon(pSrc, iSrcStride, pTmp, 16, iHeight);
512+ McHorVer02WidthEq16_neon(pSrc, iSrcStride, &pTmp[256], 16, iHeight);
513+ PixelAvgWidthEq16_neon(pDst, iDstStride, pTmp, &pTmp[256], iHeight);
514+}
515+void EncMcHorVer12_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight) {
516+ ENFORCE_STACK_ALIGN_1D(uint8_t, pTmp, 512, 16)
517+ McHorVer02WidthEq16_neon(pSrc, iSrcStride, pTmp, 16, iHeight);
518+ McHorVer22WidthEq16_neon(pSrc, iSrcStride, &pTmp[256], 16, iHeight);
519+ PixelAvgWidthEq16_neon(pDst, iDstStride, pTmp, &pTmp[256], iHeight);
520+}
521+void EncMcHorVer13_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight) {
522+ ENFORCE_STACK_ALIGN_1D(uint8_t, pTmp, 512, 16)
523+ McHorVer20WidthEq16_neon(pSrc+iSrcStride, iSrcStride, pTmp, 16, iHeight);
524+ McHorVer02WidthEq16_neon(pSrc, iSrcStride, &pTmp[256], 16, iHeight);
525+ PixelAvgWidthEq16_neon(pDst, iDstStride, pTmp, &pTmp[256], iHeight);
526+}
527+void EncMcHorVer21_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight) {
528+ ENFORCE_STACK_ALIGN_1D(uint8_t, pTmp, 512, 16)
529+ McHorVer20WidthEq16_neon(pSrc, iSrcStride, pTmp, 16, iHeight);
530+ McHorVer22WidthEq16_neon(pSrc, iSrcStride, &pTmp[256], 16, iHeight);
531+ PixelAvgWidthEq16_neon(pDst, iDstStride, pTmp, &pTmp[256], iHeight);
532+}
533+void EncMcHorVer23_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight) {
534+ ENFORCE_STACK_ALIGN_1D(uint8_t, pTmp, 512, 16)
535+ McHorVer20WidthEq16_neon(pSrc+iSrcStride, iSrcStride, pTmp, 16, iHeight);
536+ McHorVer22WidthEq16_neon(pSrc, iSrcStride, &pTmp[256], 16, iHeight);
537+ PixelAvgWidthEq16_neon(pDst, iDstStride, pTmp, &pTmp[256], iHeight);
538+}
539+void EncMcHorVer31_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight) {
540+ ENFORCE_STACK_ALIGN_1D(uint8_t, pTmp, 512, 16)
541+ McHorVer20WidthEq16_neon(pSrc, iSrcStride, pTmp, 16, iHeight);
542+ McHorVer02WidthEq16_neon(pSrc+1, iSrcStride, &pTmp[256], 16, iHeight);
543+ PixelAvgWidthEq16_neon(pDst, iDstStride, pTmp, &pTmp[256], iHeight);
544+}
545+void EncMcHorVer32_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight) {
546+ ENFORCE_STACK_ALIGN_1D(uint8_t, pTmp, 512, 16)
547+ McHorVer02WidthEq16_neon(pSrc+1, iSrcStride, pTmp, 16, iHeight);
548+ McHorVer22WidthEq16_neon(pSrc, iSrcStride, &pTmp[256], 16, iHeight);
549+ PixelAvgWidthEq16_neon(pDst, iDstStride, pTmp, &pTmp[256], iHeight);
550+}
551+void EncMcHorVer33_neon(const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride, int32_t iHeight) {
552+ ENFORCE_STACK_ALIGN_1D(uint8_t, pTmp, 512, 16)
553+ McHorVer20WidthEq16_neon(pSrc+iSrcStride, iSrcStride, pTmp, 16, iHeight);
554+ McHorVer02WidthEq16_neon(pSrc+1, iSrcStride, &pTmp[256], 16, iHeight);
555+ PixelAvgWidthEq16_neon(pDst, iDstStride, pTmp, &pTmp[256], iHeight);
556+}
557+void EncMcChroma_neon(const uint8_t *pSrc, int32_t iSrcStride, uint8_t *pDst, int32_t iDstStride,
558+ SMVUnitXY sMv, int32_t iWidth, int32_t iHeight) {
559+ const int32_t kiD8x = sMv.iMvX&0x07;
560+ const int32_t kiD8y = sMv.iMvY&0x07;
561+ if (0 == kiD8x && 0 == kiD8y) {
562+ if(8 == iWidth)
563+ McCopyWidthEq8_neon(pSrc, iSrcStride, pDst, iDstStride, iHeight);
564+ else // iWidth == 4
565+ McCopyWidthEq4_neon(pSrc, iSrcStride, pDst, iDstStride, iHeight);
566+ }
567+ else {
568+ if(8 == iWidth)
569+ McChromaWidthEq8_neon(pSrc, iSrcStride, pDst, iDstStride, (int32_t*)(g_kuiABCD[kiD8y][kiD8x]), iHeight);
570+ else //if(4 == iWidth)
571+ McChromaWidthEq4_neon(pSrc, iSrcStride, pDst, iDstStride, (int32_t*)(g_kuiABCD[kiD8y][kiD8x]), iHeight);
572+ }
573+}
574+#endif
575+
483576 typedef void (*PixelAvgFunc) (uint8_t*, int32_t, const uint8_t*, int32_t, const uint8_t*, int32_t, int32_t);
484577 void WelsInitMcFuncs (SWelsFuncPtrList* pFuncList, uint32_t uiCpuFlag) {
485578 static PixelAvgFunc pfPixAvgFunc[2] = {PixelAvgWidthEq8_c, PixelAvgWidthEq16_c};
@@ -498,6 +591,14 @@ void WelsInitMcFuncs (SWelsFuncPtrList* pFuncList, uint32_t uiCpuFlag) { · 12 unmodified lines
498591 McHorVer03WidthEq16, McHorVer13WidthEq16, McHorVer23WidthEq16, McHorVer33WidthEq16
499592 };
500593 #endif
594+#if defined(HAVE_NEON)
595+ static PWelsLumaQuarpelMcFunc pWelsMcFuncWidthEq16_neon[16] = { //[x][y]
596+ McCopyWidthEq16_neon, McHorVer10WidthEq16_neon, McHorVer20WidthEq16_neon, McHorVer30WidthEq16_neon,
597+ McHorVer01WidthEq16_neon, EncMcHorVer11_neon, EncMcHorVer21_neon, EncMcHorVer31_neon,
598+ McHorVer02WidthEq16_neon, EncMcHorVer12_neon, McHorVer22WidthEq16_neon, EncMcHorVer32_neon,
599+ McHorVer03WidthEq16_neon, EncMcHorVer13_neon, EncMcHorVer23_neon, EncMcHorVer33_neon
600+ };
601+#endif
501602
502603 pFuncList->sMcFuncs.pfLumaHalfpelHor = McHorVer20_c;
503604 pFuncList->sMcFuncs.pfLumaHalfpelVer = McHorVer02_c;
@@ -538,5 +639,17 @@ void WelsInitMcFuncs (SWelsFuncPtrList* pFuncList, uint32_t uiCpuFlag) { · 34 unmodified lines
538639 }
539640
540641 #endif //(X86_ASM)
642+
643+#if defined(HAVE_NEON)
644+ if (uiCpuFlag & WELS_CPU_NEON) {
645+ pFuncList->sMcFuncs.pfLumaQuarpelMc = pWelsMcFuncWidthEq16_neon;
646+ pFuncList->sMcFuncs.pfChromaMc = EncMcChroma_neon;
647+ pFuncList->sMcFuncs.pfSampleAveraging[0] = PixStrideAvgWidthEq8_neon;
648+ pFuncList->sMcFuncs.pfSampleAveraging[1] = PixStrideAvgWidthEq16_neon;
649+ pFuncList->sMcFuncs.pfLumaHalfpelHor = McHorVer20Width9Or17_neon;//iWidth+1:8/16
650+ pFuncList->sMcFuncs.pfLumaHalfpelVer = McHorVer02Height9Or17_neon;//heigh+1:8/16
651+ pFuncList->sMcFuncs.pfLumaHalfpelCen = McHorVer22Width9Or17Height9Or17_neon;//iWidth+1/heigh+1
652+ }
653+#endif
541654 }
542655 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t