]> git.sesse.net Git - x264/blob - core/pixel.c
* all: re-import of the CVS.
[x264] / core / pixel.c
1 /*****************************************************************************
2  * pixel.c: h264 encoder
3  *****************************************************************************
4  * Copyright (C) 2003 Laurent Aimar
5  * $Id: pixel.c,v 1.1 2004/06/03 19:27:07 fenrir Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdint.h>
27
28 #include "../x264.h"
29 #include "pixel.h"
30
31 #ifdef HAVE_MMXEXT
32 #   include "i386/pixel.h"
33 #endif
34 #ifdef HAVE_ALTIVEC
35 #   include "ppc/pixel.h"
36 #endif
37
38
39 /****************************************************************************
40  * pixel_sad_WxH
41  ****************************************************************************/
42 #define PIXEL_SAD_C( name, lx, ly ) \
43 static int name( uint8_t *pix1, int i_stride_pix1,  \
44                  uint8_t *pix2, int i_stride_pix2 ) \
45 {                                                   \
46     int i_sum = 0;                                  \
47     int x, y;                                       \
48     for( y = 0; y < ly; y++ )                       \
49     {                                               \
50         for( x = 0; x < lx; x++ )                   \
51         {                                           \
52             i_sum += abs( pix1[x] - pix2[x] );      \
53         }                                           \
54         pix1 += i_stride_pix1;                      \
55         pix2 += i_stride_pix2;                      \
56     }                                               \
57     return i_sum;                                   \
58 }
59
60
61 PIXEL_SAD_C( pixel_sad_16x16, 16, 16 )
62 PIXEL_SAD_C( pixel_sad_16x8,  16,  8 )
63 PIXEL_SAD_C( pixel_sad_8x16,   8, 16 )
64 PIXEL_SAD_C( pixel_sad_8x8,    8,  8 )
65 PIXEL_SAD_C( pixel_sad_8x4,    8,  4 )
66 PIXEL_SAD_C( pixel_sad_4x8,    4,  8 )
67 PIXEL_SAD_C( pixel_sad_4x4,    4,  4 )
68
69 static void pixel_sub_4x4( int16_t diff[4][4], uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2 )
70 {
71     int y, x;
72     for( y = 0; y < 4; y++ )
73     {
74         for( x = 0; x < 4; x++ )
75         {
76             diff[y][x] = pix1[x] - pix2[x];
77         }
78         pix1 += i_pix1;
79         pix2 += i_pix2;
80     }
81 }
82
83 static int pixel_satd_wxh( uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2, int i_width, int i_height )
84 {
85     int16_t tmp[4][4];
86     int16_t diff[4][4];
87     int x, y;
88     int i_satd = 0;
89
90     for( y = 0; y < i_height; y += 4 )
91     {
92         for( x = 0; x < i_width; x += 4 )
93         {
94             int d;
95
96             pixel_sub_4x4( diff, &pix1[x], i_pix1, &pix2[x], i_pix2 );
97
98             for( d = 0; d < 4; d++ )
99             {
100                 int s01, s23;
101                 int d01, d23;
102
103                 s01 = diff[d][0] + diff[d][1]; s23 = diff[d][2] + diff[d][3];
104                 d01 = diff[d][0] - diff[d][1]; d23 = diff[d][2] - diff[d][3];
105
106                 tmp[d][0] = s01 + s23;
107                 tmp[d][1] = s01 - s23;
108                 tmp[d][2] = d01 - d23;
109                 tmp[d][3] = d01 + d23;
110             }
111             for( d = 0; d < 4; d++ )
112             {
113                 int s01, s23;
114                 int d01, d23;
115
116                 s01 = tmp[0][d] + tmp[1][d]; s23 = tmp[2][d] + tmp[3][d];
117                 d01 = tmp[0][d] - tmp[1][d]; d23 = tmp[2][d] - tmp[3][d];
118
119                 i_satd += abs( s01 + s23 ) + abs( s01 - s23 ) + abs( d01 - d23 ) + abs( d01 + d23 );
120             }
121
122         }
123         pix1 += 4 * i_pix1;
124         pix2 += 4 * i_pix2;
125     }
126
127     return i_satd / 2;
128 }
129 #define PIXEL_SATD_C( name, width, height ) \
130 static int name( uint8_t *pix1, int i_stride_pix1, \
131                  uint8_t *pix2, int i_stride_pix2 ) \
132 { \
133     return pixel_satd_wxh( pix1, i_stride_pix1, pix2, i_stride_pix2, width, height ); \
134 }
135 PIXEL_SATD_C( pixel_satd_16x16, 16, 16 )
136 PIXEL_SATD_C( pixel_satd_16x8,  16, 8 )
137 PIXEL_SATD_C( pixel_satd_8x16,  8, 16 )
138 PIXEL_SATD_C( pixel_satd_8x8,   8, 8 )
139 PIXEL_SATD_C( pixel_satd_8x4,   8, 4 )
140 PIXEL_SATD_C( pixel_satd_4x8,   4, 8 )
141 PIXEL_SATD_C( pixel_satd_4x4,   4, 4 )
142
143
144 static inline void pixel_avg_wxh( uint8_t *dst, int i_dst, uint8_t *src, int i_src, int width, int height )
145 {
146     int x, y;
147     for( y = 0; y < height; y++ )
148     {
149         for( x = 0; x < width; x++ )
150         {
151             dst[x] = ( dst[x] + src[x] + 1 ) >> 1;
152         }
153         dst += i_dst;
154         src += i_src;
155     }
156 }
157
158
159 #define PIXEL_AVG_C( name, width, height ) \
160 static void name( uint8_t *pix1, int i_stride_pix1, \
161                   uint8_t *pix2, int i_stride_pix2 ) \
162 { \
163     pixel_avg_wxh( pix1, i_stride_pix1, pix2, i_stride_pix2, width, height ); \
164 }
165 PIXEL_AVG_C( pixel_avg_16x16, 16, 16 )
166 PIXEL_AVG_C( pixel_avg_16x8,  16, 8 )
167 PIXEL_AVG_C( pixel_avg_8x16,  8, 16 )
168 PIXEL_AVG_C( pixel_avg_8x8,   8, 8 )
169 PIXEL_AVG_C( pixel_avg_8x4,   8, 4 )
170 PIXEL_AVG_C( pixel_avg_4x8,   4, 8 )
171 PIXEL_AVG_C( pixel_avg_4x4,   4, 4 )
172
173 /****************************************************************************
174  * x264_pixel_init:
175  ****************************************************************************/
176 void x264_pixel_init( int cpu, x264_pixel_function_t *pixf )
177 {
178     pixf->sad[PIXEL_16x16] = pixel_sad_16x16;
179     pixf->sad[PIXEL_16x8]  = pixel_sad_16x8;
180     pixf->sad[PIXEL_8x16]  = pixel_sad_8x16;
181     pixf->sad[PIXEL_8x8]   = pixel_sad_8x8;
182     pixf->sad[PIXEL_8x4]   = pixel_sad_8x4;
183     pixf->sad[PIXEL_4x8]   = pixel_sad_4x8;
184     pixf->sad[PIXEL_4x4]   = pixel_sad_4x4;
185
186     pixf->satd[PIXEL_16x16]= pixel_satd_16x16;
187     pixf->satd[PIXEL_16x8] = pixel_satd_16x8;
188     pixf->satd[PIXEL_8x16] = pixel_satd_8x16;
189     pixf->satd[PIXEL_8x8]  = pixel_satd_8x8;
190     pixf->satd[PIXEL_8x4]  = pixel_satd_8x4;
191     pixf->satd[PIXEL_4x8]  = pixel_satd_4x8;
192     pixf->satd[PIXEL_4x4]  = pixel_satd_4x4;
193
194     pixf->avg[PIXEL_16x16]= pixel_avg_16x16;
195     pixf->avg[PIXEL_16x8] = pixel_avg_16x8;
196     pixf->avg[PIXEL_8x16] = pixel_avg_8x16;
197     pixf->avg[PIXEL_8x8]  = pixel_avg_8x8;
198     pixf->avg[PIXEL_8x4]  = pixel_avg_8x4;
199     pixf->avg[PIXEL_4x8]  = pixel_avg_4x8;
200     pixf->avg[PIXEL_4x4]  = pixel_avg_4x4;
201 #ifdef HAVE_MMXEXT
202     if( cpu&X264_CPU_MMXEXT )
203     {
204         pixf->sad[PIXEL_16x16] = x264_pixel_sad_16x16_mmxext;
205         pixf->sad[PIXEL_16x8 ] = x264_pixel_sad_16x8_mmxext;
206         pixf->sad[PIXEL_8x16 ] = x264_pixel_sad_8x16_mmxext;
207         pixf->sad[PIXEL_8x8  ] = x264_pixel_sad_8x8_mmxext;
208         pixf->sad[PIXEL_8x4  ] = x264_pixel_sad_8x4_mmxext;
209         pixf->sad[PIXEL_4x8  ] = x264_pixel_sad_4x8_mmxext;
210         pixf->sad[PIXEL_4x4]   = x264_pixel_sad_4x4_mmxext;
211
212         pixf->satd[PIXEL_16x16]= x264_pixel_satd_16x16_mmxext;
213         pixf->satd[PIXEL_16x8] = x264_pixel_satd_16x8_mmxext;
214         pixf->satd[PIXEL_8x16] = x264_pixel_satd_8x16_mmxext;
215         pixf->satd[PIXEL_8x8]  = x264_pixel_satd_8x8_mmxext;
216         pixf->satd[PIXEL_8x4]  = x264_pixel_satd_8x4_mmxext;
217         pixf->satd[PIXEL_4x8]  = x264_pixel_satd_4x8_mmxext;
218         pixf->satd[PIXEL_4x4]  = x264_pixel_satd_4x4_mmxext;
219     }
220 #endif
221 #ifdef HAVE_ALTIVEC
222     if( cpu&X264_CPU_ALTIVEC )
223     {
224         x264_pixel_altivec_init( pixf );
225     }
226 #endif
227 }
228