<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Nov 4, 2013 at 5:05 AM, Min Chen <span dir="ltr"><<a href="mailto:chenm003@163.com" target="_blank">chenm003@163.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Min Chen <<a href="mailto:chenm003@163.com">chenm003@163.com</a>><br>
# Date 1383563104 -28800<br>
# Node ID 539ad4851359f96591f612f8b7b6fb0483e5a48c<br>
# Parent  2a7a5766fbd84436cdbbd5018a34db92e62553a1<br>
asm: ipfilter_ss[FILTER_V_S_S_8]<br></blockquote><div><br></div><div>When this patch is applied, the testbench enters an infinite loop in this function</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
diff -r 2a7a5766fbd8 -r 539ad4851359 source/Lib/TLibCommon/TComPrediction.cpp<br>
--- a/source/Lib/TLibCommon/TComPrediction.cpp  Mon Nov 04 19:04:43 2013 +0800<br>
+++ b/source/Lib/TLibCommon/TComPrediction.cpp  Mon Nov 04 19:05:04 2013 +0800<br>
@@ -537,7 +537,7 @@<br>
         int filterSize = NTAPS_LUMA;<br>
         int halfFilterSize = (filterSize >> 1);<br>
         primitives.ipfilter_ps[FILTER_H_P_S_8](ref - (halfFilterSize - 1) * refStride, refStride, m_immedVals, tmpStride, width, height + filterSize - 1, g_lumaFilter[xFrac]);<br>
-        primitives.ipfilter_ss[FILTER_V_S_S_8](m_immedVals + (halfFilterSize - 1) * tmpStride, tmpStride, dst, dstStride, width, height, g_lumaFilter[yFrac]);<br>
+        primitives.ipfilter_ss[FILTER_V_S_S_8](m_immedVals + (halfFilterSize - 1) * tmpStride, tmpStride, dst, dstStride, width, height, yFrac);<br>
     }<br>
 }<br>
<br>
@@ -643,9 +643,9 @@<br>
         int filterSize = NTAPS_CHROMA;<br>
         int halfFilterSize = (filterSize >> 1);<br>
         primitives.ipfilter_ps[FILTER_H_P_S_4](refCb - (halfFilterSize - 1) * refStride, refStride, m_immedVals, extStride, cxWidth, cxHeight + filterSize - 1, g_chromaFilter[xFrac]);<br>
-        primitives.ipfilter_ss[FILTER_V_S_S_4](m_immedVals + (halfFilterSize - 1) * extStride, extStride, dstCb, dstStride, cxWidth, cxHeight, g_chromaFilter[yFrac]);<br>
+        primitives.ipfilter_ss[FILTER_V_S_S_4](m_immedVals + (halfFilterSize - 1) * extStride, extStride, dstCb, dstStride, cxWidth, cxHeight, yFrac);<br>
         primitives.ipfilter_ps[FILTER_H_P_S_4](refCr - (halfFilterSize - 1) * refStride, refStride, m_immedVals, extStride, cxWidth, cxHeight + filterSize - 1, g_chromaFilter[xFrac]);<br>
-        primitives.ipfilter_ss[FILTER_V_S_S_4](m_immedVals + (halfFilterSize - 1) * extStride, extStride, dstCr, dstStride, cxWidth, cxHeight, g_chromaFilter[yFrac]);<br>
+        primitives.ipfilter_ss[FILTER_V_S_S_4](m_immedVals + (halfFilterSize - 1) * extStride, extStride, dstCr, dstStride, cxWidth, cxHeight, yFrac);<br>
     }<br>
 }<br>
<br>
diff -r 2a7a5766fbd8 -r 539ad4851359 source/common/ipfilter.cpp<br>
--- a/source/common/ipfilter.cpp        Mon Nov 04 19:04:43 2013 +0800<br>
+++ b/source/common/ipfilter.cpp        Mon Nov 04 19:05:04 2013 +0800<br>
@@ -120,8 +120,9 @@<br>
 }<br>
<br>
 template<int N><br>
