cosmetics: reorganize intra prediction dsp
authorLoren Merritt <pengvado@videolan.org>
Mon, 6 Feb 2006 05:53:44 +0000 (05:53 +0000)
committerLoren Merritt <pengvado@videolan.org>
Mon, 6 Feb 2006 05:53:44 +0000 (05:53 +0000)
git-svn-id: svn://svn.videolan.org/x264/trunk@415 df754926-b1dd-0310-bc7b-ec298dee348c

Makefile
common/amd64/predict.c [new file with mode: 0644]
common/i386/predict-a.asm
common/i386/predict.c
common/i386/predict.h
common/predict.c
tools/checkasm.c

index b026e32..979bec0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,7 @@ endif
 
 # MMX/SSE optims
 ifeq ($(ARCH),X86_64)
-SRCS   += common/i386/mc-c.c common/i386/dct-c.c common/i386/predict.c
+SRCS   += common/i386/mc-c.c common/i386/dct-c.c common/amd64/predict.c
 ASMSRC  = common/amd64/dct-a.asm common/amd64/cpu-a.asm \
           common/amd64/pixel-a.asm common/amd64/mc-a.asm \
           common/amd64/mc-a2.asm common/amd64/predict-a.asm \
diff --git a/common/amd64/predict.c b/common/amd64/predict.c
new file mode 100644 (file)
index 0000000..ed30b0a
--- /dev/null
@@ -0,0 +1,171 @@
+/*****************************************************************************
+ * predict.c: h264 encoder
+ *****************************************************************************
+ * Copyright (C) 2006 x264 project
+ *
+ * Authors: Loren Merritt <lorenm@u.washington.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110 USA
+ *****************************************************************************/
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#include <inttypes.h>
+#endif
+
+#include "common/predict.h"
+#include "common/i386/predict.h"
+
+extern void predict_16x16_v_mmx( uint8_t *src, int i_stride );
+extern void predict_8x8c_v_mmx( uint8_t *src, int i_stride );
+
+/****************************************************************************
+ * 16x16 prediction for intra block
+ ****************************************************************************/
+
+#define PREDICT_16x16_DC(v) \
+    for( i = 0; i < 16; i++ )\
+    {\
+        uint64_t *p = (uint64_t*)src;\
+        *p++ = v;\
+        *p++ = v;\
+        src += i_stride;\
+    }
+
+static void predict_16x16_dc( uint8_t *src, int i_stride )
+{
+    uint32_t s = 0;
+    uint64_t dc;
+    int i;
+
+    /* calculate DC value */
+    for( i = 0; i < 16; i++ )
+    {
+        s += src[-1 + i * i_stride];
+        s += src[i - i_stride];
+    }
+    dc = (( s + 16 ) >> 5) * 0x0101010101010101ULL;
+
+    PREDICT_16x16_DC(dc);
+}
+static void predict_16x16_dc_left( uint8_t *src, int i_stride )
+{
+    uint32_t s = 0;
+    uint64_t dc;
+    int i;
+
+    for( i = 0; i < 16; i++ )
+    {
+        s += src[-1 + i * i_stride];
+    }
+    dc = (( s + 8 ) >> 4) * 0x0101010101010101ULL;
+
+    PREDICT_16x16_DC(dc);
+}
+static void predict_16x16_h( uint8_t *src, int i_stride )
+{
+    int i;
+    for( i = 0; i < 16; i++ )
+    {
+        const uint64_t v = 0x0101010101010101ULL * src[-1];
+        uint64_t *p = (uint64_t*)src;
+        *p++ = v;
+        *p++ = v;
+        src += i_stride;
+    }
+}
+
+
+/****************************************************************************
+ * 8x8 prediction for intra chroma block
+ ****************************************************************************/
+
+static void predict_8x8c_dc_left( uint8_t *src, int i_stride )
+{
+    int y;
+    uint32_t s0 = 0, s1 = 0;
+    uint64_t dc0, dc1;
+
+    for( y = 0; y < 4; y++ )
+    {
+        s0 += src[y * i_stride     - 1];
+        s1 += src[(y+4) * i_stride - 1];
+    }
+    dc0 = (( s0 + 2 ) >> 2)*0x0101010101010101ULL;
+    dc1 = (( s1 + 2 ) >> 2)*0x0101010101010101ULL;
+
+    for( y = 0; y < 4; y++ )
+    {
+        *(uint64_t*)src = dc0;
+        src += i_stride;
+    }
+    for( y = 0; y < 4; y++ )
+    {
+        *(uint64_t*)src = dc1;
+        src += i_stride;
+    }
+
+}
+static void predict_8x8c_dc_top( uint8_t *src, int i_stride )
+{
+    int y, x;
+    uint32_t s0 = 0, s1 = 0;
+    uint64_t dc;
+
+    for( x = 0; x < 4; x++ )
+    {
+        s0 += src[x     - i_stride];
+        s1 += src[x + 4 - i_stride];
+    }
+    dc = (( s0 + 2 ) >> 2)*0x01010101
+       + (( s1 + 2 ) >> 2)*0x0101010100000000ULL;
+
+    for( y = 0; y < 8; y++ )
+    {
+        *(uint64_t*)src = dc;
+        src += i_stride;
+    }
+}
+static void predict_8x8c_h( uint8_t *src, int i_stride )
+{
+    int i;
+    for( i = 0; i < 8; i++ )
+    {
+        *(uint64_t*)src = 0x0101010101010101ULL * src[-1];
+        src += i_stride;
+    }
+}
+
+
+/****************************************************************************
+ * Exported functions:
+ ****************************************************************************/
+void x264_predict_16x16_init_mmxext( x264_predict_t pf[7] )
+{
+    pf[I_PRED_16x16_V ]     = predict_16x16_v_mmx;
+    pf[I_PRED_16x16_H ]     = predict_16x16_h;
+    pf[I_PRED_16x16_DC]     = predict_16x16_dc;
+    pf[I_PRED_16x16_DC_LEFT]= predict_16x16_dc_left;
+}
+
+void x264_predict_8x8c_init_mmxext( x264_predict_t pf[7] )
+{
+    pf[I_PRED_CHROMA_V ]     = predict_8x8c_v_mmx;
+    pf[I_PRED_CHROMA_H ]     = predict_8x8c_h;
+    pf[I_PRED_CHROMA_DC_LEFT]= predict_8x8c_dc_left;
+    pf[I_PRED_CHROMA_DC_TOP ]= predict_8x8c_dc_top;
+}
+
index 3be28a1..595b65f 100644 (file)
@@ -33,12 +33,6 @@ BITS 32
     %endif
 %endmacro
 
