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