[03/28] hpeldsp: Add half-pel functions (currently copies of dsputil)

Message ID 1365604515-35299-1-git-send-email-martin@martin.st
State Committed
Headers show

Commit Message

Martin Storsjö April 10, 2013, 2:35 p.m.
From: "Ronald S. Bultje" <rsbultje@gmail.com>

---
 configure                                          |    1 +
 libavcodec/Makefile                                |    1 +
 libavcodec/dsputil.h                               |    7 +-
 libavcodec/hpeldsp.c                               |   56 +++++++
 libavcodec/hpeldsp.h                               |   97 +++++++++++
 .../{dsputil_template.c => hpeldsp_template.c}     |  174 +-------------------
 libavcodec/rnd_avg.h                               |    7 +
 7 files changed, 165 insertions(+), 178 deletions(-)
 create mode 100644 libavcodec/hpeldsp.c
 create mode 100644 libavcodec/hpeldsp.h
 copy libavcodec/{dsputil_template.c => hpeldsp_template.c} (53%)

Comments

Diego Biurrun April 10, 2013, 3:04 p.m. | #1
On Wed, Apr 10, 2013 at 05:35:15PM +0300, Martin Storsjö wrote:
> --- /dev/null
> +++ b/libavcodec/hpeldsp.h
> @@ -0,0 +1,97 @@
> +/* add and put pixel (decoding) */
> +// blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16
> +// h for op_pixels_func is limited to {width/2, width} but never larger
> +// than 16 and never smaller than 4
> +typedef void (*hpel_pixels_func)(uint8_t *block /*align width (8 or 16)*/,
> +                                 const uint8_t *pixels /*align 1*/,
> +                                 ptrdiff_t line_size, int h);

s/op_pixels_func/hpel_pixels_func/ in the comment

LGTM

Diego

Patch

diff --git a/configure b/configure
index ae46ce4..e19521a 100755
--- a/configure
+++ b/configure
@@ -1368,6 +1368,7 @@  CONFIG_EXTRA="
     h264dsp
     h264pred
     h264qpel
+    hpeldsp
     huffman
     lgplv3
     lpc
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index e6379a5..5d9b6f5 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -44,6 +44,7 @@  OBJS-$(CONFIG_H264CHROMA)              += h264chroma.o
 OBJS-$(CONFIG_H264DSP)                 += h264dsp.o h264idct.o
 OBJS-$(CONFIG_H264PRED)                += h264pred.o
 OBJS-$(CONFIG_H264QPEL)                += h264qpel.o
+OBJS-$(CONFIG_HPELDSP)                 += hpeldsp.o
 OBJS-$(CONFIG_HUFFMAN)                 += huffman.o
 OBJS-$(CONFIG_LIBXVID)                 += libxvid_rc.o
 OBJS-$(CONFIG_LPC)                     += lpc.o
diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
index 2a7c014..9c4976b 100644
--- a/libavcodec/dsputil.h
+++ b/libavcodec/dsputil.h
@@ -32,6 +32,7 @@ 
 
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "rnd_avg.h"
 
 
 //#define DEBUG
@@ -103,12 +104,6 @@  DEF_OLD_QPEL(qpel8_mc32_old_c)
 DEF_OLD_QPEL(qpel8_mc13_old_c)
 DEF_OLD_QPEL(qpel8_mc33_old_c)
 
-#define CALL_2X_PIXELS(a, b, n)\
-static void a(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
-    b(block  , pixels  , line_size, h);\
-    b(block+n, pixels+n, line_size, h);\
-}
-
 /* motion estimation */
 // h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller than 2
 // although currently h<4 is not used as functions with width <8 are neither used nor implemented