-;=============================================================================
-; Read only data
-;=============================================================================
-
-SECTION .rodata data align=16
-
 SECTION .data
 
 ;=============================================================================
@@ -68,28 +62,22 @@ cglobal predict_16x16_v_mmx
 ALIGN 16
 predict_8x8c_v_mmx :
 
-    ;push       edi
-    ;push       esi
-
     mov         edx             , [esp + 4]
     mov         ecx             , [esp + 8]
-    sub         edx             , ecx               ; esi <-- line -1
+    sub         edx             , ecx               ; edx <-- line -1
 
     movq        mm0             , [edx]
     movq        [edx + ecx]     , mm0               ; 0
     movq        [edx + 2 * ecx] , mm0               ; 1
     movq        [edx + 4 * ecx] , mm0               ; 3
     movq        [edx + 8 * ecx] , mm0               ; 7
-    add         edx             , ecx               ; esi <-- line 0
+    add         edx             , ecx               ; edx <-- line 0
     movq        [edx + 2 * ecx] , mm0               ; 2
     movq        [edx + 4 * ecx] , mm0               ; 4
-    lea         edx             , [edx + 4 * ecx]   ; esi <-- line 4
+    lea         edx             , [edx + 4 * ecx]   ; edx <-- line 4
     movq        [edx + ecx]     , mm0               ; 5
     movq        [edx + 2 * ecx] , mm0               ; 6
 
-    ;pop        esi
-    ;pop        edi
-
     ret
 
 ;-----------------------------------------------------------------------------
@@ -101,18 +89,13 @@ predict_8x8c_v_mmx :
 ALIGN 16
 predict_16x16_v_mmx :
 
-    ;push       edi
-    ;push       esi
-
     mov         edx, [esp + 4]
     mov         ecx, [esp + 8]
-    sub         edx, ecx                ; esi <-- line -1
+    sub         edx, ecx                ; edx <-- line -1
 
     movq        mm0, [edx]
     movq        mm1, [edx + 8]
-    mov         eax, ecx
-    shl         eax, 1
-    add         eax, ecx                ; eax <-- 3* stride
+    lea         eax, [ecx + 2*ecx]      ; eax <-- 3* stride
 
     SAVE_0_1    (edx + ecx)             ; 0
     SAVE_0_1    (edx + 2 * ecx)         ; 1
@@ -121,21 +104,17 @@ predict_16x16_v_mmx :
     SAVE_0_1    (edx + 2 * eax)         ; 5
     SAVE_0_1    (edx + 8 * ecx)         ; 7
     SAVE_0_1    (edx + 4 * eax)         ; 11
-    add         edx, ecx                ; esi <-- line 0
+    add         edx, ecx                ; edx <-- line 0
     SAVE_0_1    (edx + 4 * ecx)         ; 4
     SAVE_0_1    (edx + 2 * eax)         ; 6
     SAVE_0_1    (edx + 8 * ecx)         ; 8
     SAVE_0_1    (edx + 4 * eax)         ; 12
-    lea         edx, [edx + 8 * ecx]    ; esi <-- line 8
+    lea         edx, [edx + 8 * ecx]    ; edx <-- line 8
     SAVE_0_1    (edx + ecx)             ; 9
     SAVE_0_1    (edx + 2 * ecx)         ; 10
-    lea         edx, [edx + 4 * ecx]    ; esi <-- line 12
+    lea         edx, [edx + 4 * ecx]    ; edx <-- line 12
     SAVE_0_1    (edx + ecx)             ; 13
     SAVE_0_1    (edx + 2 * ecx)         ; 14
     SAVE_0_1    (edx + eax)             ; 15
 
-
-    ;pop        esi
-    ;pop        edi
-
     ret
index 8bc7f67..5971b08 100644 (file)
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
-/* XXX predict4x4 are inspired from ffmpeg h264 decoder
- */
-
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
 #else
 #include <inttypes.h>
 #endif
-#include <stdlib.h>
-#include <stdarg.h>
 
-#include "x264.h"   /* for keyword inline */
 #include "common/predict.h"
 #include "predict.h"
 
