]> git.sesse.net Git - x264/blob - common/frame.c
amd64 sse2 8x8dct. 1.45x faster than mmx.
[x264] / common / frame.c
1 /*****************************************************************************
2  * frame.c: h264 encoder library
3  *****************************************************************************
4  * Copyright (C) 2003 Laurent Aimar
5  * $Id: frame.c,v 1.1 2004/06/03 19:27:06 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 <stdio.h>
26 #include <string.h>
27
28 #include "common.h"
29
30 x264_frame_t *x264_frame_new( x264_t *h )
31 {
32     x264_frame_t   *frame = x264_malloc( sizeof( x264_frame_t ) );
33     int i;
34
35     int i_mb_count = h->mb.i_mb_count;
36     int i_stride;
37     int i_lines;
38
39     memset( frame, 0, sizeof(x264_frame_t) );
40
41     /* allocate frame data (+64 for extra data for me) */
42     i_stride = ( ( h->param.i_width  + 15 )&0xfffff0 )+ 64;
43     i_lines  = ( ( h->param.i_height + 15 )&0xfffff0 );
44
45     frame->i_plane = 3;
46     for( i = 0; i < 3; i++ )
47     {
48         int i_divh = 1;
49         int i_divw = 1;
50         if( i > 0 )
51         {
52             if( h->param.i_csp == X264_CSP_I420 )
53                 i_divh = i_divw = 2;
54             else if( h->param.i_csp == X264_CSP_I422 )
55                 i_divw = 2;
56         }
57         frame->i_stride[i] = i_stride / i_divw;
58         frame->i_lines[i] = i_lines / i_divh;
59         frame->buffer[i] = x264_malloc( frame->i_stride[i] *
60                                         ( frame->i_lines[i] + 64 / i_divh ) );
61
62         frame->plane[i] = ((uint8_t*)frame->buffer[i]) +
63                           frame->i_stride[i] * 32 / i_divh + 32 / i_divw;
64     }
65     frame->i_stride[3] = 0;
66     frame->i_lines[3] = 0;
67     frame->buffer[3] = NULL;
68     frame->plane[3] = NULL;
69
70     frame->filtered[0] = frame->plane[0];
71     for( i = 0; i < 3; i++ )
72     {
73         frame->buffer[4+i] = x264_malloc( frame->i_stride[0] *
74                                         ( frame->i_lines[0] + 64 ) );
75
76         frame->filtered[i+1] = ((uint8_t*)frame->buffer[4+i]) +
77                                 frame->i_stride[0] * 32 + 32;
78     }
79
80     if( h->frames.b_have_lowres )
81     {
82         frame->i_stride_lowres = frame->i_stride[0]/2 + 32;
83         frame->i_lines_lowres = frame->i_lines[0]/2;
84         for( i = 0; i < 4; i++ )
85         {
86             frame->buffer[7+i] = x264_malloc( frame->i_stride_lowres *
87                                             ( frame->i_lines[0]/2 + 64 ) );
88             frame->lowres[i] = ((uint8_t*)frame->buffer[7+i]) +
89                                 frame->i_stride_lowres * 32 + 32;
90         }
91     }
92
93     frame->i_poc = -1;
94     frame->i_type = X264_TYPE_AUTO;
95     frame->i_qpplus1 = 0;
96     frame->i_pts = -1;
97     frame->i_frame = -1;
98     frame->i_frame_num = -1;
99
100     frame->mb_type= x264_malloc( i_mb_count * sizeof( int8_t) );
101     frame->mv[0]  = x264_malloc( 2*16 * i_mb_count * sizeof( int16_t ) );
102     frame->ref[0] = x264_malloc( 4 * i_mb_count * sizeof( int8_t ) );
103     if( h->param.i_bframe )
104     {
105         frame->mv[1]  = x264_malloc( 2*16 * i_mb_count * sizeof( int16_t ) );
106         frame->ref[1] = x264_malloc( 4 * i_mb_count * sizeof( int8_t ) );
107     }
108     else
109     {
110         frame->mv[1]  = NULL;
111         frame->ref[1] = NULL;
112     }
113
114     return frame;
115 }
116
117 void x264_frame_delete( x264_frame_t *frame )
118 {
119     int i;
120     for( i = 0; i < frame->i_plane; i++ )
121     {
122         x264_free( frame->buffer[i] );
123     }
124     for( i = 4; i < 11; i++ ) /* filtered planes */
125     {
126         x264_free( frame->buffer[i] );
127     }
128     x264_free( frame->mb_type );
129     x264_free( frame->mv[0] );
130     x264_free( frame->mv[1] );
131     x264_free( frame->ref[0] );
132     x264_free( frame->ref[1] );
133     x264_free( frame );
134 }
135
136 void x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
137 {
138     dst->i_type     = src->i_type;
139     dst->i_qpplus1  = src->i_qpplus1;
140     dst->i_pts      = src->i_pts;
141
142     switch( src->img.i_csp & X264_CSP_MASK )
143     {
144         case X264_CSP_I420:
145             h->csp.i420( dst, &src->img, h->param.i_width, h->param.i_height );
146             break;
147         case X264_CSP_YV12:
148             h->csp.yv12( dst, &src->img, h->param.i_width, h->param.i_height );
149             break;
150         case X264_CSP_I422:
151             h->csp.i422( dst, &src->img, h->param.i_width, h->param.i_height );
152             break;
153         case X264_CSP_I444:
154             h->csp.i444( dst, &src->img, h->param.i_width, h->param.i_height );
155             break;
156         case X264_CSP_YUYV:
157             h->csp.yuyv( dst, &src->img, h->param.i_width, h->param.i_height );
158             break;
159         case X264_CSP_RGB:
160             h->csp.rgb( dst, &src->img, h->param.i_width, h->param.i_height );
161             break;
162         case X264_CSP_BGR:
163             h->csp.bgr( dst, &src->img, h->param.i_width, h->param.i_height );
164             break;
165         case X264_CSP_BGRA:
166             h->csp.bgra( dst, &src->img, h->param.i_width, h->param.i_height );
167             break;
168
169         default:
170             x264_log( h, X264_LOG_ERROR, "Arg invalid CSP\n" );
171             break;
172     }
173 }
174
175
176
177 static void plane_expand_border( uint8_t *pix, int i_stride, int i_height, int i_pad )
178 {
179 #define PPIXEL(x, y) ( pix + (x) + (y)*i_stride )
180     const int i_width = i_stride - 2*i_pad;
181     int y;
182
183     for( y = 0; y < i_height; y++ )
184     {
185         /* left band */
186         memset( PPIXEL(-i_pad, y), PPIXEL(0, y)[0], i_pad );
187         /* right band */
188         memset( PPIXEL(i_width, y), PPIXEL(i_width-1, y)[0], i_pad );
189     }
190     /* upper band */
191     for( y = 0; y < i_pad; y++ )
192         memcpy( PPIXEL(-i_pad, -y-1), PPIXEL(-i_pad, 0), i_stride );
193     /* lower band */
194     for( y = 0; y < i_pad; y++ )
195         memcpy( PPIXEL(-i_pad, i_height+y), PPIXEL(-i_pad, i_height-1), i_stride );
196 #undef PPIXEL
197 }
198
199 void x264_frame_expand_border( x264_frame_t *frame )
200 {
201     int i;
202     for( i = 0; i < frame->i_plane; i++ )
203     {
204         int i_pad = i ? 16 : 32;
205         plane_expand_border( frame->plane[i], frame->i_stride[i], frame->i_lines[i], i_pad );
206     }
207 }
208
209 void x264_frame_expand_border_filtered( x264_frame_t *frame )
210 {
211     /* during filtering, 8 extra pixels were filtered on each edge. 
212        we want to expand border from the last filtered pixel */
213     int i;
214     for( i = 1; i < 4; i++ )
215         plane_expand_border( frame->filtered[i] - 8*frame->i_stride[0] - 8, frame->i_stride[0], frame->i_lines[0]+2*8, 24 );
216 }
217
218 void x264_frame_expand_border_lowres( x264_frame_t *frame )
219 {
220     int i;
221     for( i = 0; i < 4; i++ )
222         plane_expand_border( frame->lowres[i], frame->i_stride_lowres, frame->i_lines_lowres, 32 );
223 }
224
225 void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame )
226 {
227     int i, y;
228     for( i = 0; i < frame->i_plane; i++ )
229     {
230         int i_subsample = i ? 1 : 0;
231         int i_width = h->param.i_width >> i_subsample;
232         int i_height = h->param.i_height >> i_subsample;
233         int i_padx = ( h->sps->i_mb_width * 16 - h->param.i_width ) >> i_subsample;
234         int i_pady = ( h->sps->i_mb_height * 16 - h->param.i_height ) >> i_subsample;
235
236         if( i_padx )
237         {
238             for( y = 0; y < i_height; y++ )
239                 memset( &frame->plane[i][y*frame->i_stride[i] + i_width],
240                          frame->plane[i][y*frame->i_stride[i] + i_width - 1],
241                          i_padx );
242         }
243         if( i_pady )
244         {
245             for( y = i_height; y < i_height + i_pady; y++ );
246                 memcpy( &frame->plane[i][y*frame->i_stride[i]],
247                         &frame->plane[i][(i_height-1)*frame->i_stride[i]],
248                         i_width + i_padx );
249         }
250     }
251 }
252
253
254 /* Deblocking filter */
255
256 static const int i_alpha_table[52] =
257 {
258      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
259      0,  0,  0,  0,  0,  0,  4,  4,  5,  6,
260      7,  8,  9, 10, 12, 13, 15, 17, 20, 22,
261     25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
262     80, 90,101,113,127,144,162,182,203,226,
263     255, 255
264 };
265 static const int i_beta_table[52] =
266 {
267      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
268      0,  0,  0,  0,  0,  0,  2,  2,  2,  3,
269      3,  3,  3,  4,  4,  4,  6,  6,  7,  7,
270      8,  8,  9,  9, 10, 10, 11, 11, 12, 12,
271     13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
272     18, 18
273 };
274 static const int i_tc0_table[52][3] =
275 {
276     { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
277     { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
278     { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 1 },
279     { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 1, 1 }, { 0, 1, 1 }, { 1, 1, 1 },
280     { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 2 }, { 1, 1, 2 },
281     { 1, 1, 2 }, { 1, 2, 3 }, { 1, 2, 3 }, { 2, 2, 3 }, { 2, 2, 4 }, { 2, 3, 4 },
282     { 2, 3, 4 }, { 3, 3, 5 }, { 3, 4, 6 }, { 3, 4, 6 }, { 4, 5, 7 }, { 4, 5, 8 },
283     { 4, 6, 9 }, { 5, 7,10 }, { 6, 8,11 }, { 6, 8,13 }, { 7,10,14 }, { 8,11,16 },
284     { 9,12,18 }, {10,13,20 }, {11,15,23 }, {13,17,25 }
285 };
286
287 /* From ffmpeg */
288 static inline int clip_uint8( int a )
289 {
290     if (a&(~255))
291         return (-a)>>31;
292     else
293         return a;
294 }
295
296 static inline void deblock_luma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
297 {
298     int i, d;
299     for( i = 0; i < 4; i++ ) {
300         if( tc0[i] < 0 ) {
301             pix += 4*ystride;
302             continue;
303         }
304         for( d = 0; d < 4; d++ ) {
305             const int p2 = pix[-3*xstride];
306             const int p1 = pix[-2*xstride];
307             const int p0 = pix[-1*xstride];
308             const int q0 = pix[ 0*xstride];
309             const int q1 = pix[ 1*xstride];
310             const int q2 = pix[ 2*xstride];
311    
312             if( X264_ABS( p0 - q0 ) < alpha &&
313                 X264_ABS( p1 - p0 ) < beta &&
314                 X264_ABS( q1 - q0 ) < beta ) {
315    
316                 int tc = tc0[i];
317                 int delta;
318    
319                 if( X264_ABS( p2 - p0 ) < beta ) {
320                     pix[-2*xstride] = p1 + x264_clip3( (( p2 + ((p0 + q0 + 1) >> 1)) >> 1) - p1, -tc0[i], tc0[i] );
321                     tc++; 
322                 }
323                 if( X264_ABS( q2 - q0 ) < beta ) {
324                     pix[ 1*xstride] = q1 + x264_clip3( (( q2 + ((p0 + q0 + 1) >> 1)) >> 1) - q1, -tc0[i], tc0[i] );
325                     tc++;
326                 }
327     
328                 delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
329                 pix[-1*xstride] = clip_uint8( p0 + delta );    /* p0' */
330                 pix[ 0*xstride] = clip_uint8( q0 - delta );    /* q0' */
331             }
332             pix += ystride;
333         }
334     }
335 }
336 static void deblock_v_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
337 {
338     deblock_luma_c( pix, stride, 1, alpha, beta, tc0 ); 
339 }
340 static void deblock_h_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
341 {
342     deblock_luma_c( pix, 1, stride, alpha, beta, tc0 );
343 }
344
345 static inline void deblock_chroma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
346 {
347     int i, d;
348     for( i = 0; i < 4; i++ ) {
349         const int tc = tc0[i];
350         if( tc <= 0 ) {
351             pix += 2*ystride;
352             continue;
353         }
354         for( d = 0; d < 2; d++ ) {
355             const int p1 = pix[-2*xstride];
356             const int p0 = pix[-1*xstride];
357             const int q0 = pix[ 0*xstride];
358             const int q1 = pix[ 1*xstride];
359
360             if( X264_ABS( p0 - q0 ) < alpha &&
361                 X264_ABS( p1 - p0 ) < beta &&
362                 X264_ABS( q1 - q0 ) < beta ) {
363
364                 int delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
365                 pix[-1*xstride] = clip_uint8( p0 + delta );    /* p0' */
366                 pix[ 0*xstride] = clip_uint8( q0 - delta );    /* q0' */
367             }
368             pix += ystride;
369         }
370     }
371 }
372 static void deblock_v_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
373 {   
374     deblock_chroma_c( pix, stride, 1, alpha, beta, tc0 );
375 }
376 static void deblock_h_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
377 {   
378     deblock_chroma_c( pix, 1, stride, alpha, beta, tc0 );
379 }
380
381 static inline void deblock_luma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
382 {
383     int d;
384     for( d = 0; d < 16; d++ ) {
385         const int p2 = pix[-3*xstride];
386         const int p1 = pix[-2*xstride];
387         const int p0 = pix[-1*xstride];
388         const int q0 = pix[ 0*xstride];
389         const int q1 = pix[ 1*xstride];
390         const int q2 = pix[ 2*xstride];
391
392         if( X264_ABS( p0 - q0 ) < alpha &&
393             X264_ABS( p1 - p0 ) < beta &&
394             X264_ABS( q1 - q0 ) < beta ) {
395
396             if(X264_ABS( p0 - q0 ) < ((alpha >> 2) + 2) ){
397                 if( X264_ABS( p2 - p0 ) < beta)
398                 {
399                     const int p3 = pix[-4*xstride];
400                     /* p0', p1', p2' */
401                     pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
402                     pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
403                     pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
404                 } else {
405                     /* p0' */
406                     pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
407                 }
408                 if( X264_ABS( q2 - q0 ) < beta)
409                 {
410                     const int q3 = pix[3*xstride];
411                     /* q0', q1', q2' */
412                     pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
413                     pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
414                     pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
415                 } else {
416                     /* q0' */
417                     pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
418                 }
419             }else{
420                 /* p0', q0' */
421                 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
422                 pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
423             }
424         }
425         pix += ystride;
426     }
427 }
428 static void deblock_v_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
429 {   
430     deblock_luma_intra_c( pix, stride, 1, alpha, beta );
431 }
432 static void deblock_h_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
433 {   
434     deblock_luma_intra_c( pix, 1, stride, alpha, beta );
435 }
436
437 static inline void deblock_chroma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
438 {   
439     int d; 
440     for( d = 0; d < 8; d++ ) {
441         const int p1 = pix[-2*xstride];
442         const int p0 = pix[-1*xstride];
443         const int q0 = pix[ 0*xstride];
444         const int q1 = pix[ 1*xstride];
445
446         if( X264_ABS( p0 - q0 ) < alpha &&
447             X264_ABS( p1 - p0 ) < beta &&
448             X264_ABS( q1 - q0 ) < beta ) {
449
450             pix[-1*xstride] = (2*p1 + p0 + q1 + 2) >> 2;   /* p0' */
451             pix[ 0*xstride] = (2*q1 + q0 + p1 + 2) >> 2;   /* q0' */
452         }
453
454         pix += ystride;
455     }
456 }
457 static void deblock_v_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
458 {   
459     deblock_chroma_intra_c( pix, stride, 1, alpha, beta );
460 }
461 static void deblock_h_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
462 {   
463     deblock_chroma_intra_c( pix, 1, stride, alpha, beta );
464 }
465
466 static inline void deblock_edge( x264_t *h, uint8_t *pix, int i_stride, int bS[4], int i_qp, int b_chroma,
467                                  x264_deblock_inter_t pf_inter, x264_deblock_intra_t pf_intra )
468 {
469     int i;
470     const int index_a = x264_clip3( i_qp + h->sh.i_alpha_c0_offset, 0, 51 );
471     const int alpha = i_alpha_table[index_a];
472     const int beta  = i_beta_table[x264_clip3( i_qp + h->sh.i_beta_offset, 0, 51 )];
473
474     if( bS[0] < 4 ) {
475         int8_t tc[4]; 
476         for(i=0; i<4; i++)
477             tc[i] = (bS[i] ? i_tc0_table[index_a][bS[i] - 1] : -1) + b_chroma;
478         pf_inter( pix, i_stride, alpha, beta, tc );
479     } else {
480         pf_intra( pix, i_stride, alpha, beta );
481     }
482 }
483
484 void x264_frame_deblocking_filter( x264_t *h, int i_slice_type )
485 {
486     const int s8x8 = 2 * h->mb.i_mb_stride;
487     const int s4x4 = 4 * h->mb.i_mb_stride;
488
489     int mb_y, mb_x;
490
491     for( mb_y = 0, mb_x = 0; mb_y < h->sps->i_mb_height; )
492     {
493         const int mb_xy  = mb_y * h->mb.i_mb_stride + mb_x;
494         const int mb_8x8 = 2 * s8x8 * mb_y + 2 * mb_x;
495         const int mb_4x4 = 4 * s4x4 * mb_y + 4 * mb_x;
496         int i_edge;
497         int i_dir;
498         const int b_8x8_transform = h->mb.mb_transform_size[mb_xy];
499
500         /* cavlc + 8x8 transform stores nnz per 16 coeffs for the purpose of
501          * entropy coding, but per 64 coeffs for the purpose of deblocking */
502         if( !h->param.b_cabac && b_8x8_transform )
503         {
504             uint32_t *nnz = (uint32_t*)h->mb.non_zero_count[mb_xy];
505             if( nnz[0] ) nnz[0] = 0x01010101;
506             if( nnz[1] ) nnz[1] = 0x01010101;
507             if( nnz[2] ) nnz[2] = 0x01010101;
508             if( nnz[3] ) nnz[3] = 0x01010101;
509         }
510
511         /* i_dir == 0 -> vertical edge
512          * i_dir == 1 -> horizontal edge */
513         for( i_dir = 0; i_dir < 2; i_dir++ )
514         {
515             int i_start;
516             int i_qp, i_qpn;
517
518             i_start = (( i_dir == 0 && mb_x != 0 ) || ( i_dir == 1 && mb_y != 0 ) ) ? 0 : 1;
519
520             for( i_edge = i_start; i_edge < 4; i_edge++ )
521             {
522                 int mbn_xy  = i_edge > 0 ? mb_xy  : ( i_dir == 0 ? mb_xy  - 1 : mb_xy - h->mb.i_mb_stride );
523                 int mbn_8x8 = i_edge > 0 ? mb_8x8 : ( i_dir == 0 ? mb_8x8 - 2 : mb_8x8 - 2 * s8x8 );
524                 int mbn_4x4 = i_edge > 0 ? mb_4x4 : ( i_dir == 0 ? mb_4x4 - 4 : mb_4x4 - 4 * s4x4 );
525
526                 int bS[4];  /* filtering strength */
527
528                 /* *** Get bS for each 4px for the current edge *** */
529                 if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy] ) )
530                 {
531                     bS[0] = bS[1] = bS[2] = bS[3] = ( i_edge == 0 ? 4 : 3 );
532                 }
533                 else
534                 {
535                     int i;
536                     for( i = 0; i < 4; i++ )
537                     {
538                         int x  = i_dir == 0 ? i_edge : i;
539                         int y  = i_dir == 0 ? i      : i_edge;
540                         int xn = (x - (i_dir == 0 ? 1 : 0 ))&0x03;
541                         int yn = (y - (i_dir == 0 ? 0 : 1 ))&0x03;
542
543                         if( h->mb.non_zero_count[mb_xy][block_idx_xy[x][y]] != 0 ||
544                             h->mb.non_zero_count[mbn_xy][block_idx_xy[xn][yn]] != 0 )
545                         {
546                             bS[i] = 2;
547                         }
548                         else
549                         {
550                             /* FIXME: A given frame may occupy more than one position in
551                              * the reference list. So we should compare the frame numbers,
552                              * not the indices in the ref list.
553                              * No harm yet, as we don't generate that case.*/
554
555                             int i8p= mb_8x8+(x/2)+(y/2)*s8x8;
556                             int i8q= mbn_8x8+(xn/2)+(yn/2)*s8x8;
557                             int i4p= mb_4x4+x+y*s4x4;
558                             int i4q= mbn_4x4+xn+yn*s4x4;
559                             int l;
560
561                             bS[i] = 0;
562
563                             for( l = 0; l < 1 + (i_slice_type == SLICE_TYPE_B); l++ )
564                             {
565                                 if( h->mb.ref[l][i8p] != h->mb.ref[l][i8q] ||
566                                     abs( h->mb.mv[l][i4p][0] - h->mb.mv[l][i4q][0] ) >= 4 ||
567                                     abs( h->mb.mv[l][i4p][1] - h->mb.mv[l][i4q][1] ) >= 4 )
568                                 {
569                                     bS[i] = 1;
570                                     break;
571                                 }
572                             }
573                         }
574                     }
575                 }
576
577                 /* *** filter *** */
578                 /* Y plane */
579                 i_qp = h->mb.qp[mb_xy];
580                 i_qpn= h->mb.qp[mbn_xy];
581
582                 if( i_dir == 0 )
583                 {
584                     /* vertical edge */
585                     if( !b_8x8_transform || !(i_edge & 1) )
586                     {
587                         deblock_edge( h, &h->fdec->plane[0][16*mb_y * h->fdec->i_stride[0] + 16*mb_x + 4*i_edge],
588                                       h->fdec->i_stride[0], bS, (i_qp+i_qpn+1) >> 1, 0,
589                                       h->loopf.deblock_h_luma, h->loopf.deblock_h_luma_intra );
590                     }
591                     if( !(i_edge & 1) )
592                     {
593                         /* U/V planes */
594                         int i_qpc = ( i_chroma_qp_table[x264_clip3( i_qp + h->pps->i_chroma_qp_index_offset, 0, 51 )] +
595                                       i_chroma_qp_table[x264_clip3( i_qpn + h->pps->i_chroma_qp_index_offset, 0, 51 )] + 1 ) >> 1;
596                         deblock_edge( h, &h->fdec->plane[1][8*(mb_y*h->fdec->i_stride[1]+mb_x)+2*i_edge],
597                                       h->fdec->i_stride[1], bS, i_qpc, 1,
598                                       h->loopf.deblock_h_chroma, h->loopf.deblock_h_chroma_intra );
599                         deblock_edge( h, &h->fdec->plane[2][8*(mb_y*h->fdec->i_stride[2]+mb_x)+2*i_edge],
600                                       h->fdec->i_stride[2], bS, i_qpc, 1,
601                                       h->loopf.deblock_h_chroma, h->loopf.deblock_h_chroma_intra );
602                     }
603                 }
604                 else
605                 {
606                     /* horizontal edge */
607                     if( !b_8x8_transform || !(i_edge & 1) )
608                     {
609                         deblock_edge( h, &h->fdec->plane[0][(16*mb_y + 4*i_edge) * h->fdec->i_stride[0] + 16*mb_x],
610                                       h->fdec->i_stride[0], bS, (i_qp+i_qpn+1) >> 1, 0,
611                                       h->loopf.deblock_v_luma, h->loopf.deblock_v_luma_intra );
612                     }
613                     /* U/V planes */
614                     if( !(i_edge & 1) )
615                     {
616                         int i_qpc = ( i_chroma_qp_table[x264_clip3( i_qp + h->pps->i_chroma_qp_index_offset, 0, 51 )] +
617                                       i_chroma_qp_table[x264_clip3( i_qpn + h->pps->i_chroma_qp_index_offset, 0, 51 )] + 1 ) >> 1;
618                         deblock_edge( h, &h->fdec->plane[1][8*(mb_y*h->fdec->i_stride[1]+mb_x)+2*i_edge*h->fdec->i_stride[1]],
619                                       h->fdec->i_stride[1], bS, i_qpc, 1,
620                                       h->loopf.deblock_v_chroma, h->loopf.deblock_v_chroma_intra );
621                         deblock_edge( h, &h->fdec->plane[2][8*(mb_y*h->fdec->i_stride[2]+mb_x)+2*i_edge*h->fdec->i_stride[2]],
622                                       h->fdec->i_stride[2], bS, i_qpc, 1,
623                                       h->loopf.deblock_v_chroma, h->loopf.deblock_v_chroma_intra );
624                     }
625                 }
626             }
627         }
628
629         /* newt mb */
630         mb_x++;
631         if( mb_x >= h->sps->i_mb_width )
632         {
633             mb_x = 0;
634             mb_y++;
635         }
636     }
637 }
638
639 #ifdef HAVE_MMXEXT
640 void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
641 void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
642 void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
643 void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
644 #endif
645
646 #ifdef ARCH_X86_64
647 void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
648 void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
649 #elif defined( HAVE_MMXEXT )
650 void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
651 void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
652
653 void x264_deblock_v_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
654 {
655     x264_deblock_v8_luma_mmxext( pix,   stride, alpha, beta, tc0   );
656     x264_deblock_v8_luma_mmxext( pix+8, stride, alpha, beta, tc0+2 );
657 }
658 #endif
659
660 void x264_deblock_init( int cpu, x264_deblock_function_t *pf )
661 {
662     pf->deblock_v_luma = deblock_v_luma_c;
663     pf->deblock_h_luma = deblock_h_luma_c;
664     pf->deblock_v_chroma = deblock_v_chroma_c;
665     pf->deblock_h_chroma = deblock_h_chroma_c;
666     pf->deblock_v_luma_intra = deblock_v_luma_intra_c;
667     pf->deblock_h_luma_intra = deblock_h_luma_intra_c;
668     pf->deblock_v_chroma_intra = deblock_v_chroma_intra_c;
669     pf->deblock_h_chroma_intra = deblock_h_chroma_intra_c;
670
671 #ifdef HAVE_MMXEXT
672     if( cpu&X264_CPU_MMXEXT )
673     {
674         pf->deblock_v_chroma = x264_deblock_v_chroma_mmxext;
675         pf->deblock_h_chroma = x264_deblock_h_chroma_mmxext;
676         pf->deblock_v_chroma_intra = x264_deblock_v_chroma_intra_mmxext;
677         pf->deblock_h_chroma_intra = x264_deblock_h_chroma_intra_mmxext;
678
679 #ifdef ARCH_X86_64
680         if( cpu&X264_CPU_SSE2 )
681         {
682             pf->deblock_v_luma = x264_deblock_v_luma_sse2;
683             pf->deblock_h_luma = x264_deblock_h_luma_sse2;
684         }
685 #else
686         pf->deblock_v_luma = x264_deblock_v_luma_mmxext;
687         pf->deblock_h_luma = x264_deblock_h_luma_mmxext;
688 #endif
689     }
690 #endif
691 }
692