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