4% faster deblock: special-case macroblock edges
[x262.git] / common / frame.c
1 /*****************************************************************************
2  * frame.c: h264 encoder library
3  *****************************************************************************
4  * Copyright (C) 2003-2008 x264 project
5  *
6  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7  *          Loren Merritt <lorenm@u.washington.edu>
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., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #include "common.h"
25
26 #define ALIGN(x,a) (((x)+((a)-1))&~((a)-1))
27
28 x264_frame_t *x264_frame_new( x264_t *h )
29 {
30     x264_frame_t *frame = x264_malloc( sizeof(x264_frame_t) );
31     int i, j;
32
33     int i_mb_count = h->mb.i_mb_count;
34     int i_stride, i_width, i_lines;
35     int i_padv = PADV << h->param.b_interlaced;
36     int luma_plane_size;
37     int align = h->param.cpu&X264_CPU_CACHELINE_64 ? 64 : h->param.cpu&X264_CPU_CACHELINE_32 ? 32 : 16;
38
39     if( !frame ) return NULL;
40
41     memset( frame, 0, sizeof(x264_frame_t) );
42
43     /* allocate frame data (+64 for extra data for me) */
44     i_width  = ALIGN( h->param.i_width, 16 );
45     i_stride = ALIGN( i_width + 2*PADH, align );
46     i_lines  = ALIGN( h->param.i_height, 16<<h->param.b_interlaced );
47
48     frame->i_plane = 3;
49     for( i = 0; i < 3; i++ )
50     {
51         frame->i_stride[i] = i_stride >> !!i;
52         frame->i_width[i] = i_width >> !!i;
53         frame->i_lines[i] = i_lines >> !!i;
54     }
55
56     luma_plane_size = (frame->i_stride[0] * ( frame->i_lines[0] + 2*i_padv ));
57     for( i = 1; i < 3; i++ )
58     {
59         CHECKED_MALLOC( frame->buffer[i], luma_plane_size/4 );
60         frame->plane[i] = frame->buffer[i] + (frame->i_stride[i] * i_padv + PADH)/2;
61     }
62     /* all 4 luma planes allocated together, since the cacheline split code
63      * requires them to be in-phase wrt cacheline alignment. */
64     CHECKED_MALLOC( frame->buffer[0], 4*luma_plane_size);
65     for( i = 0; i < 4; i++ )
66         frame->filtered[i] = frame->buffer[0] + i*luma_plane_size + frame->i_stride[0] * i_padv + PADH;
67     frame->plane[0] = frame->filtered[0];
68
69     if( h->frames.b_have_lowres )
70     {
71         frame->i_width_lowres = frame->i_width[0]/2;
72         frame->i_stride_lowres = ALIGN( frame->i_width_lowres + 2*PADH, align );
73         frame->i_lines_lowres = frame->i_lines[0]/2;
74
75         luma_plane_size = frame->i_stride_lowres * ( frame->i_lines[0]/2 + 2*i_padv );
76
77         CHECKED_MALLOC( frame->buffer_lowres[0], 4 * luma_plane_size );
78         for( i = 0; i < 4; i++ )
79             frame->lowres[i] = frame->buffer_lowres[0] + (frame->i_stride_lowres * i_padv + PADH) + i * luma_plane_size;
80     }
81
82     if( h->param.analyse.i_me_method >= X264_ME_ESA )
83     {
84         CHECKED_MALLOC( frame->buffer[3],
85                         2 * frame->i_stride[0] * (frame->i_lines[0] + 2*i_padv) * sizeof(uint16_t) );
86         frame->integral = (uint16_t*)frame->buffer[3] + frame->i_stride[0] * i_padv + PADH;
87     }
88
89     frame->i_poc = -1;
90     frame->i_type = X264_TYPE_AUTO;
91     frame->i_qpplus1 = 0;
92     frame->i_pts = -1;
93     frame->i_frame = -1;
94     frame->i_frame_num = -1;
95     frame->i_lines_completed = -1;
96
97     CHECKED_MALLOC( frame->mb_type, i_mb_count * sizeof(int8_t));
98     CHECKED_MALLOC( frame->mv[0], 2*16 * i_mb_count * sizeof(int16_t) );
99     CHECKED_MALLOC( frame->ref[0], 4 * i_mb_count * sizeof(int8_t) );
100     if( h->param.i_bframe )
101     {
102         CHECKED_MALLOC( frame->mv[1], 2*16 * i_mb_count * sizeof(int16_t) );
103         CHECKED_MALLOC( frame->ref[1], 4 * i_mb_count * sizeof(int8_t) );
104     }
105     else
106     {
107         frame->mv[1]  = NULL;
108         frame->ref[1] = NULL;
109     }
110
111     CHECKED_MALLOC( frame->i_row_bits, i_lines/16 * sizeof(int) );
112     CHECKED_MALLOC( frame->i_row_qp, i_lines/16 * sizeof(int) );
113     for( i = 0; i < h->param.i_bframe + 2; i++ )
114         for( j = 0; j < h->param.i_bframe + 2; j++ )
115             CHECKED_MALLOC( frame->i_row_satds[i][j], i_lines/16 * sizeof(int) );
116
117     x264_pthread_mutex_init( &frame->mutex, NULL );
118     x264_pthread_cond_init( &frame->cv, NULL );
119
120     return frame;
121
122 fail:
123     x264_frame_delete( frame );
124     return NULL;
125 }
126
127 void x264_frame_delete( x264_frame_t *frame )
128 {
129     int i, j;
130     for( i = 0; i < 4; i++ )
131         x264_free( frame->buffer[i] );
132     for( i = 0; i < 4; i++ )
133         x264_free( frame->buffer_lowres[i] );
134     for( i = 0; i < X264_BFRAME_MAX+2; i++ )
135         for( j = 0; j < X264_BFRAME_MAX+2; j++ )
136             x264_free( frame->i_row_satds[i][j] );
137     x264_free( frame->i_row_bits );
138     x264_free( frame->i_row_qp );
139     x264_free( frame->mb_type );
140     x264_free( frame->mv[0] );
141     x264_free( frame->mv[1] );
142     x264_free( frame->ref[0] );
143     x264_free( frame->ref[1] );
144     x264_pthread_mutex_destroy( &frame->mutex );
145     x264_pthread_cond_destroy( &frame->cv );
146     x264_free( frame );
147 }
148
149 int x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
150 {
151     int i_csp = src->img.i_csp & X264_CSP_MASK;
152     int i;
153     if( i_csp != X264_CSP_I420 && i_csp != X264_CSP_YV12 )
154     {
155         x264_log( h, X264_LOG_ERROR, "Arg invalid CSP\n" );
156         return -1;
157     }
158
159     dst->i_type     = src->i_type;
160     dst->i_qpplus1  = src->i_qpplus1;
161     dst->i_pts      = src->i_pts;
162
163     for( i=0; i<3; i++ )
164     {
165         int s = (i_csp == X264_CSP_YV12 && i) ? i^3 : i;
166         uint8_t *plane = src->img.plane[s];
167         int stride = src->img.i_stride[s];
168         int width = h->param.i_width >> !!i;
169         int height = h->param.i_height >> !!i;
170         if( src->img.i_csp & X264_CSP_VFLIP )
171         {
172             plane += (height-1)*stride;
173             stride = -stride;
174         }
175         h->mc.plane_copy( dst->plane[i], dst->i_stride[i], plane, stride, width, height );
176     }
177     return 0;
178 }
179
180
181
182 static void plane_expand_border( uint8_t *pix, int i_stride, int i_width, int i_height, int i_padh, int i_padv, int b_pad_top, int b_pad_bottom )
183 {
184 #define PPIXEL(x, y) ( pix + (x) + (y)*i_stride )
185     int y;
186     for( y = 0; y < i_height; y++ )
187     {
188         /* left band */
189         memset( PPIXEL(-i_padh, y), PPIXEL(0, y)[0], i_padh );
190         /* right band */
191         memset( PPIXEL(i_width, y), PPIXEL(i_width-1, y)[0], i_padh );
192     }
193     /* upper band */
194     if( b_pad_top )
195     for( y = 0; y < i_padv; y++ )
196         memcpy( PPIXEL(-i_padh, -y-1), PPIXEL(-i_padh, 0), i_width+2*i_padh );
197     /* lower band */
198     if( b_pad_bottom )
199     for( y = 0; y < i_padv; y++ )
200         memcpy( PPIXEL(-i_padh, i_height+y), PPIXEL(-i_padh, i_height-1), i_width+2*i_padh );
201 #undef PPIXEL
202 }
203
204 void x264_frame_expand_border( x264_t *h, x264_frame_t *frame, int mb_y, int b_end )
205 {
206     int i;
207     int b_start = !mb_y;
208     if( mb_y & h->sh.b_mbaff )
209         return;
210     for( i = 0; i < frame->i_plane; i++ )
211     {
212         int stride = frame->i_stride[i];
213         int width = 16*h->sps->i_mb_width >> !!i;
214         int height = (b_end ? 16*(h->sps->i_mb_height - mb_y) >> h->sh.b_mbaff : 16) >> !!i;
215         int padh = PADH >> !!i;
216         int padv = PADV >> !!i;
217         // buffer: 2 chroma, 3 luma (rounded to 4) because deblocking goes beyond the top of the mb
218         uint8_t *pix = frame->plane[i] + X264_MAX(0, (16*mb_y-4)*stride >> !!i);
219         if( b_end && !b_start )
220             height += 4 >> (!!i + h->sh.b_mbaff);
221         if( h->sh.b_mbaff )
222         {
223             plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end );
224             plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end );
225         }
226         else
227         {
228             plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end );
229         }
230     }
231 }
232
233 void x264_frame_expand_border_filtered( x264_t *h, x264_frame_t *frame, int mb_y, int b_end )
234 {
235     /* during filtering, 8 extra pixels were filtered on each edge,
236      * but up to 3 of the horizontal ones may be wrong. 
237        we want to expand border from the last filtered pixel */
238     int b_start = !mb_y;
239     int stride = frame->i_stride[0];
240     int width = 16*h->sps->i_mb_width + 8;
241     int height = b_end ? (16*(h->sps->i_mb_height - mb_y) >> h->sh.b_mbaff) + 16 : 16;
242     int padh = PADH - 4;
243     int padv = PADV - 8;
244     int i;
245     for( i = 1; i < 4; i++ )
246     {
247         // buffer: 8 luma, to match the hpel filter
248         uint8_t *pix = frame->filtered[i] + (16*mb_y - (8 << h->sh.b_mbaff)) * stride - 4;
249         if( h->sh.b_mbaff )
250         {
251             plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end );
252             plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end );
253         }
254         else
255         {
256             plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end );
257         }
258     }
259 }
260
261 void x264_frame_expand_border_lowres( x264_frame_t *frame )
262 {
263     int i;
264     for( i = 0; i < 4; i++ )
265         plane_expand_border( frame->lowres[i], frame->i_stride_lowres, frame->i_stride_lowres - 2*PADH, frame->i_lines_lowres, PADH, PADV, 1, 1 );
266 }
267
268 void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame )
269 {
270     int i, y;
271     for( i = 0; i < frame->i_plane; i++ )
272     {
273         int i_subsample = i ? 1 : 0;
274         int i_width = h->param.i_width >> i_subsample;
275         int i_height = h->param.i_height >> i_subsample;
276         int i_padx = ( h->sps->i_mb_width * 16 - h->param.i_width ) >> i_subsample;
277         int i_pady = ( h->sps->i_mb_height * 16 - h->param.i_height ) >> i_subsample;
278
279         if( i_padx )
280         {
281             for( y = 0; y < i_height; y++ )
282                 memset( &frame->plane[i][y*frame->i_stride[i] + i_width],
283                          frame->plane[i][y*frame->i_stride[i] + i_width - 1],
284                          i_padx );
285         }
286         if( i_pady )
287         {
288             //FIXME interlace? or just let it pad using the wrong field
289             for( y = i_height; y < i_height + i_pady; y++ )
290                 memcpy( &frame->plane[i][y*frame->i_stride[i]],
291                         &frame->plane[i][(i_height-1)*frame->i_stride[i]],
292                         i_width + i_padx );
293         }
294     }
295 }
296
297
298 /* cavlc + 8x8 transform stores nnz per 16 coeffs for the purpose of
299  * entropy coding, but per 64 coeffs for the purpose of deblocking */
300 void munge_cavlc_nnz_row( x264_t *h, int mb_y, uint8_t (*buf)[16] )
301 {
302     uint32_t (*src)[6] = (uint32_t(*)[6])h->mb.non_zero_count + mb_y * h->sps->i_mb_width;
303     int8_t *transform = h->mb.mb_transform_size + mb_y * h->sps->i_mb_width;
304     int x, nnz;
305     for( x=0; x<h->sps->i_mb_width; x++ )
306     {
307         memcpy( buf+x, src+x, 16 );
308         if( transform[x] )
309         {
310             nnz = src[x][0] | src[x][1];
311             src[x][0] = src[x][1] = ((uint16_t)nnz ? 0x0101 : 0) + (nnz>>16 ? 0x01010000 : 0);
312             nnz = src[x][2] | src[x][3];
313             src[x][2] = src[x][3] = ((uint16_t)nnz ? 0x0101 : 0) + (nnz>>16 ? 0x01010000 : 0);
314         }
315     }
316 }
317
318 static void restore_cavlc_nnz_row( x264_t *h, int mb_y, uint8_t (*buf)[16] )
319 {
320     uint8_t (*dst)[24] = h->mb.non_zero_count + mb_y * h->sps->i_mb_width;
321     int x;
322     for( x=0; x<h->sps->i_mb_width; x++ )
323         memcpy( dst+x, buf+x, 16 );
324 }
325
326 static void munge_cavlc_nnz( x264_t *h, int mb_y, uint8_t (*buf)[16], void (*func)(x264_t*, int, uint8_t (*)[16]) )
327 {
328     func( h, mb_y, buf );
329     if( mb_y > 0 )
330         func( h, mb_y-1, buf + h->sps->i_mb_width );
331     if( h->sh.b_mbaff )
332     {
333         func( h, mb_y+1, buf + h->sps->i_mb_width * 2 );
334         if( mb_y > 0 )
335             func( h, mb_y-2, buf + h->sps->i_mb_width * 3 );
336     }
337 }
338
339
340 /* Deblocking filter */
341 static const uint8_t i_alpha_table[52+12*2] =
342 {
343      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
344      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
345      0,  0,  0,  0,  0,  0,  4,  4,  5,  6,
346      7,  8,  9, 10, 12, 13, 15, 17, 20, 22,
347     25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
348     80, 90,101,113,127,144,162,182,203,226,
349    255,255,
350    255,255,255,255,255,255,255,255,255,255,255,255,
351 };
352 static const uint8_t i_beta_table[52+12*2] =
353 {
354      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
355      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
356      0,  0,  0,  0,  0,  0,  2,  2,  2,  3,
357      3,  3,  3,  4,  4,  4,  6,  6,  7,  7,
358      8,  8,  9,  9, 10, 10, 11, 11, 12, 12,
359     13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
360     18, 18,
361     18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
362 };
363 static const int8_t i_tc0_table[52+12*2][4] =
364 {
365     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
366     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
367     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
368     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
369     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 1 },
370     {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 1, 1 }, {-1, 0, 1, 1 }, {-1, 1, 1, 1 },
371     {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 },
372     {-1, 1, 1, 2 }, {-1, 1, 2, 3 }, {-1, 1, 2, 3 }, {-1, 2, 2, 3 }, {-1, 2, 2, 4 }, {-1, 2, 3, 4 },
373     {-1, 2, 3, 4 }, {-1, 3, 3, 5 }, {-1, 3, 4, 6 }, {-1, 3, 4, 6 }, {-1, 4, 5, 7 }, {-1, 4, 5, 8 },
374     {-1, 4, 6, 9 }, {-1, 5, 7,10 }, {-1, 6, 8,11 }, {-1, 6, 8,13 }, {-1, 7,10,14 }, {-1, 8,11,16 },
375     {-1, 9,12,18 }, {-1,10,13,20 }, {-1,11,15,23 }, {-1,13,17,25 },
376     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
377     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
378 };
379 #define alpha_table(x) i_alpha_table[(x)+12]
380 #define beta_table(x)  i_beta_table[(x)+12]
381 #define tc0_table(x)   i_tc0_table[(x)+12]
382
383 /* From ffmpeg */
384 static inline int clip_uint8( int a )
385 {
386     if (a&(~255))
387         return (-a)>>31;
388     else
389         return a;
390 }
391
392 static inline void deblock_luma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
393 {
394     int i, d;
395     for( i = 0; i < 4; i++ ) {
396         if( tc0[i] < 0 ) {
397             pix += 4*ystride;
398             continue;
399         }
400         for( d = 0; d < 4; d++ ) {
401             const int p2 = pix[-3*xstride];
402             const int p1 = pix[-2*xstride];
403             const int p0 = pix[-1*xstride];
404             const int q0 = pix[ 0*xstride];
405             const int q1 = pix[ 1*xstride];
406             const int q2 = pix[ 2*xstride];
407    
408             if( abs( p0 - q0 ) < alpha &&
409                 abs( p1 - p0 ) < beta &&
410                 abs( q1 - q0 ) < beta ) {
411    
412                 int tc = tc0[i];
413                 int delta;
414    
415                 if( abs( p2 - p0 ) < beta ) {
416                     pix[-2*xstride] = p1 + x264_clip3( (( p2 + ((p0 + q0 + 1) >> 1)) >> 1) - p1, -tc0[i], tc0[i] );
417                     tc++;
418                 }
419                 if( abs( q2 - q0 ) < beta ) {
420                     pix[ 1*xstride] = q1 + x264_clip3( (( q2 + ((p0 + q0 + 1) >> 1)) >> 1) - q1, -tc0[i], tc0[i] );
421                     tc++;
422                 }
423     
424                 delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
425                 pix[-1*xstride] = clip_uint8( p0 + delta );    /* p0' */
426                 pix[ 0*xstride] = clip_uint8( q0 - delta );    /* q0' */
427             }
428             pix += ystride;
429         }
430     }
431 }
432 static void deblock_v_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
433 {
434     deblock_luma_c( pix, stride, 1, alpha, beta, tc0 ); 
435 }
436 static void deblock_h_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
437 {
438     deblock_luma_c( pix, 1, stride, alpha, beta, tc0 );
439 }
440
441 static inline void deblock_chroma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
442 {
443     int i, d;
444     for( i = 0; i < 4; i++ ) {
445         const int tc = tc0[i];
446         if( tc <= 0 ) {
447             pix += 2*ystride;
448             continue;
449         }
450         for( d = 0; d < 2; d++ ) {
451             const int p1 = pix[-2*xstride];
452             const int p0 = pix[-1*xstride];
453             const int q0 = pix[ 0*xstride];
454             const int q1 = pix[ 1*xstride];
455
456             if( abs( p0 - q0 ) < alpha &&
457                 abs( p1 - p0 ) < beta &&
458                 abs( q1 - q0 ) < beta ) {
459
460                 int delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
461                 pix[-1*xstride] = clip_uint8( p0 + delta );    /* p0' */
462                 pix[ 0*xstride] = clip_uint8( q0 - delta );    /* q0' */
463             }
464             pix += ystride;
465         }
466     }
467 }
468 static void deblock_v_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
469 {   
470     deblock_chroma_c( pix, stride, 1, alpha, beta, tc0 );
471 }
472 static void deblock_h_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
473 {   
474     deblock_chroma_c( pix, 1, stride, alpha, beta, tc0 );
475 }
476
477 static inline void deblock_luma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
478 {
479     int d;
480     for( d = 0; d < 16; d++ ) {
481         const int p2 = pix[-3*xstride];
482         const int p1 = pix[-2*xstride];
483         const int p0 = pix[-1*xstride];
484         const int q0 = pix[ 0*xstride];
485         const int q1 = pix[ 1*xstride];
486         const int q2 = pix[ 2*xstride];
487
488         if( abs( p0 - q0 ) < alpha &&
489             abs( p1 - p0 ) < beta &&
490             abs( q1 - q0 ) < beta ) {
491
492             if(abs( p0 - q0 ) < ((alpha >> 2) + 2) ){
493                 if( abs( p2 - p0 ) < beta)
494                 {
495                     const int p3 = pix[-4*xstride];
496                     /* p0', p1', p2' */
497                     pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
498                     pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
499                     pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
500                 } else {
501                     /* p0' */
502                     pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
503                 }
504                 if( abs( q2 - q0 ) < beta)
505                 {
506                     const int q3 = pix[3*xstride];
507                     /* q0', q1', q2' */
508                     pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
509                     pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
510                     pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
511                 } else {
512                     /* q0' */
513                     pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
514                 }
515             }else{
516                 /* p0', q0' */
517                 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
518                 pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
519             }
520         }
521         pix += ystride;
522     }
523 }
524 static void deblock_v_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
525 {   
526     deblock_luma_intra_c( pix, stride, 1, alpha, beta );
527 }
528 static void deblock_h_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
529 {   
530     deblock_luma_intra_c( pix, 1, stride, alpha, beta );
531 }
532
533 static inline void deblock_chroma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
534 {   
535     int d; 
536     for( d = 0; d < 8; d++ ) {
537         const int p1 = pix[-2*xstride];
538         const int p0 = pix[-1*xstride];
539         const int q0 = pix[ 0*xstride];
540         const int q1 = pix[ 1*xstride];
541
542         if( abs( p0 - q0 ) < alpha &&
543             abs( p1 - p0 ) < beta &&
544             abs( q1 - q0 ) < beta ) {
545
546             pix[-1*xstride] = (2*p1 + p0 + q1 + 2) >> 2;   /* p0' */
547             pix[ 0*xstride] = (2*q1 + q0 + p1 + 2) >> 2;   /* q0' */
548         }
549
550         pix += ystride;
551     }
552 }
553 static void deblock_v_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
554 {   
555     deblock_chroma_intra_c( pix, stride, 1, alpha, beta );
556 }
557 static void deblock_h_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
558 {   
559     deblock_chroma_intra_c( pix, 1, stride, alpha, beta );
560 }
561
562 static inline void deblock_edge( x264_t *h, uint8_t *pix1, uint8_t *pix2, int i_stride, uint8_t bS[4], int i_qp, int b_chroma, x264_deblock_inter_t pf_inter )
563 {
564     const int index_a = i_qp + h->sh.i_alpha_c0_offset;
565     const int alpha = alpha_table(index_a);
566     const int beta  = beta_table(i_qp + h->sh.i_beta_offset);
567     int8_t tc[4];
568
569     if( !alpha || !beta )
570         return;
571
572     tc[0] = tc0_table(index_a)[bS[0]] + b_chroma;
573     tc[1] = tc0_table(index_a)[bS[1]] + b_chroma;
574     tc[2] = tc0_table(index_a)[bS[2]] + b_chroma;
575     tc[3] = tc0_table(index_a)[bS[3]] + b_chroma;
576
577     pf_inter( pix1, i_stride, alpha, beta, tc );
578     if(b_chroma)
579         pf_inter( pix2, i_stride, alpha, beta, tc );
580 }
581
582 static inline void deblock_edge_intra( x264_t *h, uint8_t *pix1, uint8_t *pix2, int i_stride, uint8_t bS[4], int i_qp, int b_chroma, x264_deblock_intra_t pf_intra )
583 {
584     const int alpha = alpha_table(i_qp + h->sh.i_alpha_c0_offset);
585     const int beta  = beta_table(i_qp + h->sh.i_beta_offset);
586
587     if( !alpha || !beta )
588         return;
589
590     pf_intra( pix1, i_stride, alpha, beta );
591     if(b_chroma)
592         pf_intra( pix2, i_stride, alpha, beta );
593 }
594
595 void x264_frame_deblock_row( x264_t *h, int mb_y )
596 {
597     const int s8x8 = 2 * h->mb.i_mb_stride;
598     const int s4x4 = 4 * h->mb.i_mb_stride;
599     const int b_interlaced = h->sh.b_mbaff;
600     const int mvy_limit = 4 >> b_interlaced;
601     const int qp_thresh = 15 - X264_MIN(h->sh.i_alpha_c0_offset, h->sh.i_beta_offset) - X264_MAX(0, h->param.analyse.i_chroma_qp_offset);
602     int mb_x;
603     int stridey   = h->fdec->i_stride[0];
604     int stride2y  = stridey << b_interlaced;
605     int strideuv  = h->fdec->i_stride[1];
606     int stride2uv = strideuv << b_interlaced;
607
608     if( !h->pps->b_cabac && h->pps->b_transform_8x8_mode )
609         munge_cavlc_nnz( h, mb_y, h->mb.nnz_backup, munge_cavlc_nnz_row );
610
611     for( mb_x = 0; mb_x < h->sps->i_mb_width; mb_x += (~b_interlaced | mb_y)&1, mb_y ^= b_interlaced )
612     {
613         const int mb_xy  = mb_y * h->mb.i_mb_stride + mb_x;
614         const int mb_8x8 = 2 * s8x8 * mb_y + 2 * mb_x;
615         const int mb_4x4 = 4 * s4x4 * mb_y + 4 * mb_x;
616         const int b_8x8_transform = h->mb.mb_transform_size[mb_xy];
617         const int i_qp = h->mb.qp[mb_xy];
618         int i_edge_end = (h->mb.type[mb_xy] == P_SKIP) ? 1 : 4;
619         uint8_t *pixy = h->fdec->plane[0] + 16*mb_y*stridey  + 16*mb_x;
620         uint8_t *pixu = h->fdec->plane[1] +  8*mb_y*strideuv +  8*mb_x;
621         uint8_t *pixv = h->fdec->plane[2] +  8*mb_y*strideuv +  8*mb_x;
622         if( b_interlaced && (mb_y&1) )
623         {
624             pixy -= 15*stridey;
625             pixu -=  7*strideuv;
626             pixv -=  7*strideuv;
627         }
628
629         x264_prefetch_fenc( h, h->fdec, mb_x, mb_y );
630
631         if( i_qp <= qp_thresh )
632             i_edge_end = 1;
633
634         #define FILTER_DIR(intra, i_dir)\
635         {\
636             /* Y plane */\
637             i_qpn= h->mb.qp[mbn_xy];\
638             if( i_dir == 0 )\
639             {\
640                 /* vertical edge */\
641                 deblock_edge##intra( h, pixy + 4*i_edge, NULL,\
642                               stride2y, bS, (i_qp+i_qpn+1) >> 1, 0,\
643                               h->loopf.deblock_h_luma##intra );\
644                 if( !(i_edge & 1) )\
645                 {\
646                     /* U/V planes */\
647                     int i_qpc = (h->chroma_qp_table[i_qp] + h->chroma_qp_table[i_qpn] + 1) >> 1;\
648                     deblock_edge##intra( h, pixu + 2*i_edge, pixv + 2*i_edge,\
649                                   stride2uv, bS, i_qpc, 1,\
650                                   h->loopf.deblock_h_chroma##intra );\
651                 }\
652             }\
653             else\
654             {\
655                 /* horizontal edge */\
656                 deblock_edge##intra( h, pixy + 4*i_edge*stride2y, NULL,\
657                               stride2y, bS, (i_qp+i_qpn+1) >> 1, 0,\
658                               h->loopf.deblock_v_luma##intra );\
659                 /* U/V planes */\
660                 if( !(i_edge & 1) )\
661                 {\
662                     int i_qpc = (h->chroma_qp_table[i_qp] + h->chroma_qp_table[i_qpn] + 1) >> 1;\
663                     deblock_edge##intra( h, pixu + 2*i_edge*stride2uv, pixv + 2*i_edge*stride2uv,\
664                                   stride2uv, bS, i_qpc, 1,\
665                                   h->loopf.deblock_v_chroma##intra );\
666                 }\
667             }\
668         }
669
670         #define DEBLOCK_STRENGTH(i_dir)\
671         {\
672             /* *** Get bS for each 4px for the current edge *** */\
673             if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy]) )\
674                 *(uint32_t*)bS = 0x03030303;\
675             else\
676             {\
677                 *(uint32_t*)bS = 0x00000000;\
678                 for( i = 0; i < 4; i++ )\
679                 {\
680                     int x  = i_dir == 0 ? i_edge : i;\
681                     int y  = i_dir == 0 ? i      : i_edge;\
682                     int xn = i_dir == 0 ? (x - 1)&0x03 : x;\
683                     int yn = i_dir == 0 ? y : (y - 1)&0x03;\
684                     if( h->mb.non_zero_count[mb_xy][x+y*4] != 0 ||\
685                         h->mb.non_zero_count[mbn_xy][xn+yn*4] != 0 )\
686                         bS[i] = 2;\
687                     else\
688                     {\
689                         /* FIXME: A given frame may occupy more than one position in\
690                          * the reference list. So we should compare the frame numbers,\
691                          * not the indices in the ref list.\
692                          * No harm yet, as we don't generate that case.*/\
693                         int i8p= mb_8x8+(x>>1)+(y>>1)*s8x8;\
694                         int i8q= mbn_8x8+(xn>>1)+(yn>>1)*s8x8;\
695                         int i4p= mb_4x4+x+y*s4x4;\
696                         int i4q= mbn_4x4+xn+yn*s4x4;\
697                         for( l = 0; l < 1 + (h->sh.i_type == SLICE_TYPE_B); l++ )\
698                             if( h->mb.ref[l][i8p] != h->mb.ref[l][i8q] ||\
699                                 abs( h->mb.mv[l][i4p][0] - h->mb.mv[l][i4q][0] ) >= 4 ||\
700                                 abs( h->mb.mv[l][i4p][1] - h->mb.mv[l][i4q][1] ) >= mvy_limit )\
701                             {\
702                                 bS[i] = 1;\
703                                 break;\
704                             }\
705                     }\
706                 }\
707             }\
708         }
709
710         /* i_dir == 0 -> vertical edge
711          * i_dir == 1 -> horizontal edge */
712         #define DEBLOCK_DIR(i_dir)\
713         {\
714             int i_edge = (i_dir ? (mb_y <= b_interlaced) : (mb_x == 0));\
715             int i_qpn, i, l, mbn_xy, mbn_8x8, mbn_4x4;\
716             DECLARE_ALIGNED_4( uint8_t bS[4] );  /* filtering strength */\
717             if( i_edge )\
718                 i_edge+= b_8x8_transform;\
719             else\
720             {\
721                 mbn_xy  = i_dir == 0 ? mb_xy  - 1 : mb_xy - h->mb.i_mb_stride;\
722                 mbn_8x8 = i_dir == 0 ? mb_8x8 - 2 : mb_8x8 - 2 * s8x8;\
723                 mbn_4x4 = i_dir == 0 ? mb_4x4 - 4 : mb_4x4 - 4 * s4x4;\
724                 if( b_interlaced && i_dir == 1 )\
725                 {\
726                     mbn_xy -= h->mb.i_mb_stride;\
727                     mbn_8x8 -= 2 * s8x8;\
728                     mbn_4x4 -= 4 * s4x4;\
729                 }\
730                 else if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy]) )\
731                 {\
732                     FILTER_DIR( _intra, i_dir );\
733                     goto end##i_dir;\
734                 }\
735                 DEBLOCK_STRENGTH(i_dir);\
736                 if( *(uint32_t*)bS )\
737                     FILTER_DIR( , i_dir);\
738                 end##i_dir:\
739                 i_edge += b_8x8_transform+1;\
740             }\
741             mbn_xy  = mb_xy;\
742             mbn_8x8 = mb_8x8;\
743             mbn_4x4 = mb_4x4;\
744             for( ; i_edge < i_edge_end; i_edge+=b_8x8_transform+1 )\
745             {\
746                 DEBLOCK_STRENGTH(i_dir);\
747                 if( *(uint32_t*)bS )\
748                     FILTER_DIR( , i_dir);\
749             }\
750         }
751
752         DEBLOCK_DIR(0);
753         DEBLOCK_DIR(1);
754     }
755
756     if( !h->pps->b_cabac && h->pps->b_transform_8x8_mode )
757         munge_cavlc_nnz( h, mb_y, h->mb.nnz_backup, restore_cavlc_nnz_row );
758 }
759
760 void x264_frame_deblock( x264_t *h )
761 {
762     int mb_y;
763     for( mb_y = 0; mb_y < h->sps->i_mb_height; mb_y += 1 + h->sh.b_mbaff )
764         x264_frame_deblock_row( h, mb_y );
765 }
766
767 #ifdef HAVE_MMX
768 void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
769 void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
770 void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
771 void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
772
773 void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
774 void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
775 void x264_deblock_v_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta );
776 void x264_deblock_h_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta );
777 #ifdef ARCH_X86
778 void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
779 void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
780 void x264_deblock_h_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
781 void x264_deblock_v8_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
782
783 void x264_deblock_v_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
784 {
785     x264_deblock_v8_luma_mmxext( pix,   stride, alpha, beta, tc0   );
786     x264_deblock_v8_luma_mmxext( pix+8, stride, alpha, beta, tc0+2 );
787 }
788 void x264_deblock_v_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
789 {
790     x264_deblock_v8_luma_intra_mmxext( pix,   stride, alpha, beta );
791     x264_deblock_v8_luma_intra_mmxext( pix+8, stride, alpha, beta );
792 }
793 #endif
794 #endif
795
796 #ifdef ARCH_PPC
797 void x264_deblock_v_luma_altivec( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
798 void x264_deblock_h_luma_altivec( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
799 #endif // ARCH_PPC
800
801 void x264_deblock_init( int cpu, x264_deblock_function_t *pf )
802 {
803     pf->deblock_v_luma = deblock_v_luma_c;
804     pf->deblock_h_luma = deblock_h_luma_c;
805     pf->deblock_v_chroma = deblock_v_chroma_c;
806     pf->deblock_h_chroma = deblock_h_chroma_c;
807     pf->deblock_v_luma_intra = deblock_v_luma_intra_c;
808     pf->deblock_h_luma_intra = deblock_h_luma_intra_c;
809     pf->deblock_v_chroma_intra = deblock_v_chroma_intra_c;
810     pf->deblock_h_chroma_intra = deblock_h_chroma_intra_c;
811
812 #ifdef HAVE_MMX
813     if( cpu&X264_CPU_MMXEXT )
814     {
815         pf->deblock_v_chroma = x264_deblock_v_chroma_mmxext;
816         pf->deblock_h_chroma = x264_deblock_h_chroma_mmxext;
817         pf->deblock_v_chroma_intra = x264_deblock_v_chroma_intra_mmxext;
818         pf->deblock_h_chroma_intra = x264_deblock_h_chroma_intra_mmxext;
819 #ifdef ARCH_X86
820         pf->deblock_v_luma = x264_deblock_v_luma_mmxext;
821         pf->deblock_h_luma = x264_deblock_h_luma_mmxext;
822         pf->deblock_v_luma_intra = x264_deblock_v_luma_intra_mmxext;
823         pf->deblock_h_luma_intra = x264_deblock_h_luma_intra_mmxext;
824 #endif
825         if( (cpu&X264_CPU_SSE2) && !(cpu&X264_CPU_STACK_MOD4) )
826         {
827             pf->deblock_v_luma = x264_deblock_v_luma_sse2;
828             pf->deblock_h_luma = x264_deblock_h_luma_sse2;
829             pf->deblock_v_luma_intra = x264_deblock_v_luma_intra_sse2;
830             pf->deblock_h_luma_intra = x264_deblock_h_luma_intra_sse2;
831         }
832     }
833 #endif
834
835 #ifdef ARCH_PPC
836     if( cpu&X264_CPU_ALTIVEC )
837     {
838         pf->deblock_v_luma = x264_deblock_v_luma_altivec;
839         pf->deblock_h_luma = x264_deblock_h_luma_altivec;
840    }
841 #endif // ARCH_PPC
842 }
843
844
845 /* threading */
846 void x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed )
847 {
848     x264_pthread_mutex_lock( &frame->mutex );
849     frame->i_lines_completed = i_lines_completed;
850     x264_pthread_cond_broadcast( &frame->cv );
851     x264_pthread_mutex_unlock( &frame->mutex );
852 }
853
854 void x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed )
855 {
856     x264_pthread_mutex_lock( &frame->mutex );
857     while( frame->i_lines_completed < i_lines_completed )
858         x264_pthread_cond_wait( &frame->cv, &frame->mutex );
859     x264_pthread_mutex_unlock( &frame->mutex );
860 }
861
862 /* list operators */
863
864 void x264_frame_push( x264_frame_t **list, x264_frame_t *frame )
865 {
866     int i = 0;
867     while( list[i] ) i++;
868     list[i] = frame;
869 }
870
871 x264_frame_t *x264_frame_pop( x264_frame_t **list )
872 {
873     x264_frame_t *frame;
874     int i = 0;
875     assert( list[0] );
876     while( list[i+1] ) i++;
877     frame = list[i];
878     list[i] = NULL;
879     return frame;
880 }
881
882 void x264_frame_unshift( x264_frame_t **list, x264_frame_t *frame )
883 {
884     int i = 0;
885     while( list[i] ) i++;
886     while( i-- )
887         list[i+1] = list[i];
888     list[0] = frame;
889 }
890
891 x264_frame_t *x264_frame_shift( x264_frame_t **list )
892 {
893     x264_frame_t *frame = list[0];
894     int i;
895     for( i = 0; list[i]; i++ )
896         list[i] = list[i+1];
897     assert(frame);
898     return frame;
899 }
900
901 void x264_frame_push_unused( x264_t *h, x264_frame_t *frame )
902 {
903     assert( frame->i_reference_count > 0 );
904     frame->i_reference_count--;
905     if( frame->i_reference_count == 0 )
906         x264_frame_push( h->frames.unused, frame );
907     assert( h->frames.unused[ sizeof(h->frames.unused) / sizeof(*h->frames.unused) - 1 ] == NULL );
908 }
909
910 x264_frame_t *x264_frame_pop_unused( x264_t *h )
911 {
912     x264_frame_t *frame;
913     if( h->frames.unused[0] )
914         frame = x264_frame_pop( h->frames.unused );
915     else
916         frame = x264_frame_new( h );
917     assert( frame->i_reference_count == 0 );
918     frame->i_reference_count = 1;
919     return frame;
920 }
921
922 void x264_frame_sort( x264_frame_t **list, int b_dts )
923 {
924     int i, b_ok;
925     do {
926         b_ok = 1;
927         for( i = 0; list[i+1]; i++ )
928         {
929             int dtype = list[i]->i_type - list[i+1]->i_type;
930             int dtime = list[i]->i_frame - list[i+1]->i_frame;
931             int swap = b_dts ? dtype > 0 || ( dtype == 0 && dtime > 0 )
932                              : dtime > 0;
933             if( swap )
934             {
935                 XCHG( x264_frame_t*, list[i], list[i+1] );
936                 b_ok = 0;
937             }
938         }
939     } while( !b_ok );
940 }