-void filterVertical_ss_c(int16_t *src, intptr_t srcStride, int16_t *dst, intptr_t dstStride, int width, int height, int16_t const *c)<br>
+void filterVertical_ss_c(int16_t *src, intptr_t srcStride, int16_t *dst, intptr_t dstStride, int width, int height, const int coefIdx)<br>
 {<br>
+    const int16_t *const c = (N == 8 ? g_lumaFilter[coefIdx] : g_chromaFilter[coefIdx]);<br>
     int shift = IF_FILTER_PREC;<br>
     int row, col;<br>
     src -= (N / 2 - 1) * srcStride;<br>
diff -r 2a7a5766fbd8 -r 539ad4851359 source/common/primitives.h<br>
--- a/source/common/primitives.h        Mon Nov 04 19:04:43 2013 +0800<br>
+++ b/source/common/primitives.h        Mon Nov 04 19:05:04 2013 +0800<br>
@@ -166,7 +166,7 @@<br>
 typedef void (*ipfilter_pp_t)(pixel *src, intptr_t srcStride, pixel *dst, intptr_t dstStride, int width, int height, const int16_t *coeff);<br>
 typedef void (*ipfilter_ps_t)(pixel *src, intptr_t srcStride, int16_t *dst, intptr_t dstStride, int width, int height, const int16_t *coeff);<br>
 typedef void (*ipfilter_sp_t)(int16_t *src, intptr_t srcStride, pixel *dst, intptr_t dstStride, int width, int height, const int coeffIdx);<br>
-typedef void (*ipfilter_ss_t)(int16_t *src, intptr_t srcStride, int16_t *dst, intptr_t dstStride, int width, int height, const int16_t *coeff);<br>
+typedef void (*ipfilter_ss_t)(int16_t *src, intptr_t srcStride, int16_t *dst, intptr_t dstStride, int width, int height, const int coeffIdx);<br>
 typedef void (*ipfilter_p2s_t)(pixel *src, intptr_t srcStride, int16_t *dst, intptr_t dstStride, int width, int height);<br>
 typedef void (*ipfilter_s2p_t)(int16_t *src, intptr_t srcStride, pixel *dst, intptr_t dstStride, int width, int height);<br>
 typedef void (*blockcpy_pp_t)(int bx, int by, pixel *dst, intptr_t dstride, pixel *src, intptr_t sstride); // dst is aligned<br>
diff -r 2a7a5766fbd8 -r 539ad4851359 source/common/x86/asm-primitives.cpp<br>
--- a/source/common/x86/asm-primitives.cpp      Mon Nov 04 19:04:43 2013 +0800<br>
+++ b/source/common/x86/asm-primitives.cpp      Mon Nov 04 19:05:04 2013 +0800<br>
@@ -279,6 +279,7 @@<br>
         SA8D_INTER_FROM_BLOCK(sse2);<br>
<br>
         p.cvt32to16_shr = x265_cvt32to16_shr_sse2;<br>
+        p.ipfilter_ss[FILTER_V_S_S_8] = x265_interp_8tap_v_ss_sse2;<br>
     }<br>
     if (cpuMask & X265_CPU_SSSE3)<br>
     {<br>
diff -r 2a7a5766fbd8 -r 539ad4851359 source/common/x86/ipfilter8.asm<br>
--- a/source/common/x86/ipfilter8.asm   Mon Nov 04 19:04:43 2013 +0800<br>
+++ b/source/common/x86/ipfilter8.asm   Mon Nov 04 19:05:04 2013 +0800<br>
@@ -2593,3 +2593,144 @@<br>
     jnz         .loopH<br>
<br>
     RET<br>
+<br>
+<br>
+;-------------------------------------------------------------------------------------------------------------<br>
+; void interp_8tap_v_ss(int16_t *src, intptr_t srcStride, int16_t *dst, intptr_t dstStride, int width, int height, const int coefIdx)<br>
+;-------------------------------------------------------------------------------------------------------------<br>
+INIT_XMM sse2<br>
+<br>
+%if ARCH_X86_64<br>
+cglobal interp_8tap_v_ss, 4, 7+1, 8<br>
+%define tmp_r4d     r7d<br>
+%define tmp_r5d     r8d<br>
+%else<br>
+cglobal interp_8tap_v_ss, 4, 7, 8, 0-2*4<br>
+%define tmp_r4d     dword [rsp + 0*4]<br>
+%define tmp_r5d     dword [rsp + 1*4]<br>
+%endif<br>
+<br>
+    ; load width, height and filterIdx<br>
+    mov         r4d, r4m<br>
+    mov         r5d, r5m<br>
+    mov         r6d, r6m<br>
+<br>
+    ; convert to word stride<br>
+    add         r1, r1<br>
+    add         r3, r3<br>
+<br>
+    ; stort to temporary memory or register<br>
+    shr         r4d, 2<br>
+    mov         tmp_r4d, r4d<br>
+    shr         r5d, 2<br>
+    mov         tmp_r5d, r5d<br>
+<br>
+    shl         r6d, 6<br>
+%ifdef PIC<br>
+    lea         r5, [tab_LumaCoeffV]<br>
+    lea         r6, [r5 + r6]<br>
+%else<br>
+    lea         r6, [tab_LumaCoeffV + r6]<br>
+%endif<br>
+<br>
+    lea         r4, [r1 * 3]<br>
+    sub         r0, r4<br>
+<br>
+.loopH:<br>
+    ; load width<br>
+    mov         r4d, tmp_r4d<br>
+<br>
+.loopW:<br>
+<br>
+    movh        m0, [r0]                    ; m0 = [0]<br>
+    movh        m1, [r0 + r1]               ; m1 = [1]<br>
+    lea         r0, [r0 + r1 * 2]<br>
+    punpcklwd   m0, m1<br>
+    pmaddwd     m0, [r6 + 0 * 16]           ; m0 = [0+1]            = R0<br>
+<br>
+    movh        m2, [r0]                    ; m2 = [2]<br>
+    movh        m3, [r0 + r1]               ; m3 = [3]<br>
+    lea         r0, [r0 + r1 * 2]<br>
+    punpcklwd   m1, m2<br>
+    pmaddwd     m1, [r6 + 0 * 16]           ; m1 = [1+2]            = R1<br>
+    punpcklwd   m2, m3                      ; m2 = [2 3]<br>
+    pmaddwd     m7, m2, [r6 + 1 * 16]       ;<br>
+    paddd       m0, m7                      ; m0 = [0+1+2+3]        = R0<br>
+    pmaddwd     m2, [r6 + 0 * 16]           ; m2 = [2+3]            = R2<br>
+<br>
+    movh        m4, [r0]                    ; m4 = [4]<br>
+    movh        m5, [r0 + r1]               ; m5 = [5]<br>
+    lea         r0, [r0 + r1 * 2]<br>
+    punpcklwd   m3, m4                      ; m3 = [3 4]<br>
+    pmaddwd     m7, m3, [r6 + 1 * 16]<br>
+    paddd       m1, m7                      ; m1 = [1+2+3+4]        = R1<br>
+    pmaddwd     m3, [r6 + 0 * 16]           ; m3 = [3+4]            = R3<br>
+    punpcklwd   m4, m5                      ; m4 = [4 5]<br>
+    pmaddwd     m7, m4, [r6 + 2 * 16]<br>
+    paddd       m0, m7                      ; m0 = [0+1+2+3+4+5]    = R0<br>
+    pmaddwd     m4, [r6 + 1 * 16]<br>
+    paddd       m2, m4                      ; m2 = [2+3+4+5]        = R2<br>
+<br>
+    movh        m6, [r0]                    ; m6 = [6]<br>
+    movh        m7, [r0 + r1]               ; m7 = [7]<br>
+    lea         r0, [r0 + r1 * 2]<br>
+    punpcklwd   m5, m6                      ; m5 = [5 6]<br>
+    pmaddwd     m4, m5, [r6 + 2 * 16]<br>
+    paddd       m1, m4                      ; m1 = [1+2+3+4+5+6]    = R1<br>
+    pmaddwd     m5, [r6 + 1 * 16]<br>
+    paddd       m3, m5                      ; m3 = [3+4+5+6]        = R3<br>
+    punpcklwd   m6, m7                      ; m6 = [6 7]<br>
+    pmaddwd     m4, m6, [r6 + 3 * 16]<br>
+    paddd       m0, m4                      ; m0 = [0+1+2+3+4+5+6+7]= R0<br>
+    pmaddwd     m6, [r6 + 2 * 16]<br>
+    paddd       m2, m6                      ; m2 = [2+3+4+5+6+7]    = R2<br>
+    psrad       m0, 6<br>
+    packssdw    m0, m0<br>
+    movh        [r2], m0                    ; store [0]<br>
+<br>
+    movh        m4, [r0]                    ; m4 = [8]<br>
+    movh        m5, [r0 + r1]               ; m5 = [9]<br>
+    punpcklwd   m7, m4                      ; m7 = [7 8]<br>
+    pmaddwd     m6, m7, [r6 + 3 * 16]<br>
+    paddd       m1, m6                      ; m1 = [1+2+3+4+5+6+7+8]= R1<br>
+    pmaddwd     m7, [r6 + 2 * 16]<br>
+    paddd       m3, m7                      ; m3 = [3+4+5+6+7+8]    = R3<br>
+    psrad       m1, 6<br>
+    packssdw    m1, m1<br>
+    movh        [r2 + r3], m1               ; store [1]<br>
+    punpcklwd   m4, m5                      ; m4 = [8 9]<br>
+    pmaddwd     m4, [r6 + 3 * 16]<br>
+    paddd       m2, m4                      ; m2 = [2+3+4+5+6+7+8+9]= R2<br>
+    psrad       m2, 6<br>
+    packssdw    m2, m2<br>
+    movh        [r2 + r3 * 2], m2           ; store [2]<br>
+    lea         r2, [r2 + r3 * 2]<br>
+<br>
+    movh        m4, [r0 + r1 * 2]           ; m4 = [10]<br>
+    punpcklwd   m5, m4                      ; m5 = [9 10]<br>
+    pmaddwd     m5, [r6 + 3 * 16]<br>
+    paddd       m3, m5                      ; m3 = [3+4+5+6+7+8+9+10]=R3<br>
+    psrad       m3, 6<br>
+    packssdw    m3, m3<br>
+    movh        [r2 + r3], m3               ; store [3]<br>
+<br>
+    lea         r5, [r1 * 8 - 8]<br>
+    sub         r0, r5<br>
+    lea         r5, [r3 * 2 - 8]<br>
+    sub         r2, r5<br>
+<br>
+    dec         r4d<br>
+    jnz         .loopW<br>
+<br>
+    ; move to next row<br>
+    mov         r4d, tmp_r4d<br>
+    shl         r4d, 3<br>
+    lea         r0, [r0 + r1 * 4]<br>
+    sub         r0, r4<br>
+    lea         r2, [r2 + r3 * 4]<br>
+    sub         r2, r4<br>
+<br>
+    dec         tmp_r5d<br>
+    jnz         .loopH<br>
+<br>
+    RET<br>
diff -r 2a7a5766fbd8 -r 539ad4851359 source/common/x86/pixel.h<br>
--- a/source/common/x86/pixel.h Mon Nov 04 19:04:43 2013 +0800<br>
+++ b/source/common/x86/pixel.h Mon Nov 04 19:05:04 2013 +0800<br>
@@ -214,6 +214,7 @@<br>
 uint64_t x265_pixel_sa8d_satd_16x16_avx2(pixel *pix1, intptr_t stride1, pixel *pix2, intptr_t stride2);<br>
<br>
 void x265_cvt32to16_shr_sse2(int16_t *dst, int *src, intptr_t, int, int);<br>
+void x265_interp_8tap_v_ss_sse2(int16_t *src, intptr_t srcStride, int16_t *dst, intptr_t dstStride, int width, int height, const int coefIdx);<br>
<br>
 #define DECL_HEVC_SSD(suffix) \<br>
     int x265_pixel_ssd_32x64_ ## suffix(pixel *, intptr_t, pixel *, intptr_t); \<br>
diff -r 2a7a5766fbd8 -r 539ad4851359 source/encoder/motion.cpp<br>
--- a/source/encoder/motion.cpp Mon Nov 04 19:04:43 2013 +0800<br>
+++ b/source/encoder/motion.cpp Mon Nov 04 19:05:04 2013 +0800<br>
@@ -1213,7 +1213,7 @@<br>
             int filterSize = NTAPS_LUMA;<br>
             int halfFilterSize = (filterSize >> 1);<br>
             primitives.ipfilter_ps[FILTER_H_P_S_8](fref - (halfFilterSize - 1) * ref->lumaStride, ref->lumaStride, immedVal, blockwidth, blockwidth, realHeight + filterSize - 1, g_lumaFilter[xFrac]);<br>
-            primitives.ipfilter_ss[FILTER_V_S_S_8](immedVal + (halfFilterSize - 1) * blockwidth, blockwidth, immedVal2, FENC_STRIDE, blockwidth, realHeight, g_lumaFilter[yFrac]);<br>
+            primitives.ipfilter_ss[FILTER_V_S_S_8](immedVal + (halfFilterSize - 1) * blockwidth, blockwidth, immedVal2, FENC_STRIDE, blockwidth, realHeight, yFrac);<br>
             primitives.weightpUni(immedVal2, subpelbuf, FENC_STRIDE, FENC_STRIDE, blockwidth, realHeight, ref->weight, local_round, local_shift, ref->offset);<br>
         }<br>
     }<br>
