ref: 249b8a0aa6b9e8fd7d0a1327d9b6dcd35af0900c
parent: c1a24d52f5e4ca96a0775dfe0f83cc22e43f3c8c
author: dongzhang <dongzha@cisco.com>
date: Tue Jul 8 10:17:38 EDT 2014
add arm64 MB COPY code and UT
--- a/codec/build/iOS/common/common.xcodeproj/project.pbxproj
+++ b/codec/build/iOS/common/common.xcodeproj/project.pbxproj
@@ -24,6 +24,7 @@
F556A8251906673900E156A8 /* expand_picture_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F556A8231906673900E156A8 /* expand_picture_aarch64_neon.S */; };
F5AC94FF193EB7D800F58154 /* deblocking_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F5AC94FE193EB7D800F58154 /* deblocking_aarch64_neon.S */; };
F5B8D82D190757290037849A /* mc_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F5B8D82C190757290037849A /* mc_aarch64_neon.S */; };
+ F5BB0BB8196BB5960072D50D /* copy_mb_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F5BB0BB7196BB5960072D50D /* copy_mb_aarch64_neon.S */; };
FAABAA1818E9354A00D4186F /* sad_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAABAA1718E9354A00D4186F /* sad_common.cpp */; };
/* End PBXBuildFile section */
@@ -72,6 +73,7 @@
F556A8231906673900E156A8 /* expand_picture_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = expand_picture_aarch64_neon.S; path = arm64/expand_picture_aarch64_neon.S; sourceTree = "<group>"; };
F5AC94FE193EB7D800F58154 /* deblocking_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = deblocking_aarch64_neon.S; path = arm64/deblocking_aarch64_neon.S; sourceTree = "<group>"; };
F5B8D82C190757290037849A /* mc_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = mc_aarch64_neon.S; path = arm64/mc_aarch64_neon.S; sourceTree = "<group>"; };
+ F5BB0BB7196BB5960072D50D /* copy_mb_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = copy_mb_aarch64_neon.S; path = arm64/copy_mb_aarch64_neon.S; sourceTree = "<group>"; };
FAABAA1618E9353F00D4186F /* sad_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sad_common.h; sourceTree = "<group>"; };
FAABAA1718E9354A00D4186F /* sad_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sad_common.cpp; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -177,6 +179,7 @@
F556A81D1906669F00E156A8 /* arm64 */ = {
isa = PBXGroup;
children = (
+ F5BB0BB7196BB5960072D50D /* copy_mb_aarch64_neon.S */,
F5AC94FE193EB7D800F58154 /* deblocking_aarch64_neon.S */,
F5B8D82C190757290037849A /* mc_aarch64_neon.S */,
F556A8221906673900E156A8 /* arm_arch64_common_macro.S */,
@@ -245,6 +248,7 @@
5BA8F2C019603F5F00011CE4 /* common_tables.cpp in Sources */,
4C3406D118D96EA600DFA14A /* WelsThreadLib.cpp in Sources */,
4C3406CC18D96EA600DFA14A /* mc_neon.S in Sources */,
+ F5BB0BB8196BB5960072D50D /* copy_mb_aarch64_neon.S in Sources */,
4C3406CB18D96EA600DFA14A /* expand_picture_neon.S in Sources */,
4CC61F0918FF6B4B00E56EAB /* copy_mb_neon.S in Sources */,
53C1C9BC193F0FB000404D8F /* expand_pic.cpp in Sources */,
--- /dev/null
+++ b/codec/common/arm64/copy_mb_aarch64_neon.S
@@ -1,0 +1,274 @@
+/*!
+ * \copy
+ * Copyright (c) 2013, Cisco Systems
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_NEON_AARCH64
+.text
+#include "arm_arch64_common_macro.S"
+
+#ifdef __APPLE__
+.macro LOAD_ALIGNED_DATA_WITH_STRIDE
+// { // input: $0~$3, src*, src_stride
+ ld1 {$0.d}[0], [$4], $5
+ ld1 {$1.d}[0], [$4], $5
+ ld1 {$2.d}[0], [$4], $5
+ ld1 {$3.d}[0], [$4], $5
+// }
+.endm
+
+.macro STORE_ALIGNED_DATA_WITH_STRIDE
+// { // input: $0~$3, dst*, dst_stride
+ st1 {$0.d}[0], [$4], $5
+ st1 {$1.d}[0], [$4], $5
+ st1 {$2.d}[0], [$4], $5
+ st1 {$3.d}[0], [$4], $5
+// }
+.endm
+
+.macro LOAD_UNALIGNED_DATA_WITH_STRIDE
+// { // input: $0~$3, src*, src_stride
+ ld1 {$0.8b}, [$4], $5
+ ld1 {$1.8b}, [$4], $5
+ ld1 {$2.8b}, [$4], $5
+ ld1 {$3.8b}, [$4], $5
+// }
+.endm
+
+.macro STORE_UNALIGNED_DATA_WITH_STRIDE
+// { // input: $0~$3, dst*, dst_stride
+ st1 {$0.8b}, [$4], $5
+ st1 {$1.8b}, [$4], $5
+ st1 {$2.8b}, [$4], $5
+ st1 {$3.8b}, [$4], $5
+// }
+.endm
+
+.macro LOAD16_ALIGNED_DATA_WITH_STRIDE
+// { // input: $0~$3, src*, src_stride
+ ld1 {$0.2d}, [$4], $5
+ ld1 {$1.2d}, [$4], $5
+ ld1 {$2.2d}, [$4], $5
+ ld1 {$3.2d}, [$4], $5
+// }
+.endm
+
+.macro STORE16_ALIGNED_DATA_WITH_STRIDE
+// { // input: $0~$3, dst*, dst_stride
+ st1 {$0.2d}, [$4], $5
+ st1 {$1.2d}, [$4], $5
+ st1 {$2.2d}, [$4], $5
+ st1 {$3.2d}, [$4], $5
+// }
+.endm
+
+.macro LOAD16_UNALIGNED_DATA_WITH_STRIDE
+// { // input: $0~$3, src*, src_stride
+ ld1 {$0.16b}, [$4], $5
+ ld1 {$1.16b}, [$4], $5
+ ld1 {$2.16b}, [$4], $5
+ ld1 {$3.16b}, [$4], $5
+// }
+.endm
+
+.macro STORE16_UNALIGNED_DATA_WITH_STRIDE
+// { // input: $0~$3, dst*, dst_stride
+ st1 {$0.16b}, [$4], $5
+ st1 {$1.16b}, [$4], $5
+ st1 {$2.16b}, [$4], $5
+ st1 {$3.16b}, [$4], $5
+// }
+.endm
+
+#else
+.macro LOAD_ALIGNED_DATA_WITH_STRIDE arg0, arg1, arg2, arg3, arg4, arg5
+// { // input: $0~$3, src*, src_stride
+ ld1 {\arg0\().d}[0], [\arg4], \arg5
+ ld1 {\arg1\().d}[0], [\arg4], \arg5
+ ld1 {\arg2\().d}[0], [\arg4], \arg5
+ ld1 {\arg3\().d}[0], [\arg4], \arg5
+// }
+.endm
+
+.macro STORE_ALIGNED_DATA_WITH_STRIDE arg0, arg1, arg2, arg3, arg4, arg5
+// { // input: $0~$3, dst*, dst_stride
+ st1 {\arg0\().d}[0], [\arg4], \arg5
+ st1 {\arg1\().d}[0], [\arg4], \arg5
+ st1 {\arg2\().d}[0], [\arg4], \arg5
+ st1 {\arg3\().d}[0], [\arg4], \arg5
+// }
+.endm
+
+.macro LOAD_UNALIGNED_DATA_WITH_STRIDE arg0, arg1, arg2, arg3, arg4, arg5
+// { // input: $0~$3, src*, src_stride
+ ld1 {\arg0\().8b}, [\arg4], \arg5
+ ld1 {\arg1\().8b}, [\arg4], \arg5
+ ld1 {\arg2\().8b}, [\arg4], \arg5
+ ld1 {\arg3\().8b}, [\arg4], \arg5
+// }
+.endm
+
+.macro STORE_UNALIGNED_DATA_WITH_STRIDE arg0, arg1, arg2, arg3, arg4, arg5
+// { // input: $0~$3, dst*, dst_stride
+ st1 {\arg0\().8b}, [\arg4], \arg5
+ st1 {\arg1\().8b}, [\arg4], \arg5
+ st1 {\arg2\().8b}, [\arg4], \arg5
+ st1 {\arg3\().8b}, [\arg4], \arg5
+// }
+.endm
+
+.macro LOAD16_ALIGNED_DATA_WITH_STRIDE arg0, arg1, arg2, arg3, arg4, arg5
+// { // input: $0~$3, src*, src_stride
+ ld1 {\arg0\().2d}, [\arg4], \arg5
+ ld1 {\arg1\().2d}, [\arg4], \arg5
+ ld1 {\arg2\().2d}, [\arg4], \arg5
+ ld1 {\arg3\().2d}, [\arg4], \arg5
+// }
+.endm
+
+.macro STORE16_ALIGNED_DATA_WITH_STRIDE arg0, arg1, arg2, arg3, arg4, arg5
+// { // input: $0~$3, dst*, dst_stride
+ st1 {\arg0\().2d}, [\arg4], \arg5
+ st1 {\arg1\().2d}, [\arg4], \arg5
+ st1 {\arg2\().2d}, [\arg4], \arg5
+ st1 {\arg3\().2d}, [\arg4], \arg5
+// }
+.endm
+
+.macro LOAD16_UNALIGNED_DATA_WITH_STRIDE arg0, arg1, arg2, arg3, arg4, arg5
+// { // input: $0~$3, src*, src_stride
+ ld1 {\arg0\().16b}, [\arg4], \arg5
+ ld1 {\arg1\().16b}, [\arg4], \arg5
+ ld1 {\arg2\().16b}, [\arg4], \arg5
+ ld1 {\arg3\().16b}, [\arg4], \arg5
+// }
+.endm
+
+.macro STORE16_UNALIGNED_DATA_WITH_STRIDE arg0, arg1, arg2, arg3, arg4, arg5
+// { // input: $0~$3, dst*, dst_stride
+ st1 {\arg0\().16b}, [\arg4], \arg5
+ st1 {\arg1\().16b}, [\arg4], \arg5
+ st1 {\arg2\().16b}, [\arg4], \arg5
+ st1 {\arg3\().16b}, [\arg4], \arg5
+// }
+.endm
+
+#endif
+
+
+WELS_ASM_AARCH64_FUNC_BEGIN WelsCopy8x8_AArch64_neon
+
+ LOAD_UNALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x2, x3
+
+ STORE_UNALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x0, x1
+
+ LOAD_UNALIGNED_DATA_WITH_STRIDE v4, v5, v6, v7, x2, x3
+
+ STORE_UNALIGNED_DATA_WITH_STRIDE v4, v5, v6, v7, x0, x1
+
+WELS_ASM_AARCH64_FUNC_END
+
+
+WELS_ASM_AARCH64_FUNC_BEGIN WelsCopy16x16_AArch64_neon
+
+ LOAD16_ALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x2, x3
+
+ STORE16_ALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x0, x1
+
+ LOAD16_ALIGNED_DATA_WITH_STRIDE v16, v17, v18, v19, x2, x3
+
+ STORE16_ALIGNED_DATA_WITH_STRIDE v16, v17, v18, v19, x0, x1
+
+ LOAD16_ALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x2, x3
+
+ STORE16_ALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x0, x1
+
+ LOAD16_ALIGNED_DATA_WITH_STRIDE v16, v17, v18, v19, x2, x3
+
+ STORE16_ALIGNED_DATA_WITH_STRIDE v16, v17, v18, v19, x0, x1
+
+WELS_ASM_AARCH64_FUNC_END
+
+
+WELS_ASM_AARCH64_FUNC_BEGIN WelsCopy16x16NotAligned_AArch64_neon
+
+ LOAD16_UNALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x2, x3
+
+ STORE16_UNALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x0, x1
+
+ LOAD16_UNALIGNED_DATA_WITH_STRIDE v16, v17, v18, v19, x2, x3
+
+ STORE16_UNALIGNED_DATA_WITH_STRIDE v16, v17, v18, v19, x0, x1
+
+ LOAD16_UNALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x2, x3
+
+ STORE16_UNALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x0, x1
+
+ LOAD16_UNALIGNED_DATA_WITH_STRIDE v16, v17, v18, v19, x2, x3
+
+ STORE16_UNALIGNED_DATA_WITH_STRIDE v16, v17, v18, v19, x0, x1
+
+WELS_ASM_AARCH64_FUNC_END
+
+
+WELS_ASM_AARCH64_FUNC_BEGIN WelsCopy16x8NotAligned_AArch64_neon
+
+ LOAD16_UNALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x2, x3
+
+ STORE16_UNALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x0, x1
+
+ LOAD16_UNALIGNED_DATA_WITH_STRIDE v16, v17, v18, v19, x2, x3
+
+ STORE16_UNALIGNED_DATA_WITH_STRIDE v16, v17, v18, v19, x0, x1
+
+WELS_ASM_AARCH64_FUNC_END
+
+
+WELS_ASM_AARCH64_FUNC_BEGIN WelsCopy8x16_AArch64_neon
+
+ LOAD_UNALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x2, x3
+
+ STORE_UNALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x0, x1
+
+ LOAD_UNALIGNED_DATA_WITH_STRIDE v4, v5, v6, v7, x2, x3
+
+ STORE_UNALIGNED_DATA_WITH_STRIDE v4, v5, v6, v7, x0, x1
+
+ LOAD_UNALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x2, x3
+
+ STORE_UNALIGNED_DATA_WITH_STRIDE v0, v1, v2, v3, x0, x1
+
+ LOAD_UNALIGNED_DATA_WITH_STRIDE v4, v5, v6, v7, x2, x3
+
+ STORE_UNALIGNED_DATA_WITH_STRIDE v4, v5, v6, v7, x0, x1
+
+WELS_ASM_AARCH64_FUNC_END
+
+#endif
--- a/codec/common/inc/copy_mb.h
+++ b/codec/common/inc/copy_mb.h
@@ -65,6 +65,14 @@
void WelsCopy8x16_neon (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);
#endif
+#if defined (HAVE_NEON_AARCH64)
+void WelsCopy8x8_AArch64_neon (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);
+void WelsCopy16x16_AArch64_neon (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);
+void WelsCopy16x16NotAligned_AArch64_neon (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);
+void WelsCopy16x8NotAligned_AArch64_neon (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);
+void WelsCopy8x16_AArch64_neon (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);
+#endif
+
#if defined(__cplusplus)
}
#endif//__cplusplus
--- a/codec/common/targets.mk
+++ b/codec/common/targets.mk
@@ -39,6 +39,7 @@
ifeq ($(ASM_ARCH), arm64)
COMMON_ASM_ARM64_SRCS=\
+ $(COMMON_SRCDIR)/arm64/copy_mb_aarch64_neon.S\
$(COMMON_SRCDIR)/arm64/deblocking_aarch64_neon.S\
$(COMMON_SRCDIR)/arm64/expand_picture_aarch64_neon.S\
$(COMMON_SRCDIR)/arm64/mc_aarch64_neon.S\
--- a/codec/encoder/core/src/encode_mb_aux.cpp
+++ b/codec/encoder/core/src/encode_mb_aux.cpp
@@ -553,8 +553,8 @@
pFuncList->pfQuantizationHadamard2x2 = WelsHadamardQuant2x2_AArch64_neon;
pFuncList->pfQuantizationHadamard2x2Skip = WelsHadamardQuant2x2Skip_AArch64_neon;
pFuncList->pfDctT4 = WelsDctT4_AArch64_neon;
- //pFuncList->pfCopy8x8Aligned = WelsCopy8x8_AArch64_neon; // will enable in next update
- //pFuncList->pfCopy8x16Aligned = WelsCopy8x16_AArch64_neon; // will enable in next update
+ pFuncList->pfCopy8x8Aligned = WelsCopy8x8_AArch64_neon;
+ pFuncList->pfCopy8x16Aligned = WelsCopy8x16_AArch64_neon;
pFuncList->pfGetNoneZeroCount = WelsGetNoneZeroCount_AArch64_neon;
pFuncList->pfTransformHadamard4x4Dc = WelsHadamardT4Dc_AArch64_neon;
@@ -564,9 +564,9 @@
pFuncList->pfQuantizationFour4x4 = WelsQuantFour4x4_AArch64_neon;
pFuncList->pfQuantizationFour4x4Max = WelsQuantFour4x4Max_AArch64_neon;
- //pFuncList->pfCopy16x16Aligned = WelsCopy16x16_AArch64_neon; // will enable in next update
- //pFuncList->pfCopy16x16NotAligned = WelsCopy16x16NotAligned_AArch64_neon; // will enable in next update
- //pFuncList->pfCopy16x8NotAligned = WelsCopy16x8NotAligned_AArch64_neon; // will enable in next update
+ pFuncList->pfCopy16x16Aligned = WelsCopy16x16_AArch64_neon;
+ pFuncList->pfCopy16x16NotAligned = WelsCopy16x16NotAligned_AArch64_neon;
+ pFuncList->pfCopy16x8NotAligned = WelsCopy16x8NotAligned_AArch64_neon;
pFuncList->pfDctFourT4 = WelsDctFourT4_AArch64_neon;
}
#endif
--- /dev/null
+++ b/test/encoder/EncUT_MBCopy.cpp
@@ -1,0 +1,140 @@
+#include <gtest/gtest.h>
+#include <math.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "cpu_core.h"
+#include "cpu.h"
+#include "macros.h"
+#include "encode_mb_aux.h"
+#include "wels_func_ptr_def.h"
+#include "copy_mb.h"
+
+using namespace WelsSVCEnc;
+#define MBCOPYTEST_NUM 1000
+static void FillWithRandomData (uint8_t* p, int32_t Len) {
+ for (int32_t i = 0; i < Len; i++) {
+ p[i] = rand() % 256;
+ }
+}
+
+
+TEST (MBCopyFunTest, pfCopy8x8Aligned) {
+ ENFORCE_STACK_ALIGN_1D (uint8_t, pSrcAlign, 16 * 64 + 1, 16)
+ ENFORCE_STACK_ALIGN_2D (uint8_t, pDstAlign, 2, 16 * 32 + 16, 16)
+
+ int32_t iCpuCores = 0;
+ SWelsFuncPtrList sFuncPtrList;
+ uint32_t m_uiCpuFeatureFlag = WelsCPUFeatureDetect (&iCpuCores);
+ WelsInitEncodingFuncs (&sFuncPtrList, m_uiCpuFeatureFlag);
+
+ for (int32_t k = 0; k < MBCOPYTEST_NUM; k++) {
+ memset (pDstAlign[0], 0, 16 * 32 + 1);
+ memset (pDstAlign[1], 0, 16 * 32 + 1);
+ FillWithRandomData ((uint8_t*)pSrcAlign, 16 * 64 + 1);
+ WelsCopy8x8_c (pDstAlign[0], 32, pSrcAlign, 64);
+ sFuncPtrList.pfCopy8x8Aligned (pDstAlign[1], 32, pSrcAlign, 64);
+
+ for (int32_t i = 0; i < 16 * 32 + 1; i++) {
+ ASSERT_EQ (pDstAlign[0][i], pDstAlign[1][i]);
+ }
+
+ }
+
+}
+
+TEST (MBCopyFunTest, pfCopy8x16Aligned) {
+ ENFORCE_STACK_ALIGN_1D (uint8_t, pSrcAlign, 16 * 64 + 1, 16)
+ ENFORCE_STACK_ALIGN_2D (uint8_t, pDstAlign, 2, 16 * 32 + 16, 16)
+
+ int32_t iCpuCores = 0;
+ SWelsFuncPtrList sFuncPtrList;
+ uint32_t m_uiCpuFeatureFlag = WelsCPUFeatureDetect (&iCpuCores);
+ WelsInitEncodingFuncs (&sFuncPtrList, m_uiCpuFeatureFlag);
+
+ for (int32_t k = 0; k < MBCOPYTEST_NUM; k++) {
+ memset (pDstAlign[0], 0, 16 * 32 + 1);
+ memset (pDstAlign[1], 0, 16 * 32 + 1);
+ FillWithRandomData ((uint8_t*)pSrcAlign, 16 * 64 + 1);
+ WelsCopy8x16_c (pDstAlign[0], 32, pSrcAlign, 64);
+ sFuncPtrList.pfCopy8x16Aligned (pDstAlign[1], 32, pSrcAlign, 64);
+
+ for (int32_t i = 0; i < 16 * 32 + 1; i++) {
+ ASSERT_EQ (pDstAlign[0][i], pDstAlign[1][i]);
+ }
+
+ }
+
+}
+
+TEST (MBCopyFunTest, pfCopy16x16Aligned) {
+ ENFORCE_STACK_ALIGN_1D (uint8_t, pSrcAlign, 16 * 64 + 1, 16)
+ ENFORCE_STACK_ALIGN_2D (uint8_t, pDstAlign, 2, 16 * 32 + 16, 16)
+
+ int32_t iCpuCores = 0;
+ SWelsFuncPtrList sFuncPtrList;
+ uint32_t m_uiCpuFeatureFlag = WelsCPUFeatureDetect (&iCpuCores);
+ WelsInitEncodingFuncs (&sFuncPtrList, m_uiCpuFeatureFlag);
+
+ for (int32_t k = 0; k < MBCOPYTEST_NUM; k++) {
+ memset (pDstAlign[0], 0, 16 * 32 + 1);
+ memset (pDstAlign[1], 0, 16 * 32 + 1);
+ FillWithRandomData ((uint8_t*)pSrcAlign, 16 * 64 + 1);
+ WelsCopy16x16_c (pDstAlign[0], 32, pSrcAlign, 64);
+ sFuncPtrList.pfCopy16x16Aligned (pDstAlign[1], 32, pSrcAlign, 64);
+
+ for (int32_t i = 0; i < 16 * 32 + 1; i++) {
+ ASSERT_EQ (pDstAlign[0][i], pDstAlign[1][i]);
+ }
+
+ }
+
+}
+
+TEST (MBCopyFunTest, pfCopy16x8NotAligned) {
+ ENFORCE_STACK_ALIGN_1D (uint8_t, pSrcAlign, 16 * 64 + 1, 16)
+ ENFORCE_STACK_ALIGN_2D (uint8_t, pDstAlign, 2, 16 * 32 + 16, 16)
+
+ int32_t iCpuCores = 0;
+ SWelsFuncPtrList sFuncPtrList;
+ uint32_t m_uiCpuFeatureFlag = WelsCPUFeatureDetect (&iCpuCores);
+ WelsInitEncodingFuncs (&sFuncPtrList, m_uiCpuFeatureFlag);
+
+ for (int32_t k = 0; k < MBCOPYTEST_NUM; k++) {
+ memset (pDstAlign[0], 0, 16 * 32 + 1);
+ memset (pDstAlign[1], 0, 16 * 32 + 1);
+ FillWithRandomData ((uint8_t*)pSrcAlign, 16 * 64 + 1);
+ WelsCopy16x8_c (pDstAlign[0], 32, pSrcAlign + 1, 64);
+ sFuncPtrList.pfCopy16x8NotAligned (pDstAlign[1], 32, pSrcAlign + 1, 64);
+
+ for (int32_t i = 0; i < 16 * 32 + 1; i++) {
+ ASSERT_EQ (pDstAlign[0][i], pDstAlign[1][i]);
+ }
+
+ }
+
+}
+
+TEST (MBCopyFunTest, pfCopy16x16NotAligned) {
+ ENFORCE_STACK_ALIGN_1D (uint8_t, pSrcAlign, 16 * 64 + 1, 16)
+ ENFORCE_STACK_ALIGN_2D (uint8_t, pDstAlign, 2, 16 * 32 + 16, 16)
+
+ int32_t iCpuCores = 0;
+ SWelsFuncPtrList sFuncPtrList;
+ uint32_t m_uiCpuFeatureFlag = WelsCPUFeatureDetect (&iCpuCores);
+ WelsInitEncodingFuncs (&sFuncPtrList, m_uiCpuFeatureFlag);
+
+ for (int32_t k = 0; k < MBCOPYTEST_NUM; k++) {
+ memset (pDstAlign[0], 0, 16 * 32 + 1);
+ memset (pDstAlign[1], 0, 16 * 32 + 1);
+ FillWithRandomData ((uint8_t*)pSrcAlign, 16 * 64 + 1);
+ WelsCopy16x16_c (pDstAlign[0], 32, pSrcAlign + 1, 64);
+ sFuncPtrList.pfCopy16x16NotAligned (pDstAlign[1], 32, pSrcAlign + 1, 64);
+
+ for (int32_t i = 0; i < 16 * 32 + 1; i++) {
+ ASSERT_EQ (pDstAlign[0][i], pDstAlign[1][i]);
+ }
+
+ }
+
+}
--- a/test/encoder/targets.mk
+++ b/test/encoder/targets.mk
@@ -6,6 +6,7 @@
$(ENCODER_UNITTEST_SRCDIR)/EncUT_EncoderMbAux.cpp\
$(ENCODER_UNITTEST_SRCDIR)/EncUT_ExpGolomb.cpp\
$(ENCODER_UNITTEST_SRCDIR)/EncUT_GetIntraPredictor.cpp\
+ $(ENCODER_UNITTEST_SRCDIR)/EncUT_MBCopy.cpp\
$(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryAlloc.cpp\
$(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryZero.cpp\
$(ENCODER_UNITTEST_SRCDIR)/EncUT_MotionEstimate.cpp\