-static inline int clip_uint8( int a )
-{
-    if (a&(~255))
-        return (-a)>>31;
-    else
-        return a;
-}
-
-/****************************************************************************
- * 16x16 prediction for intra block DC, H, V, P
- ****************************************************************************/
-static void predict_16x16_dc( uint8_t *src, int i_stride )
-{
-    uint32_t dc = 0;
-    int i;
-
-    /* calculate DC value */
-    for( i = 0; i < 16; i++ )
-    {
-        dc += src[-1 + i * i_stride];
-        dc += src[i - i_stride];
-    }
-    dc = (( dc + 16 ) >> 5) * 0x01010101;
-
-    for( i = 0; i < 16; i++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-
-        *p++ = dc;
-        *p++ = dc;
-        *p++ = dc;
-        *p++ = dc;
-
-        src += i_stride;
-    }
-}
-static void predict_16x16_dc_left( uint8_t *src, int i_stride )
-{
-    uint32_t dc = 0;
-    int i;
-
-    for( i = 0; i < 16; i++ )
-    {
-        dc += src[-1 + i * i_stride];
-    }
-    dc = (( dc + 8 ) >> 4) * 0x01010101;
-
-    for( i = 0; i < 16; i++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-
-        *p++ = dc;
-        *p++ = dc;
-        *p++ = dc;
-        *p++ = dc;
-
-        src += i_stride;
-    }
-}
-static void predict_16x16_dc_top( uint8_t *src, int i_stride )
-{
-    uint32_t dc = 0;
-    int i;
-
-    for( i = 0; i < 16; i++ )
-    {
-        dc += src[i - i_stride];
-    }
-    dc = (( dc + 8 ) >> 4) * 0x01010101;
-
-    for( i = 0; i < 16; i++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-
-        *p++ = dc;
-        *p++ = dc;
-        *p++ = dc;
-        *p++ = dc;
-
-        src += i_stride;
-    }
-}
-static void predict_16x16_dc_128( uint8_t *src, int i_stride )
-{
-    int i;
-
-    for( i = 0; i < 16; i++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-
-        *p++ = 0x80808080;
-        *p++ = 0x80808080;
-        *p++ = 0x80808080;
-        *p++ = 0x80808080;
-
-        src += i_stride;
-    }
-}
-static void predict_16x16_h( uint8_t *src, int i_stride )
-{
-    int i;
-
-    for( i = 0; i < 16; i++ )
-    {
-        const uint32_t v = 0x01010101 * src[-1];
-        uint32_t *p = (uint32_t*)src;
-
-        *p++ = v;
-        *p++ = v;
-        *p++ = v;
-        *p++ = v;
-
-        src += i_stride;
-
-    }
-}
-
 extern void predict_16x16_v_mmx( uint8_t *src, int i_stride );
-
-
-/****************************************************************************
- * 8x8 prediction for intra chroma block DC, H, V, P
- ****************************************************************************/
-static void predict_8x8c_dc_128( uint8_t *src, int i_stride )
-{
-    int y;
-
-    for( y = 0; y < 8; y++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-
-        *p++ = 0x80808080;
-        *p++ = 0x80808080;
-
-        src += i_stride;
-    }
-}
-static void predict_8x8c_dc_left( uint8_t *src, int i_stride )
-{
-    int y;
-    uint32_t dc0 = 0, dc1 = 0;
-
-    for( y = 0; y < 4; y++ )
-    {
-        dc0 += src[y * i_stride     - 1];
-        dc1 += src[(y+4) * i_stride - 1];
-    }
-    dc0 = (( dc0 + 2 ) >> 2)*0x01010101;
-    dc1 = (( dc1 + 2 ) >> 2)*0x01010101;
-
-    for( y = 0; y < 4; y++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-        *p++ = dc0;
-        *p++ = dc0;
-
-        src += i_stride;
-    }
-    for( y = 0; y < 4; y++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-        *p++ = dc1;
-        *p++ = dc1;
-
-        src += i_stride;
-    }
-
-}
-static void predict_8x8c_dc_top( uint8_t *src, int i_stride )
-{
-    int y, x;
-    uint32_t dc0 = 0, dc1 = 0;
-
-    for( x = 0; x < 4; x++ )
-    {
-        dc0 += src[x     - i_stride];
-        dc1 += src[x + 4 - i_stride];
-    }
-    dc0 = (( dc0 + 2 ) >> 2)*0x01010101;
-    dc1 = (( dc1 + 2 ) >> 2)*0x01010101;
-
-    for( y = 0; y < 8; y++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-        *p++ = dc0;
-        *p++ = dc1;
-
-        src += i_stride;
-    }
-}
-static void predict_8x8c_dc( uint8_t *src, int i_stride )
-{
-    int y;
-    int s0 = 0, s1 = 0, s2 = 0, s3 = 0;
-    uint32_t dc0, dc1, dc2, dc3;
-    int i;
-
-    /* First do :
-          s0 s1
-       s2
-       s3
-    */
-    for( i = 0; i < 4; i++ )
-    {
-        s0 += src[i - i_stride];
-        s1 += src[i + 4 - i_stride];
-        s2 += src[-1 + i * i_stride];
-        s3 += src[-1 + (i+4)*i_stride];
-    }
-    /* now calculate
-       dc0 dc1
-       dc2 dc3
-     */
-    dc0 = (( s0 + s2 + 4 ) >> 3)*0x01010101;
-    dc1 = (( s1 + 2 ) >> 2)*0x01010101;
-    dc2 = (( s3 + 2 ) >> 2)*0x01010101;
-    dc3 = (( s1 + s3 + 4 ) >> 3)*0x01010101;
-
-    for( y = 0; y < 4; y++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-        *p++ = dc0;
-        *p++ = dc1;
-
-        src += i_stride;
-    }
-
-    for( y = 0; y < 4; y++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-        *p++ = dc2;
-        *p++ = dc3;
-
-        src += i_stride;
-    }
-}
-
-static void predict_8x8c_h( uint8_t *src, int i_stride )
-{
-    int i;
-
-    for( i = 0; i < 8; i++ )
-    {
-        uint32_t v = 0x01010101 * src[-1];
-        uint32_t *p = (uint32_t*)src;
-
-        *p++ = v;
-        *p++ = v;
-
-        src += i_stride;
-    }
-}
-
 extern void predict_8x8c_v_mmx( uint8_t *src, int i_stride );
 