diff -r 2a7a5766fbd8 -r 539ad4851359 source/test/ipfilterharness.cpp<br>
--- a/source/test/ipfilterharness.cpp   Mon Nov 04 19:04:43 2013 +0800<br>
+++ b/source/test/ipfilterharness.cpp   Mon Nov 04 19:05:04 2013 +0800<br>
@@ -318,6 +318,68 @@<br>
     return true;<br>
 }<br>
<br>
+bool IPFilterHarness::check_IPFilter_primitive(ipfilter_ss_t ref, ipfilter_ss_t opt, int isChroma)<br>
+{<br>
+    int rand_val, rand_srcStride, rand_dstStride;<br>
+    const int min_size = isChroma ? 2 : 4;<br>
+<br>
+    // NOTE: refill data to avoid overflow<br>
+    const int max_filter_val = 64 * (1 << 8);<br>
+    for (int i = 0; i < ipf_t_size; i++)<br>
+    {<br>
+        short_buff[i] = rand() % (2 * max_filter_val) - max_filter_val;<br>
+    }<br>
+<br>
+    for (int i = 0; i <= 1000; i++)<br>
+    {<br>
+        int rand_height = rand() % 100;                 // Randomly generated Height<br>
+        int rand_width = rand() % 100;                  // Randomly generated Width<br>
+<br>
+        memset(IPF_vec_output_s, 0xCD, ipf_t_size);      // Initialize output buffer to zero<br>
+        memset(IPF_C_output_s, 0xCD, ipf_t_size);        // Initialize output buffer to zero<br>
+<br>
+        rand_val = rand() % 4;                      // Random offset in the filter<br>
+        rand_srcStride = rand() % 100;              // Randomly generated srcStride<br>
+        rand_dstStride = rand() % 100;              // Randomly generated dstStride<br>
+<br>
+        rand_width &= ~(min_size - 1);<br>
+        if (rand_width < min_size)<br>
+            rand_width = min_size;<br>
+<br>
+        rand_height &= ~(min_size - 1);<br>
+        if (rand_height < min_size)<br>
+            rand_height = min_size;<br>
+<br>
+        if (rand_srcStride < rand_width)<br>
+            rand_srcStride = rand_width;<br>
+<br>
+        if (rand_dstStride < rand_width)<br>
+            rand_dstStride = rand_width;<br>
+<br>
+        ref(short_buff + 3 * rand_srcStride,<br>
+            rand_srcStride,<br>
+            IPF_C_output_s,<br>
+            rand_dstStride,<br>
+            rand_width,<br>
+            rand_height, rand_val<br>
+            );<br>
+        opt(short_buff + 3 * rand_srcStride,<br>
+            rand_srcStride,<br>
+            IPF_vec_output_s,<br>
+            rand_dstStride,<br>
+            rand_width,<br>
+            rand_height, rand_val<br>
+            );<br>
+<br>
+        if (memcmp(IPF_C_output_s, IPF_vec_output_s, ipf_t_size * sizeof(int16_t)))<br>
+        {<br>
+            return false;<br>
+        }<br>
+    }<br>
+<br>
+    return true;<br>
+}<br>
+<br>
 bool IPFilterHarness::check_IPFilterChroma_primitive(filter_pp_t ref, filter_pp_t opt)<br>
 {<br>
     int rand_srcStride, rand_dstStride, rand_coeffIdx;<br>
@@ -452,6 +514,18 @@<br>
         }<br>
     }<br>