diff --git a/libavcodec/hpeldsp.c b/libavcodec/hpeldsp.c
new file mode 100644
index 0000000..4268029
--- /dev/null
+++ b/libavcodec/hpeldsp.c
@@ -0,0 +1,56 @@ 
+/*
+ * Half-pel DSP functions.
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Half-pel DSP functions.
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/intreadwrite.h"
+#include "hpeldsp.h"
+
+#define BIT_DEPTH 8
+#include "hpeldsp_template.c"
+
+av_cold void ff_hpeldsp_init(HpelDSPContext *c, int flags)
+{
+#define hpel_funcs(prefix, idx, num) \
+    c->prefix ## _pixels_tab idx [0] = prefix ## _pixels ## num ## _8_c; \
+    c->prefix ## _pixels_tab idx [1] = prefix ## _pixels ## num ## _x2_8_c; \
+    c->prefix ## _pixels_tab idx [2] = prefix ## _pixels ## num ## _y2_8_c; \
+    c->prefix ## _pixels_tab idx [3] = prefix ## _pixels ## num ## _xy2_8_c
+
+    hpel_funcs(put, [0], 16);
+    hpel_funcs(put, [1],  8);
+    hpel_funcs(put, [2],  4);
+    hpel_funcs(put, [3],  2);
+    hpel_funcs(put_no_rnd, [0], 16);
+    hpel_funcs(put_no_rnd, [1],  8);
+    hpel_funcs(avg, [0], 16);
+    hpel_funcs(avg, [1],  8);
+    hpel_funcs(avg, [2],  4);
+    hpel_funcs(avg, [3],  2);
+    hpel_funcs(avg_no_rnd,, 16);
+}
diff --git a/libavcodec/hpeldsp.h b/libavcodec/hpeldsp.h
new file mode 100644
index 0000000..e0b3812
--- /dev/null
+++ b/libavcodec/hpeldsp.h
@@ -0,0 +1,97 @@ 
+/*
+ * Half-pel DSP functions.
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Half-pel DSP functions.
+ */
+
+#ifndef AVCODEC_HPELDSP_H
+#define AVCODEC_HPELDSP_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+/* add and put pixel (decoding) */
+// blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16
+// h for op_pixels_func is limited to {width/2, width} but never larger
+// than 16 and never smaller than 4
+typedef void (*hpel_pixels_func)(uint8_t *block /*align width (8 or 16)*/,
+                                 const uint8_t *pixels /*align 1*/,
+                                 ptrdiff_t line_size, int h);
+
+/**
+ * Half-pel DSP context.
+ */
+typedef struct HpelDSPContext {
+    /**
+     * Halfpel motion compensation with rounding (a+b+1)>>1.
+     * this is an array[4][4] of motion compensation functions for 4
+     * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
+     * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
+     * @param block destination where the result is stored
+     * @param pixels source
+     * @param line_size number of bytes in a horizontal line of block
+     * @param h height
+     */
+    hpel_pixels_func put_pixels_tab[4][4];
+
+    /**
+     * Halfpel motion compensation with rounding (a+b+1)>>1.
+     * This is an array[4][4] of motion compensation functions for 4
+     * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
+     * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
+     * @param block destination into which the result is averaged (a+b+1)>>1
+     * @param pixels source
+     * @param line_size number of bytes in a horizontal line of block
+     * @param h height
+     */
+    hpel_pixels_func avg_pixels_tab[4][4];
+
+    /**
+     * Halfpel motion compensation with no rounding (a+b)>>1.
+     * this is an array[2][4] of motion compensation functions for 2
+     * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
+     * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
+     * @param block destination where the result is stored
+     * @param pixels source
+     * @param line_size number of bytes in a horizontal line of block
+     * @param h height
+     */
+    hpel_pixels_func put_no_rnd_pixels_tab[2][4];
+
+    /**
+     * Halfpel motion compensation with no rounding (a+b)>>1.
+     * this is an array[4] of motion compensation functions for 1
+     * horizontal blocksize (16) and the 4 halfpel positions<br>
+     * *pixels_tab[0][ xhalfpel + 2*yhalfpel ]
+     * @param block destination into which the result is averaged (a+b)>>1
+     * @param pixels source
+     * @param line_size number of bytes in a horizontal line of block
+     * @param h height
+     */
+    hpel_pixels_func avg_no_rnd_pixels_tab[4];
+} HpelDSPContext;
+
+void ff_hpeldsp_init(HpelDSPContext *c, int flags);
+
+#endif /* AVCODEC_HPELDSP_H */
diff --git a/libavcodec/dsputil_template.c b/libavcodec/hpeldsp_template.c
similarity index 53%
copy from libavcodec/dsputil_template.c
copy to libavcodec/hpeldsp_template.c
index d232d51..6518941 100644
--- a/libavcodec/dsputil_template.c
+++ b/libavcodec/hpeldsp_template.c
@@ -1,5 +1,5 @@ 
 /*
- * DSP utils
+ * Half-pel DSP functions.
  * Copyright (c) 2000, 2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
@@ -24,92 +24,12 @@ 
 
 /**
  * @file
- * DSP utils
+ * Half-pel DSP functions.
  */
 
 #include "bit_depth_template.c"
 