-
-/****************************************************************************
- * 4x4 prediction for intra luma block
- ****************************************************************************/
-static void predict_4x4_dc_128( uint8_t *src, int i_stride )
-{
-    int y;
-    for( y = 0; y < 4; y++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-        *p = 0x80808080;
-
-        src += i_stride;
-    }
-}
-static void predict_4x4_dc_left( uint8_t *src, int i_stride )
-{
-    int y;
-    uint32_t dc = (( src[-1+0*i_stride] + src[-1+i_stride]+
-                     src[-1+2*i_stride] + src[-1+3*i_stride] + 2 ) >> 2)*0x01010101;
-
-    for( y = 0; y < 4; y++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-        *p = dc;
-
-        src += i_stride;
-    }
-}
-static void predict_4x4_dc_top( uint8_t *src, int i_stride )
-{
-    int y;
-    uint32_t dc = (( src[0 - i_stride] + src[1 - i_stride] +
-                     src[2 - i_stride] + src[3 - i_stride] + 2 ) >> 2)*0x01010101;
-
-    for( y = 0; y < 4; y++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-        *p = dc;
-        src += i_stride;
-    }
-}
-static void predict_4x4_dc( uint8_t *src, int i_stride )
-{
-    int y;
-    uint32_t dc = (( src[-1+0*i_stride] + src[-1+i_stride]+
-                     src[-1+2*i_stride] + src[-1+3*i_stride] +
-                     src[0 - i_stride]  + src[1 - i_stride] +
-                     src[2 - i_stride]  + src[3 - i_stride] + 4 ) >> 3)*0x01010101;
-
-    for( y = 0; y < 4; y++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-        *p = dc;
-
-        src += i_stride;
-    }
-}
-static void predict_4x4_h( uint8_t *src, int i_stride )
-{
-    int i;
-
-    for( i = 0; i < 4; i++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-        *p = 0x01010101*src[-1];
-
-        src += i_stride;
-    }
-}
-static void predict_4x4_v( uint8_t *src, int i_stride )
-{
-    uint32_t top = *((uint32_t*)&src[-i_stride]);
-    int i;
-
-    for( i = 0; i < 4; i++ )
-    {
-        uint32_t *p = (uint32_t*)src;
-
-        *p = top;
-
-        src += i_stride;
-    }
-}
-
 /****************************************************************************
  * Exported functions:
  ****************************************************************************/
 void x264_predict_16x16_init_mmxext( x264_predict_t pf[7] )
 {
-    pf[I_PRED_16x16_V ]     = predict_16x16_v_mmx;
-    pf[I_PRED_16x16_H ]     = predict_16x16_h;
-    pf[I_PRED_16x16_DC]     = predict_16x16_dc;
-    pf[I_PRED_16x16_DC_LEFT]= predict_16x16_dc_left;
-    pf[I_PRED_16x16_DC_TOP ]= predict_16x16_dc_top;
-    pf[I_PRED_16x16_DC_128 ]= predict_16x16_dc_128;
+    pf[I_PRED_16x16_V] = predict_16x16_v_mmx;
 }
 
 void x264_predict_8x8c_init_mmxext( x264_predict_t pf[7] )
 {
-    pf[I_PRED_CHROMA_V ]     = predict_8x8c_v_mmx;
-    pf[I_PRED_CHROMA_H ]     = predict_8x8c_h;
-    pf[I_PRED_CHROMA_DC]     = predict_8x8c_dc;
-    pf[I_PRED_CHROMA_DC_LEFT]= predict_8x8c_dc_left;
-    pf[I_PRED_CHROMA_DC_TOP ]= predict_8x8c_dc_top;
-    pf[I_PRED_CHROMA_DC_128 ]= predict_8x8c_dc_128;
-}
-
-void x264_predict_4x4_init_mmxext( x264_predict_t pf[12] )
-{
-    pf[I_PRED_4x4_V]      = predict_4x4_v;
-    pf[I_PRED_4x4_H]      = predict_4x4_h;
-    pf[I_PRED_4x4_DC]     = predict_4x4_dc;
-    pf[I_PRED_4x4_DC_LEFT]= predict_4x4_dc_left;
-    pf[I_PRED_4x4_DC_TOP] = predict_4x4_dc_top;
-    pf[I_PRED_4x4_DC_128] = predict_4x4_dc_128;
+    pf[I_PRED_CHROMA_V] = predict_8x8c_v_mmx;
 }
 
index 9cec1ed..ba2eeb0 100644 (file)
@@ -26,6 +26,5 @@
 
 void x264_predict_16x16_init_mmxext ( x264_predict_t pf[7] );
 void x264_predict_8x8c_init_mmxext  ( x264_predict_t pf[7] );
-void x264_predict_4x4_init_mmxext   ( x264_predict_t pf[12] );
 
 #endif
index e0c1270..668d03c 100644 (file)
@@ -5,6 +5,7 @@
  * $Id: predict.c,v 1.1 2004/06/03 19:27:07 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
+ *          Loren Merritt <lorenm@u.washington.edu>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -44,10 +45,22 @@ static inline int clip_uint8( int a )
 /****************************************************************************
  * 16x16 prediction for intra block DC, H, V, P
  ****************************************************************************/
