ref: 9f0d51d8d28046fa9614f4eb5ea9a0f09d3fa847
parent: d04c7b93473afad575104ab8130a3fd16c236858
author: Guangwei Wang <guangwwa@cisco.com>
date: Tue Jul 7 06:13:56 EDT 2015
add new AArch32 asm functions to support sub8x8 mode
--- a/codec/common/arm/mc_neon.S
+++ b/codec/common/arm/mc_neon.S
@@ -1635,6 +1635,36 @@
WELS_ASM_FUNC_END
+WELS_ASM_FUNC_BEGIN McHorVer20Width5_neon
+ push {r4}
+ sub r3, #4
+ sub r0, #2
+ ldr r4, [sp, #4]
+ vmov.u16 q14, #0x0014 // 20
+ vshr.u16 q15, q14, #2 // 5
+
+w5_h_mc_luma_loop:
+ vld1.u8 {d0,d1}, [r0], r1 //only use 10(5+5); q0=src[-2]
+ pld [r0]
+
+ vext.8 d2, d0, d1, #1 //d2=src[-1]
+ vext.8 d3, d0, d1, #2 //d3=src[0]
+ vext.8 d4, d0, d1, #3 //d4=src[1]
+ vext.8 d5, d0, d1, #4 //d5=src[2]
+ vext.8 d6, d0, d1, #5 //d6=src[3]
+
+ FILTER_6TAG_8BITS d0, d2, d3, d4, d5, d6, d16, q14, q15
+
+ sub r4, #1
+ vst1.u32 {d16[0]}, [r2]! //write [0:3] Byte
+ vst1.u8 {d16[4]}, [r2], r3 //write 5th Byte
+
+ cmp r4, #0
+ bne w5_h_mc_luma_loop
+ pop {r4}
+WELS_ASM_FUNC_END
+
+
WELS_ASM_FUNC_BEGIN McHorVer02Height17_neon
push {r4}
ldr r4, [sp, #4]
@@ -1780,6 +1810,63 @@
WELS_ASM_FUNC_END
+WELS_ASM_FUNC_BEGIN McHorVer02Height5_neon
+ push {r4}
+ ldr r4, [sp, #4]
+
+ sub r0, r0, r1, lsl #1 //src[-2*src_stride]
+ pld [r0]
+ pld [r0, r1]
+ vmov.u16 q14, #0x0014 // 20
+ vld1.u8 {d0}, [r0], r1 //d0=src[-2]
+ vld1.u8 {d1}, [r0], r1 //d1=src[-1]
+
+ pld [r0]
+ pld [r0, r1]
+ vshr.u16 q15, q14, #2 // 5
+ vld1.u8 {d2}, [r0], r1 //d2=src[0]
+ vld1.u8 {d3}, [r0], r1 //d3=src[1]
+
+ vld1.u8 {d4}, [r0], r1 //d4=src[2]
+ vld1.u8 {d5}, [r0], r1 //d5=src[3]
+
+w5_v_mc_luma_loop:
+
+ pld [r0]
+ FILTER_6TAG_8BITS d0, d1, d2, d3, d4, d5, d16, q14, q15
+ vld1.u8 {d0}, [r0], r1 //read 2nd row
+ vst1.u32 {d16[0]}, [r2], r3 //write 1st 4Byte
+
+ pld [r0]
+ FILTER_6TAG_8BITS d1, d2, d3, d4, d5, d0, d16, q14, q15
+ vld1.u8 {d1}, [r0], r1 //read 3rd row
+ vst1.u32 {d16[0]}, [r2], r3 //write 2nd 4Byte
+
+ pld [r0]
+ FILTER_6TAG_8BITS d2, d3, d4, d5, d0, d1, d16, q14, q15
+ vld1.u8 {d2}, [r0], r1 //read 4th row
+ vst1.u32 {d16[0]}, [r2], r3 //write 3rd 4Byte
+
+ pld [r0]
+ FILTER_6TAG_8BITS d3, d4, d5, d0, d1, d2, d16, q14, q15
+ vld1.u8 {d3}, [r0], r1 //read 5th row
+ vst1.u32 {d16[0]}, [r2], r3 //write 4th 8Byte
+
+ //d4, d5, d0, d1, d2, d3 --> d0, d1, d2, d3, d4, d5
+ vswp q0, q2
+ vswp q1, q2
+
+ sub r4, #4
+ cmp r4, #1
+ bne w5_v_mc_luma_loop
+
+ FILTER_6TAG_8BITS d0, d1, d2, d3, d4, d5, d16, q14, q15
+ vst1.u32 {d16[0]}, [r2], r3 //write last 4Byte
+
+ pop {r4}
+WELS_ASM_FUNC_END
+
+
WELS_ASM_FUNC_BEGIN McHorVer22Width17_neon
push {r4}
vpush {q4-q7}
@@ -2014,6 +2101,105 @@
vst1.u8 d18, [r2]! //write 8Byte
UNPACK_1_IN_8x16BITS_TO_8BITS d19, d20, d21, q10 //output to d19[0]
vst1.u8 {d19[0]}, [r2], r3 //write 8th Byte
+ vpop {q4}
+ pop {r4}
+WELS_ASM_FUNC_END
+
+
+WELS_ASM_FUNC_BEGIN McHorVer22Width5_neon
+ push {r4}
+ vpush {q4}
+ ldr r4, [sp, #20]
+
+ sub r0, #2 //src[-2]
+ sub r0, r0, r1, lsl #1 //src[-2*src_stride-2]
+ pld [r0]
+ pld [r0, r1]
+
+ vmov.u16 q14, #0x0014 // 20
+ vld1.u8 {q0}, [r0], r1 //use 10(5+5), =src[-2]
+ vld1.u8 {q1}, [r0], r1 //use 10(5+5), =src[-1]
+
+ pld [r0]
+ pld [r0, r1]
+ vshr.u16 q15, q14, #2 // 5
+
+ vld1.u8 {q2}, [r0], r1 //use 10(5+5), =src[0]
+ vld1.u8 {q3}, [r0], r1 //use 10(5+5), =src[1]
+ pld [r0]
+ pld [r0, r1]
+ vld1.u8 {q4}, [r0], r1 //use 10(5+5), =src[2]
+ sub r3, #4
+
+w5_hv_mc_luma_loop:
+
+ vld1.u8 {q8}, [r0], r1 //use 10(5+5), =src[3]
+ //the 1st row
+ pld [r0]
+ // vertical filtered into q9/q10
+ FILTER_6TAG_8BITS_TO_16BITS d0, d2, d4, d6, d8, d16, q9, q14, q15
+ FILTER_6TAG_8BITS_TO_16BITS d1, d3, d5, d7, d9, d17, q10, q14, q15
+ // horizon filtered
+ UNPACK_2_16BITS_TO_ABC q9, q10, q11, q12, q13
+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18
+ vst1.u32 {d18[0]}, [r2]! //write 4Byte
+ vst1.u8 {d18[4]}, [r2], r3 //write 5th Byte
+
+ vld1.u8 {q0}, [r0], r1 //read 2nd row
+ //the 2nd row
+ pld [r0]
+ // vertical filtered into q9/q10
+ FILTER_6TAG_8BITS_TO_16BITS d2, d4, d6, d8, d16, d0, q9, q14, q15
+ FILTER_6TAG_8BITS_TO_16BITS d3, d5, d7, d9, d17, d1, q10, q14, q15
+ // horizon filtered
+ UNPACK_2_16BITS_TO_ABC q9, q10, q11, q12, q13
+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18
+ vst1.u32 {d18[0]}, [r2]! //write 4Byte
+ vst1.u8 {d18[4]}, [r2], r3 //write 5th Byte
+
+ vld1.u8 {q1}, [r0], r1 //read 3rd row
+ //the 3rd row
+ pld [r0]
+ // vertical filtered into q9/q10
+ FILTER_6TAG_8BITS_TO_16BITS d4, d6, d8, d16, d0, d2, q9, q14, q15
+ FILTER_6TAG_8BITS_TO_16BITS d5, d7, d9, d17, d1, d3, q10, q14, q15
+ // horizon filtered
+ UNPACK_2_16BITS_TO_ABC q9, q10, q11, q12, q13
+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18
+ vst1.u32 {d18[0]}, [r2]! //write 4Byte
+ vst1.u8 {d18[4]}, [r2], r3 //write 5th Byte
+
+ vld1.u8 {q2}, [r0], r1 //read 4th row
+ //the 4th row
+ pld [r0]
+ // vertical filtered into q9/q10
+ FILTER_6TAG_8BITS_TO_16BITS d6, d8, d16, d0, d2, d4, q9, q14, q15
+ FILTER_6TAG_8BITS_TO_16BITS d7, d9, d17, d1, d3, d5, q10, q14, q15
+ // horizon filtered
+ UNPACK_2_16BITS_TO_ABC q9, q10, q11, q12, q13
+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18
+ vst1.u32 {d18[0]}, [r2]! //write 4Byte
+ vst1.u8 {d18[4]}, [r2], r3 //write 5th Byte
+
+ //q4~q8, q0~q2, --> q0~q4
+ vswp q0, q4
+ vswp q2, q4
+ vmov q3, q1
+ vmov q1, q8
+
+ sub r4, #4
+ cmp r4, #1
+ bne w5_hv_mc_luma_loop
+ //the last row
+ vld1.u8 {q8}, [r0], r1 //use 10(5+5), =src[3]
+ // vertical filtered into q9/q10
+ FILTER_6TAG_8BITS_TO_16BITS d0, d2, d4, d6, d8, d16, q9, q14, q15
+ FILTER_6TAG_8BITS_TO_16BITS d1, d3, d5, d7, d9, d17, q10, q14, q15
+ // horizon filtered
+ UNPACK_2_16BITS_TO_ABC q9, q10, q11, q12, q13
+ FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18
+ vst1.u32 {d18[0]}, [r2]! //write 4Byte
+ vst1.u8 {d18[4]}, [r2], r3 //write 5th Byte
vpop {q4}
pop {r4}
WELS_ASM_FUNC_END
--- a/codec/common/inc/mc.h
+++ b/codec/common/inc/mc.h
@@ -140,15 +140,21 @@
int32_t iHeight);// width+1
void McHorVer20Width9_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iHeight);// width+1
+void McHorVer20Width5_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
+ int32_t iHeight);// width+1
void McHorVer02Height17_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iHeight);// height+1
void McHorVer02Height9_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iHeight);// height+1
+void McHorVer02Height5_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
+ int32_t iHeight);// height+1
void McHorVer22Width17_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iHeight);//width+1&&height+1
void McHorVer22Width9_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
+ int32_t iHeight);//width+1&&height+1
+void McHorVer22Width5_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iHeight);//width+1&&height+1
#endif
--- a/codec/common/src/mc.cpp
+++ b/codec/common/src/mc.cpp
@@ -716,26 +716,32 @@
// NEON implementation //
//***************************************************************************//
#if defined(HAVE_NEON)
-void McHorVer20Width9Or17_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
+void McHorVer20Width5Or9Or17_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
if (iWidth == 17)
McHorVer20Width17_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
- else //if (iWidth == 9)
+ else if (iWidth == 9)
McHorVer20Width9_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
+ else //if (iWidth == 5)
+ McHorVer20Width5_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
}
-void McHorVer02Height9Or17_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
+void McHorVer02Height5Or9Or17_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
if (iWidth == 16)
McHorVer02Height17_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
- else //if (iWidth == 8)
+ else if (iWidth == 8)
McHorVer02Height9_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
+ else //if (iWidth == 4)
+ McHorVer02Height5_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
}
-void McHorVer22Width9Or17Height9Or17_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
+void McHorVer22Width5Or9Or17Height5Or9Or17_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
if (iWidth == 17)
McHorVer22Width17_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
- else //if (iWidth == 9)
+ else if (iWidth == 9)
McHorVer22Width9_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
+ else //if (iWidth == 5)
+ McHorVer22Width5_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
}
void McCopy_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
@@ -1311,9 +1317,9 @@
pMcFuncs->pMcLumaFunc = McLuma_neon;
pMcFuncs->pMcChromaFunc = McChroma_neon;
pMcFuncs->pfSampleAveraging = PixelAvg_neon;
- pMcFuncs->pfLumaHalfpelHor = McHorVer20Width9Or17_neon;//iWidth+1:8/16
- pMcFuncs->pfLumaHalfpelVer = McHorVer02Height9Or17_neon;//heigh+1:8/16
- pMcFuncs->pfLumaHalfpelCen = McHorVer22Width9Or17Height9Or17_neon;//iWidth+1/heigh+1
+ pMcFuncs->pfLumaHalfpelHor = McHorVer20Width5Or9Or17_neon;//iWidth+1:4/8/16
+ pMcFuncs->pfLumaHalfpelVer = McHorVer02Height5Or9Or17_neon;//heigh+1:4/8/16
+ pMcFuncs->pfLumaHalfpelCen = McHorVer22Width5Or9Or17Height5Or9Or17_neon;//iWidth+1/heigh+1
}
#endif
#if defined(HAVE_NEON_AARCH64)