-/* draw the edges of width 'w' of an image of size width, height */
-//FIXME check that this is ok for mpeg4 interlaced
-static void FUNCC(draw_edges)(uint8_t *_buf, int _wrap, int width, int height, int w, int h, int sides)
-{
-    pixel *buf = (pixel*)_buf;
-    int wrap = _wrap / sizeof(pixel);
-    pixel *ptr, *last_line;
-    int i;
-
-    /* left and right */
-    ptr = buf;
-    for(i=0;i<height;i++) {
-#if BIT_DEPTH > 8
-        int j;
-        for (j = 0; j < w; j++) {
-            ptr[j-w] = ptr[0];
-            ptr[j+width] = ptr[width-1];
-        }
-#else
-        memset(ptr - w, ptr[0], w);
-        memset(ptr + width, ptr[width-1], w);
-#endif
-        ptr += wrap;
-    }
-
-    /* top and bottom + corners */
-    buf -= w;
-    last_line = buf + (height - 1) * wrap;
-    if (sides & EDGE_TOP)
-        for(i = 0; i < h; i++)
-            memcpy(buf - (i + 1) * wrap, buf, (width + w + w) * sizeof(pixel)); // top
-    if (sides & EDGE_BOTTOM)
-        for (i = 0; i < h; i++)
-            memcpy(last_line + (i + 1) * wrap, last_line, (width + w + w) * sizeof(pixel)); // bottom
-}
-
-#define DCTELEM_FUNCS(dctcoef, suffix)                                  \
-static void FUNCC(get_pixels ## suffix)(int16_t *restrict _block,       \
-                                        const uint8_t *_pixels,         \
-                                        int line_size)                  \
-{                                                                       \
-    const pixel *pixels = (const pixel *) _pixels;                      \
-    dctcoef *restrict block = (dctcoef *) _block;                       \
-    int i;                                                              \
-                                                                        \
-    /* read the pixels */                                               \
-    for(i=0;i<8;i++) {                                                  \
-        block[0] = pixels[0];                                           \
-        block[1] = pixels[1];                                           \
-        block[2] = pixels[2];                                           \
-        block[3] = pixels[3];                                           \
-        block[4] = pixels[4];                                           \
-        block[5] = pixels[5];                                           \
-        block[6] = pixels[6];                                           \
-        block[7] = pixels[7];                                           \
-        pixels += line_size / sizeof(pixel);                            \
-        block += 8;                                                     \
-    }                                                                   \
-}                                                                       \
-                                                                        \
-static void FUNCC(clear_block ## suffix)(int16_t *block)                \
-{                                                                       \
-    memset(block, 0, sizeof(dctcoef)*64);                               \
-}                                                                       \
-                                                                        \
-/**                                                                     \
- * memset(blocks, 0, sizeof(int16_t)*6*64)                              \
- */                                                                     \
-static void FUNCC(clear_blocks ## suffix)(int16_t *blocks)              \
-{                                                                       \
-    memset(blocks, 0, sizeof(dctcoef)*6*64);                            \
-}
-
-DCTELEM_FUNCS(int16_t, _16)
-#if BIT_DEPTH > 8
-DCTELEM_FUNCS(dctcoef, _32)
-#endif
-
-#if BIT_DEPTH == 8
 #include "hpel_template.c"
-#endif
 
 #define PIXOP2(OPNAME, OP) \
 static inline void FUNC(OPNAME ## _no_rnd_pixels8_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
@@ -126,12 +46,6 @@  static inline void FUNC(OPNAME ## _no_rnd_pixels8_l2)(uint8_t *dst, const uint8_
     }\
 }\
 \
-static inline void FUNC(OPNAME ## _no_rnd_pixels16_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
-                                                int src_stride1, int src_stride2, int h){\
-    FUNC(OPNAME ## _no_rnd_pixels8_l2)(dst  , src1  , src2  , dst_stride, src_stride1, src_stride2, h);\
-    FUNC(OPNAME ## _no_rnd_pixels8_l2)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, h);\
-}\
-\
 static inline void FUNCC(OPNAME ## _no_rnd_pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
     FUNC(OPNAME ## _no_rnd_pixels8_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
 }\
@@ -148,43 +62,6 @@  static inline void FUNCC(OPNAME ## _pixels8_y2)(uint8_t *block, const uint8_t *p
     FUNC(OPNAME ## _pixels8_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
 }\
 \
-static inline void FUNC(OPNAME ## _pixels8_l4)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, const uint8_t *src4,\
-                 int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
-    /* FIXME HIGH BIT DEPTH */\
-    int i;\
-    for(i=0; i<h; i++){\
-        uint32_t a, b, c, d, l0, l1, h0, h1;\
-        a= AV_RN32(&src1[i*src_stride1]);\
-        b= AV_RN32(&src2[i*src_stride2]);\
-        c= AV_RN32(&src3[i*src_stride3]);\
-        d= AV_RN32(&src4[i*src_stride4]);\
-        l0=  (a&0x03030303UL)\
-           + (b&0x03030303UL)\
-           + 0x02020202UL;\
-        h0= ((a&0xFCFCFCFCUL)>>2)\
-          + ((b&0xFCFCFCFCUL)>>2);\
-        l1=  (c&0x03030303UL)\
-           + (d&0x03030303UL);\
-        h1= ((c&0xFCFCFCFCUL)>>2)\
-          + ((d&0xFCFCFCFCUL)>>2);\
-        OP(*((uint32_t*)&dst[i*dst_stride]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
-        a= AV_RN32(&src1[i*src_stride1+4]);\
-        b= AV_RN32(&src2[i*src_stride2+4]);\
-        c= AV_RN32(&src3[i*src_stride3+4]);\
-        d= AV_RN32(&src4[i*src_stride4+4]);\
-        l0=  (a&0x03030303UL)\
-           + (b&0x03030303UL)\
-           + 0x02020202UL;\
-        h0= ((a&0xFCFCFCFCUL)>>2)\
-          + ((b&0xFCFCFCFCUL)>>2);\
-        l1=  (c&0x03030303UL)\
-           + (d&0x03030303UL);\
-        h1= ((c&0xFCFCFCFCUL)>>2)\
-          + ((d&0xFCFCFCFCUL)>>2);\
-        OP(*((uint32_t*)&dst[i*dst_stride+4]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
-    }\
-}\
-\
 static inline void FUNCC(OPNAME ## _pixels4_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
     FUNC(OPNAME ## _pixels4_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
 }\
@@ -201,53 +78,6 @@  static inline void FUNCC(OPNAME ## _pixels2_y2)(uint8_t *block, const uint8_t *p
     FUNC(OPNAME ## _pixels2_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
 }\
 \
-static inline void FUNC(OPNAME ## _no_rnd_pixels8_l4)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, const uint8_t *src4,\
-                 int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
-    /* FIXME HIGH BIT DEPTH*/\
-    int i;\
-    for(i=0; i<h; i++){\
-        uint32_t a, b, c, d, l0, l1, h0, h1;\
-        a= AV_RN32(&src1[i*src_stride1]);\
-        b= AV_RN32(&src2[i*src_stride2]);\
-        c= AV_RN32(&src3[i*src_stride3]);\
-        d= AV_RN32(&src4[i*src_stride4]);\
-        l0=  (a&0x03030303UL)\
-           + (b&0x03030303UL)\
-           + 0x01010101UL;\
-        h0= ((a&0xFCFCFCFCUL)>>2)\
-          + ((b&0xFCFCFCFCUL)>>2);\
-        l1=  (c&0x03030303UL)\
-           + (d&0x03030303UL);\
-        h1= ((c&0xFCFCFCFCUL)>>2)\
-          + ((d&0xFCFCFCFCUL)>>2);\
-        OP(*((uint32_t*)&dst[i*dst_stride]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
-        a= AV_RN32(&src1[i*src_stride1+4]);\
-        b= AV_RN32(&src2[i*src_stride2+4]);\
-        c= AV_RN32(&src3[i*src_stride3+4]);\
-        d= AV_RN32(&src4[i*src_stride4+4]);\
-        l0=  (a&0x03030303UL)\
-           + (b&0x03030303UL)\
-           + 0x01010101UL;\
-        h0= ((a&0xFCFCFCFCUL)>>2)\
-          + ((b&0xFCFCFCFCUL)>>2);\
-        l1=  (c&0x03030303UL)\
-           + (d&0x03030303UL);\
-        h1= ((c&0xFCFCFCFCUL)>>2)\
-          + ((d&0xFCFCFCFCUL)>>2);\
-        OP(*((uint32_t*)&dst[i*dst_stride+4]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
-    }\
-}\
-static inline void FUNC(OPNAME ## _pixels16_l4)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, const uint8_t *src4,\
-                 int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
-    FUNC(OPNAME ## _pixels8_l4)(dst  , src1  , src2  , src3  , src4  , dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\
-    FUNC(OPNAME ## _pixels8_l4)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), src3+8*sizeof(pixel), src4+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\
-}\
-static inline void FUNC(OPNAME ## _no_rnd_pixels16_l4)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, const uint8_t *src4,\
-                 int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
-    FUNC(OPNAME ## _no_rnd_pixels8_l4)(dst  , src1  , src2  , src3  , src4  , dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\
-    FUNC(OPNAME ## _no_rnd_pixels8_l4)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), src3+8*sizeof(pixel), src4+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\
-}\
-\
 static inline void FUNCC(OPNAME ## _pixels2_xy2)(uint8_t *_block, const uint8_t *_pixels, ptrdiff_t line_size, int h)\
 {\
         int i, a0, b0, a1, b1;\
diff --git a/libavcodec/rnd_avg.h b/libavcodec/rnd_avg.h
index c2b90e0..7301578 100644
--- a/libavcodec/rnd_avg.h
+++ b/libavcodec/rnd_avg.h
@@ -19,8 +19,15 @@ 
 #ifndef AVCODEC_RND_AVG_H
 #define AVCODEC_RND_AVG_H
 
+#include <stddef.h>
 #include <stdint.h>
 
+#define CALL_2X_PIXELS(a, b, n)\
+static void a(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    b(block  , pixels  , line_size, h);\
+    b(block+n, pixels+n, line_size, h);\
+}
+
 #define         BYTE_VEC32(c)   ((c)*0x01010101UL)
 #define         BYTE_VEC64(c)   ((c)*0x0001000100010001UL)