+
+#define PREDICT_16x16_DC(v) \
+    for( i = 0; i < 16; i++ )\
+    {\
+        uint32_t *p = (uint32_t*)src;\
+        *p++ = v;\
+        *p++ = v;\
+        *p++ = v;\
+        *p++ = v;\
+        src += i_stride;\
+    }
+
 static void predict_16x16_dc( uint8_t *src, int i_stride )
 {
-    int dc = 0;
-    int i, j;
+    uint32_t dc = 0;
+    int i;
 
     /* calculate DC value */
     for( i = 0; i < 16; i++ )
@@ -55,97 +68,75 @@ static void predict_16x16_dc( uint8_t *src, int i_stride )
         dc += src[-1 + i * i_stride];
         dc += src[i - i_stride];
     }
-    dc = ( dc + 16 ) >> 5;
+    dc = (( dc + 16 ) >> 5) * 0x01010101;
 
-    for( i = 0; i < 16; i++ )
-    {
-        for( j = 0; j < 16; j++ )
-        {
-            src[j] = dc;
-        }
-        src += i_stride;
-    }
+    PREDICT_16x16_DC(dc);
 }
 static void predict_16x16_dc_left( uint8_t *src, int i_stride )
 {
-    int dc = 0;
-    int i,j;
+    uint32_t dc = 0;
+    int i;
 
     for( i = 0; i < 16; i++ )
     {
         dc += src[-1 + i * i_stride];
     }
-    dc = ( dc + 8 ) >> 4;
+    dc = (( dc + 8 ) >> 4) * 0x01010101;
 
-    for( i = 0; i < 16; i++ )
-    {
-        for( j = 0; j < 16; j++ )
-        {
-            src[j] = dc;
-        }
-        src += i_stride;
-    }
+    PREDICT_16x16_DC(dc);
 }
 static void predict_16x16_dc_top( uint8_t *src, int i_stride )
 {
-    int dc = 0;
-    int i,j;
+    uint32_t dc = 0;
+    int i;
 
     for( i = 0; i < 16; i++ )
     {
         dc += src[i - i_stride];
     }
-    dc = ( dc + 8 ) >> 4;
+    dc = (( dc + 8 ) >> 4) * 0x01010101;
 
-    for( i = 0; i < 16; i++ )
-    {
-        for( j = 0; j < 16; j++ )
-        {
-            src[j] = dc;
-        }
-        src += i_stride;
-    }
+    PREDICT_16x16_DC(dc);
 }
 static void predict_16x16_dc_128( uint8_t *src, int i_stride )
 {
-    int i,j;
-
-    for( i = 0; i < 16; i++ )
-    {
-        for( j = 0; j < 16; j++ )
-        {
-            src[j] = 128;
-        }
-        src += i_stride;
-    }
+    int i;
+    PREDICT_16x16_DC(0x80808080);
 }
 static void predict_16x16_h( uint8_t *src, int i_stride )
 {
-    int i,j;
+    int i;
 
     for( i = 0; i < 16; i++ )
     {
-        uint8_t v;
+        const uint32_t v = 0x01010101 * src[-1];
+        uint32_t *p = (uint32_t*)src;
+
+        *p++ = v;
+        *p++ = v;
+        *p++ = v;
+        *p++ = v;
 
-        v = src[-1];
-        for( j = 0; j < 16; j++ )
-        {
-            src[j] = v;
-        }
         src += i_stride;
 
     }
 }
 static void predict_16x16_v( uint8_t *src, int i_stride )
 {
-    int i,j;
+    uint32_t v0 = *(uint32_t*)&src[ 0-i_stride];
+    uint32_t v1 = *(uint32_t*)&src[ 4-i_stride];
+    uint32_t v2 = *(uint32_t*)&src[ 8-i_stride];
+    uint32_t v3 = *(uint32_t*)&src[12-i_stride];
+    int i;
 
     for( i = 0; i < 16; i++ )
     {
-        for( j = 0; j < 16; j++ )
-        {
-            src[i * i_stride +j] = src[j - i_stride];
-        }
+        uint32_t *p = (uint32_t*)src;
+        *p++ = v0;
+        *p++ = v1;
+        *p++ = v2;
+        *p++ = v3;
+        src += i_stride;
     }
 }
 static void predict_16x16_p( uint8_t *src, int i_stride )
@@ -186,75 +177,79 @@ static void predict_16x16_p( uint8_t *src, int i_stride )
 
 
 /****************************************************************************
- * 8x8 prediction for intra chroma block DC, H, V, P
+ * 8x8 prediction for intra chroma block
  ****************************************************************************/
