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