<br>
+    for (int value = 0; value < NUM_IPFILTER_S_S; value++)<br>
+    {<br>
+        if (opt.ipfilter_ss[value])<br>
+        {<br>
+            if (!check_IPFilter_primitive(ref.ipfilter_ss[value], opt.ipfilter_ss[value], (value == FILTER_V_S_S_4)))<br>
+            {<br>
+                printf("ipfilter_ss %d failed\n", 8 / (value + 1));<br>
+                return false;<br>
+            }<br>
+        }<br>
+    }<br>
+<br>
     if (opt.ipfilter_p2s)<br>
     {<br>
         if (!check_IPFilter_primitive(ref.ipfilter_p2s, opt.ipfilter_p2s))<br>
@@ -583,6 +657,17 @@<br>
         }<br>
     }<br>
<br>
+    for (int value = 0; value < NUM_IPFILTER_S_S; value++)<br>
+    {<br>
+        if (opt.ipfilter_ss[value])<br>
+        {<br>
+            printf("ipfilter_ss %d\t", 8 / (value + 1));<br>
+            REPORT_SPEEDUP(opt.ipfilter_ss[value], ref.ipfilter_ss[value],<br>
+                           short_buff + maxVerticalfilterHalfDistance * srcStride, srcStride,<br>
+                           IPF_vec_output_s, dstStride, width, height, val);<br>
+        }<br>
+    }<br>
+<br>
     if (opt.ipfilter_p2s)<br>
     {<br>
         printf("ipfilter_p2s\t");<br>
diff -r 2a7a5766fbd8 -r 539ad4851359 source/test/ipfilterharness.h<br>
--- a/source/test/ipfilterharness.h     Mon Nov 04 19:04:43 2013 +0800<br>
+++ b/source/test/ipfilterharness.h     Mon Nov 04 19:05:04 2013 +0800<br>
@@ -47,6 +47,7 @@<br>
     bool check_IPFilter_primitive(ipfilter_p2s_t ref, ipfilter_p2s_t opt);<br>
     bool check_IPFilter_primitive(filter_p2s_t ref, filter_p2s_t opt, int isChroma);<br>
     bool check_IPFilter_primitive(ipfilter_s2p_t ref, ipfilter_s2p_t opt);<br>
+    bool check_IPFilter_primitive(ipfilter_ss_t ref, ipfilter_ss_t opt, int isChroma);<br>
     bool check_IPFilterChroma_primitive(filter_pp_t ref, filter_pp_t opt);<br>
     bool check_IPFilterLuma_primitive(filter_pp_t ref, filter_pp_t opt);<br>
     bool check_IPFilterLumaHV_primitive(filter_hv_pp_t ref, filter_hv_pp_t opt);<br>
<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>Steve Borho
</div></div>