+
 static void predict_8x8c_dc_128( uint8_t *src, int i_stride )
 {
-    int x,y;
+    int y;
 
     for( y = 0; y < 8; y++ )
     {
-        for( x = 0; x < 8; x++ )
-        {
-            src[x] = 128;
-        }
+        uint32_t *p = (uint32_t*)src;
+        *p++ = 0x80808080;
+        *p++ = 0x80808080;
         src += i_stride;
     }
 }
 static void predict_8x8c_dc_left( uint8_t *src, int i_stride )
 {
-    int x,y;
-    int dc0 = 0, dc1 = 0;
+    int y;
+    uint32_t dc0 = 0, dc1 = 0;
 
     for( y = 0; y < 4; y++ )
     {
         dc0 += src[y * i_stride     - 1];
         dc1 += src[(y+4) * i_stride - 1];
     }
-    dc0 = ( dc0 + 2 ) >> 2;
-    dc1 = ( dc1 + 2 ) >> 2;
+    dc0 = (( dc0 + 2 ) >> 2)*0x01010101;
+    dc1 = (( dc1 + 2 ) >> 2)*0x01010101;
 
     for( y = 0; y < 4; y++ )
     {
-        for( x = 0; x < 8; x++ )
-        {
-            src[           x] = dc0;
-            src[4*i_stride+x] = dc1;
-        }
+        uint32_t *p = (uint32_t*)src;
+        *p++ = dc0;
+        *p++ = dc0;
+        src += i_stride;
+    }
+    for( y = 0; y < 4; y++ )
+    {
+        uint32_t *p = (uint32_t*)src;
+        *p++ = dc1;
+        *p++ = dc1;
         src += i_stride;
     }
+
 }
 static void predict_8x8c_dc_top( uint8_t *src, int i_stride )
 {
-    int x,y;
-    int dc0 = 0, dc1 = 0;
+    int y, x;
+    uint32_t dc0 = 0, dc1 = 0;
 
     for( x = 0; x < 4; x++ )
     {
         dc0 += src[x     - i_stride];
         dc1 += src[x + 4 - i_stride];
     }
-    dc0 = ( dc0 + 2 ) >> 2;
-    dc1 = ( dc1 + 2 ) >> 2;
+    dc0 = (( dc0 + 2 ) >> 2)*0x01010101;
+    dc1 = (( dc1 + 2 ) >> 2)*0x01010101;
 
     for( y = 0; y < 8; y++ )
     {
-        for( x = 0; x < 4; x++ )
-        {
-            src[x    ] = dc0;
-            src[x + 4] = dc1;
-        }
+        uint32_t *p = (uint32_t*)src;
+        *p++ = dc0;
+        *p++ = dc1;
         src += i_stride;
     }
 }
 static void predict_8x8c_dc( uint8_t *src, int i_stride )
 {
-    int x,y;
+    int y;
     int s0 = 0, s1 = 0, s2 = 0, s3 = 0;
-    int dc0, dc1, dc2, dc3;
+    uint32_t dc0, dc1, dc2, dc3;
     int i;
 
-    /* First do :
+    /*
           s0 s1
        s2
        s3
@@ -266,58 +261,58 @@ static void predict_8x8c_dc( uint8_t *src, int i_stride )
         s2 += src[-1 + i * i_stride];
         s3 += src[-1 + (i+4)*i_stride];
     }
-    /* now calculate
+    /*
        dc0 dc1
        dc2 dc3
      */
-    dc0 = ( s0 + s2 + 4 ) >> 3;
-    dc1 = ( s1 + 2 ) >> 2;
-    dc2 = ( s3 + 2 ) >> 2;
-    dc3 = ( s1 + s3 + 4 ) >> 3;
+    dc0 = (( s0 + s2 + 4 ) >> 3)*0x01010101;
+    dc1 = (( s1 + 2 ) >> 2)*0x01010101;
+    dc2 = (( s3 + 2 ) >> 2)*0x01010101;
+    dc3 = (( s1 + s3 + 4 ) >> 3)*0x01010101;
 
     for( y = 0; y < 4; y++ )
     {
-        for( x = 0; x < 4; x++ )
-        {
-            src[             x    ] = dc0;
-            src[             x + 4] = dc1;
-            src[4*i_stride + x    ] = dc2;
-            src[4*i_stride + x + 4] = dc3;
-        }
+        uint32_t *p = (uint32_t*)src;
+        *p++ = dc0;
+        *p++ = dc1;
         src += i_stride;
     }
-}
 
+    for( y = 0; y < 4; y++ )
+    {
+        uint32_t *p = (uint32_t*)src;
+        *p++ = dc2;
+        *p++ = dc3;
+        src += i_stride;
+    }
+}
 static void predict_8x8c_h( uint8_t *src, int i_stride )
 {
-    int i,j;
+    int i;
 
     for( i = 0; i < 8; i++ )
     {
-        uint8_t v;
-
-        v = src[-1];
-
-        for( j = 0; j < 8; j++ )
-        {
-            src[j] = v;
-        }
+        uint32_t v = 0x01010101 * src[-1];
+        uint32_t *p = (uint32_t*)src;
+        *p++ = v;
+        *p++ = v;
         src += i_stride;
     }
 }
 static void predict_8x8c_v( uint8_t *src, int i_stride )
 {
-    int i,j;
+    uint32_t v0 = *(uint32_t*)&src[0-i_stride];
+    uint32_t v1 = *(uint32_t*)&src[4-i_stride];
+    int i;
 
     for( i = 0; i < 8; i++ )
     {
-        for( j = 0; j < 8; j++ )
-        {
-            src[i * i_stride +j] = src[j - i_stride];
-        }
+        uint32_t *p = (uint32_t*)src;
+        *p++ = v0;
+        *p++ = v1;
+        src += i_stride;
     }
 }
-
 static void predict_8x8c_p( uint8_t *src, int i_stride )
 {
     int i;
@@ -342,9 +337,7 @@ static void predict_8x8c_p( uint8_t *src, int i_stride )
     {
         for( x = 0; x < 8; x++ )
         {
-            int pix;
-
-            pix = (i00 +b*x) >> 5;
+            int pix = (i00 +b*x) >> 5;
             src[x] = clip_uint8( pix );
         }
         src += i_stride;
@@ -355,92 +348,60 @@ static void predict_8x8c_p( uint8_t *src, int i_stride )
 /****************************************************************************
  * 4x4 prediction for intra luma block
  ****************************************************************************/
+
+#define PREDICT_4x4_DC(v) \
+{\
+    int i;\
+    for( i = 0; i < 4; i++ )\
+    {\
+        *(uint32_t*)src = v;\
+        src += i_stride;\
+    }\
+}
+
 static void predict_4x4_dc_128( uint8_t *src, int i_stride )
 {
-    int x,y;
-    for( y = 0; y < 4; y++ )
-    {
-        for( x = 0; x < 4; x++ )
-        {
-            src[x] = 128;
-        }
-        src += i_stride;
-    }
+    PREDICT_4x4_DC(0x80808080);
 }
 static void predict_4x4_dc_left( uint8_t *src, int i_stride )
 {
-    int x,y;
-    int dc = ( src[-1+0*i_stride] + src[-1+i_stride]+
-               src[-1+2*i_stride] + src[-1+3*i_stride] + 2 ) >> 2;
-
-    for( y = 0; y < 4; y++ )
-    {
-        for( x = 0; x < 4; x++ )
-        {
-            src[x] = dc;
-        }
-        src += i_stride;
-    }
+    uint32_t dc = (( src[-1+0*i_stride] + src[-1+i_stride]+
+                     src[-1+2*i_stride] + src[-1+3*i_stride] + 2 ) >> 2)*0x01010101;
+    PREDICT_4x4_DC(dc);
 }
 static void predict_4x4_dc_top( uint8_t *src, int i_stride )
 {
-    int x,y;
-    int dc = ( src[0 - i_stride] + src[1 - i_stride] +
-               src[2 - i_stride] + src[3 - i_stride] + 2 ) >> 2;
-
-    for( y = 0; y < 4; y++ )
-    {
-        for( x = 0; x < 4; x++ )
-        {
-            src[x] = dc;
-        }
-        src += i_stride;
-    }
+    uint32_t dc = (( src[0 - i_stride] + src[1 - i_stride] +
+                     src[2 - i_stride] + src[3 - i_stride] + 2 ) >> 2)*0x01010101;
+    PREDICT_4x4_DC(dc);
 }
 static void predict_4x4_dc( uint8_t *src, int i_stride )
 {
-    int x,y;
-    int dc = ( src[-1+0*i_stride] + src[-1+i_stride]+
-               src[-1+2*i_stride] + src[-1+3*i_stride] +
-               src[0 - i_stride]  + src[1 - i_stride] +
-               src[2 - i_stride]  + src[3 - i_stride] + 4 ) >> 3;
-
-    for( y = 0; y < 4; y++ )
-    {
-        for( x = 0; x < 4; x++ )
-        {
-            src[x] = dc;
-        }
-        src += i_stride;
-    }
+    uint32_t dc = (( src[-1+0*i_stride] + src[-1+i_stride] +
+                     src[-1+2*i_stride] + src[-1+3*i_stride] +
+                     src[0 - i_stride]  + src[1 - i_stride] +
+                     src[2 - i_stride]  + src[3 - i_stride] + 4 ) >> 3)*0x01010101;
+    PREDICT_4x4_DC(dc);
 }
 static void predict_4x4_h( uint8_t *src, int i_stride )
 {
-    int i,j;
+    int i;
 
     for( i = 0; i < 4; i++ )
     {
-        uint8_t v;
-
-        v = src[-1];
-
-        for( j = 0; j < 4; j++ )
-        {
-            src[j] = v;
-        }
+        *(uint32_t*)src = 0x01010101*src[-1];
         src += i_stride;
     }
 }
 static void predict_4x4_v( uint8_t *src, int i_stride )
 {
-    int i,j;
+    uint32_t top = *((uint32_t*)&src[-i_stride]);
+    int i;
 
     for( i = 0; i < 4; i++ )
     {
-        for( j = 0; j < 4; j++ )
-        {
-            src[i * i_stride +j] = src[j - i_stride];
-        }
+        *(uint32_t*)src = top;
+        src += i_stride;
     }
 }
 
@@ -462,34 +423,33 @@ static void predict_4x4_v( uint8_t *src, int i_stride )
     const int t6 = src[6-1*i_stride];   \
     UNUSED const int t7 = src[7-1*i_stride];
 
-
 static void predict_4x4_ddl( uint8_t *src, int i_stride )
 {
     PREDICT_4x4_LOAD_TOP
     PREDICT_4x4_LOAD_TOP_RIGHT
 
-    src[0*i_stride+0] = ( t0 + 2*t1+ t2 + 2 ) >> 2;
+    src[0*i_stride+0] = ( t0 + 2*t1 + t2 + 2 ) >> 2;
 
     src[0*i_stride+1] =
-    src[1*i_stride+0] = ( t1 + 2*t2+ t3 + 2 ) >> 2;
+    src[1*i_stride+0] = ( t1 + 2*t2 + t3 + 2 ) >> 2;
 
     src[0*i_stride+2] =
     src[1*i_stride+1] =
-    src[2*i_stride+0] = ( t2 + 2*t3+ t4 + 2 ) >> 2;
+    src[2*i_stride+0] = ( t2 + 2*t3 + t4 + 2 ) >> 2;
 
     src[0*i_stride+3] =
     src[1*i_stride+2] =
     src[2*i_stride+1] =
-    src[3*i_stride+0] = ( t3 + 2*t4+ t5 + 2 ) >> 2;
+    src[3*i_stride+0] = ( t3 + 2*t4 + t5 + 2 ) >> 2;
 
     src[1*i_stride+3] =
     src[2*i_stride+2] =
-    src[3*i_stride+1] = ( t4 + 2*t5+ t6 + 2 ) >> 2;
+    src[3*i_stride+1] = ( t4 + 2*t5 + t6 + 2 ) >> 2;
 
     src[2*i_stride+3] =
-    src[3*i_stride+2] = ( t5 + 2*t6+ t7 + 2 ) >> 2;
+    src[3*i_stride+2] = ( t5 + 2*t6 + t7 + 2 ) >> 2;
 
-    src[3*i_stride+3] = ( t6 + 3 * t7 + 2 ) >> 2;
+    src[3*i_stride+3] = ( t6 + 3*t7 + 2 ) >> 2;
 }
 static void predict_4x4_ddr( uint8_t *src, int i_stride )
 {
@@ -500,7 +460,7 @@ static void predict_4x4_ddr( uint8_t *src, int i_stride )
     src[0*i_stride+0] =
     src[1*i_stride+1] =
     src[2*i_stride+2] =
-    src[3*i_stride+3] = ( t0 + 2*lt +l0 + 2 ) >> 2;
+    src[3*i_stride+3] = ( t0 + 2 * lt + l0 + 2 ) >> 2;
 
     src[0*i_stride+1] =
     src[1*i_stride+2] =
@@ -590,8 +550,8 @@ static void predict_4x4_vl( uint8_t *src, int i_stride )
     src[0*i_stride+2]=
     src[2*i_stride+1]= ( t2 + t3 + 1 ) >> 1;
     src[0*i_stride+3]=
-    src[2*i_stride+2]= ( t3 + t4+ 1 ) >> 1;
-    src[2*i_stride+3]= ( t4 + t5+ 1 ) >> 1;
+    src[2*i_stride+2]= ( t3 + t4 + 1 ) >> 1;
+    src[2*i_stride+3]= ( t4 + t5 + 1 ) >> 1;
     src[1*i_stride+0]= ( t0 + 2 * t1 + t2 + 2 ) >> 2;
     src[1*i_stride+1]=
     src[3*i_stride+0]= ( t1 + 2 * t2 + t3 + 2 ) >> 2;
@@ -937,12 +897,5 @@ void x264_predict_4x4_init( int cpu, x264_predict_t pf[12] )
     pf[I_PRED_4x4_DC_LEFT]= predict_4x4_dc_left;
     pf[I_PRED_4x4_DC_TOP] = predict_4x4_dc_top;
     pf[I_PRED_4x4_DC_128] = predict_4x4_dc_128;
-
-#ifdef HAVE_MMXEXT
-    if( cpu&X264_CPU_MMXEXT )
-    {
-        x264_predict_4x4_init_mmxext( pf );
-    }
-#endif
 }
 
index 42f2eea..67307ab 100644 (file)
@@ -455,11 +455,67 @@ static int check_quant( int cpu_ref, int cpu_new )
     return ret;
 }
 
+static int check_intra( int cpu_ref, int cpu_new )
+{
+    int ret = 0, ok = 1, used_asm = 0;
+    int i;
+    struct
+    {
+        x264_predict_t      predict_16x16[4+3];
+        x264_predict_t      predict_8x8c[4+3];
+        x264_predict8x8_t   predict_8x8[9+3];
+        x264_predict_t      predict_4x4[9+3];
+    } ip_c, ip_ref, ip_a;
+
+    x264_predict_16x16_init( 0, ip_c.predict_16x16 );
+    x264_predict_8x8c_init( 0, ip_c.predict_8x8c );
+    x264_predict_8x8_init( 0, ip_c.predict_8x8 );
+    x264_predict_4x4_init( 0, ip_c.predict_4x4 );
+
+    x264_predict_16x16_init( cpu_ref, ip_ref.predict_16x16 );
+    x264_predict_8x8c_init( cpu_ref, ip_ref.predict_8x8c );
+    x264_predict_8x8_init( cpu_ref, ip_ref.predict_8x8 );
+    x264_predict_4x4_init( cpu_ref, ip_ref.predict_4x4 );
+
+    x264_predict_16x16_init( cpu_new, ip_a.predict_16x16 );
+    x264_predict_8x8c_init( cpu_new, ip_a.predict_8x8c );
+    x264_predict_8x8_init( cpu_new, ip_a.predict_8x8 );
+    x264_predict_4x4_init( cpu_new, ip_a.predict_4x4 );
+
+#define INTRA_TEST( name, dir, ... ) \
+    if( ip_a.name[dir] != ip_ref.name[dir] )\
+    { \
+        used_asm = 1; \
+        memcpy( buf3, buf1, 32*20 );\
+        memcpy( buf4, buf1, 32*20 );\
+        ip_c.name[dir]( buf3+48, 32, ##__VA_ARGS__ );\
+        ip_a.name[dir]( buf4+48, 32, ##__VA_ARGS__ );\
+        if( memcmp( buf3, buf4, 32*20 ) )\
+        {\
+            fprintf( stderr, #name "[%d] :  [FAILED]\n", dir );\
+            ok = 0;\
+        }\
+    }
+
+    for( i = 0; i < 12; i++ )
+        INTRA_TEST( predict_4x4, i );
+    for( i = 0; i < 12; i++ )
+        INTRA_TEST( predict_8x8, i, 0xf );
+    for( i = 0; i < 7; i++ )
+        INTRA_TEST( predict_8x8c, i );
+    for( i = 0; i < 7; i++ )
+        INTRA_TEST( predict_16x16, i );
+
+    report( "intra pred :" );
+    return ret;
+}
+
 int check_all( int cpu_ref, int cpu_new )
 {
     return check_pixel( cpu_ref, cpu_new )
          + check_dct( cpu_ref, cpu_new )
          + check_mc( cpu_ref, cpu_new )
+         + check_intra( cpu_ref, cpu_new )
          + check_deblock( cpu_ref, cpu_new )
          + check_quant( cpu_ref, cpu_new );
 }