6% faster deblock: remove some clips, earlier termiantion on low qps.
[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         /* i_dir == 0 -> vertical edge
671          * i_dir == 1 -> horizontal edge */
672         #define deblock_dir(i_dir)\
673         {\
674             int i_edge = (i_dir ? (mb_y <= b_interlaced) : (mb_x == 0));\
675             int i_qpn, i, l, mbn_xy, mbn_8x8, mbn_4x4;\
676             DECLARE_ALIGNED_4( uint8_t bS[4] );  /* filtering strength */\
677             if( i_edge )\
678             {\
679                 i_edge+= b_8x8_transform;\
680                 mbn_xy  = mb_xy;\
681                 mbn_8x8 = mb_8x8;\
682                 mbn_4x4 = mb_4x4;\
683             }\
684             else\
685             {\
686                 mbn_xy  = i_dir == 0 ? mb_xy  - 1 : mb_xy - h->mb.i_mb_stride;\
687                 mbn_8x8 = i_dir == 0 ? mb_8x8 - 2 : mb_8x8 - 2 * s8x8;\
688                 mbn_4x4 = i_dir == 0 ? mb_4x4 - 4 : mb_4x4 - 4 * s4x4;\
689                 if( b_interlaced && i_dir == 1 )\
690                 {\
691                     mbn_xy -= h->mb.i_mb_stride;\
692                     mbn_8x8 -= 2 * s8x8;\
693                     mbn_4x4 -= 4 * s4x4;\
694                 }\
695                 else if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy]) )\
696                 {\
697                     FILTER_DIR( _intra, i_dir );\
698                     i_edge += b_8x8_transform+1;\
699                     mbn_xy  = mb_xy;\
700                     mbn_8x8 = mb_8x8;\
701                     mbn_4x4 = mb_4x4;\
702                 }\
703             }\
704             for( ; i_edge < i_edge_end; i_edge+=b_8x8_transform+1 )\
705             {\
706                 /* *** Get bS for each 4px for the current edge *** */\
707                 if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy] ) )\
708                     *(uint32_t*)bS = 0x03030303;\
709                 else\
710                 {\
711                     *(uint32_t*)bS = 0x00000000;\
712                     for( i = 0; i < 4; i++ )\
713                     {\
714                         int x  = i_dir == 0 ? i_edge : i;\
715                         int y  = i_dir == 0 ? i      : i_edge;\
716                         int xn = (x - (i_dir == 0 ? 1 : 0 ))&0x03;\
717                         int yn = (y - (i_dir == 0 ? 0 : 1 ))&0x03;\
718                         if( h->mb.non_zero_count[mb_xy][x+y*4] != 0 ||\
719                             h->mb.non_zero_count[mbn_xy][xn+yn*4] != 0 )\
720                             bS[i] = 2;\
721                         else\
722                         {\
723                             /* FIXME: A given frame may occupy more than one position in\
724                              * the reference list. So we should compare the frame numbers,\
725                              * not the indices in the ref list.\
726                              * No harm yet, as we don't generate that case.*/\
727                             int i8p= mb_8x8+(x>>1)+(y>>1)*s8x8;\
728                             int i8q= mbn_8x8+(xn>>1)+(yn>>1)*s8x8;\
729                             int i4p= mb_4x4+x+y*s4x4;\
730                             int i4q= mbn_4x4+xn+yn*s4x4;\
731                             for( l = 0; l < 1 + (h->sh.i_type == SLICE_TYPE_B); l++ )\
732                                 if( h->mb.ref[l][i8p] != h->mb.ref[l][i8q] ||\
733                                     abs( h->mb.mv[l][i4p][0] - h->mb.mv[l][i4q][0] ) >= 4 ||\
734                                     abs( h->mb.mv[l][i4p][1] - h->mb.mv[l][i4q][1] ) >= mvy_limit )\
735                                 {\
736                                     bS[i] = 1;\
737                                     break;\
738                                 }\
739                         }\
740                     }\
741                 }\
742                 if( *(uint32_t*)bS )\
743                     FILTER_DIR( , i_dir);\
744                 mbn_xy  = mb_xy;\
745                 mbn_8x8 = mb_8x8;\
746                 mbn_4x4 = mb_4x4;\
747             }\
748         }
749
750         deblock_dir(0);
751         deblock_dir(1);
752     }
753
754     if( !h->pps->b_cabac && h->pps->b_transform_8x8_mode )
755         munge_cavlc_nnz( h, mb_y, h->mb.nnz_backup, restore_cavlc_nnz_row );
756 }
757
758 void x264_frame_deblock( x264_t *h )
759 {
760     int mb_y;
761     for( mb_y = 0; mb_y < h->sps->i_mb_height; mb_y += 1 + h->sh.b_mbaff )
762         x264_frame_deblock_row( h, mb_y );
763 }
764
765 #ifdef HAVE_MMX
766 void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
767 void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
768 void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
769 void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
770
771 void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
772 void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
773 void x264_deblock_v_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta );
774 void x264_deblock_h_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta );
775 #ifdef ARCH_X86
776 void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
777 void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
778 void x264_deblock_h_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
779 void x264_deblock_v8_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
780
781 void x264_deblock_v_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
782 {
783     x264_deblock_v8_luma_mmxext( pix,   stride, alpha, beta, tc0   );
784     x264_deblock_v8_luma_mmxext( pix+8, stride, alpha, beta, tc0+2 );
785 }
786 void x264_deblock_v_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
787 {
788     x264_deblock_v8_luma_intra_mmxext( pix,   stride, alpha, beta );
789     x264_deblock_v8_luma_intra_mmxext( pix+8, stride, alpha, beta );
790 }
791 #endif
792 #endif
793
794 #ifdef ARCH_PPC
795 void x264_deblock_v_luma_altivec( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
796 void x264_deblock_h_luma_altivec( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
797 #endif // ARCH_PPC
798
799 void x264_deblock_init( int cpu, x264_deblock_function_t *pf )
800 {
801     pf->deblock_v_luma = deblock_v_luma_c;
802     pf->deblock_h_luma = deblock_h_luma_c;
803     pf->deblock_v_chroma = deblock_v_chroma_c;
804     pf->deblock_h_chroma = deblock_h_chroma_c;
805     pf->deblock_v_luma_intra = deblock_v_luma_intra_c;
806     pf->deblock_h_luma_intra = deblock_h_luma_intra_c;
807     pf->deblock_v_chroma_intra = deblock_v_chroma_intra_c;
808     pf->deblock_h_chroma_intra = deblock_h_chroma_intra_c;
809
810 #ifdef HAVE_MMX
811     if( cpu&X264_CPU_MMXEXT )
812     {
813         pf->deblock_v_chroma = x264_deblock_v_chroma_mmxext;
814         pf->deblock_h_chroma = x264_deblock_h_chroma_mmxext;
815         pf->deblock_v_chroma_intra = x264_deblock_v_chroma_intra_mmxext;
816         pf->deblock_h_chroma_intra = x264_deblock_h_chroma_intra_mmxext;
817 #ifdef ARCH_X86
818         pf->deblock_v_luma = x264_deblock_v_luma_mmxext;
819         pf->deblock_h_luma = x264_deblock_h_luma_mmxext;
820         pf->deblock_v_luma_intra = x264_deblock_v_luma_intra_mmxext;
821         pf->deblock_h_luma_intra = x264_deblock_h_luma_intra_mmxext;
822 #endif
823         if( (cpu&X264_CPU_SSE2) && !(cpu&X264_CPU_STACK_MOD4) )
824         {
825             pf->deblock_v_luma = x264_deblock_v_luma_sse2;
826             pf->deblock_h_luma = x264_deblock_h_luma_sse2;
827             pf->deblock_v_luma_intra = x264_deblock_v_luma_intra_sse2;
828             pf->deblock_h_luma_intra = x264_deblock_h_luma_intra_sse2;
829         }
830     }
831 #endif
832
833 #ifdef ARCH_PPC
834     if( cpu&X264_CPU_ALTIVEC )
835     {
836         pf->deblock_v_luma = x264_deblock_v_luma_altivec;
837         pf->deblock_h_luma = x264_deblock_h_luma_altivec;
838    }
839 #endif // ARCH_PPC
840 }
841
842
843 /* threading */
844 void x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed )
845 {
846     x264_pthread_mutex_lock( &frame->mutex );
847     frame->i_lines_completed = i_lines_completed;
848     x264_pthread_cond_broadcast( &frame->cv );
849     x264_pthread_mutex_unlock( &frame->mutex );
850 }
851
852 void x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed )
853 {
854     x264_pthread_mutex_lock( &frame->mutex );
855     while( frame->i_lines_completed < i_lines_completed )
856         x264_pthread_cond_wait( &frame->cv, &frame->mutex );
857     x264_pthread_mutex_unlock( &frame->mutex );
858 }
859
860 /* list operators */
861
862 void x264_frame_push( x264_frame_t **list, x264_frame_t *frame )
863 {
864     int i = 0;
865     while( list[i] ) i++;
866     list[i] = frame;
867 }
868
869 x264_frame_t *x264_frame_pop( x264_frame_t **list )
870 {
871     x264_frame_t *frame;
872     int i = 0;
873     assert( list[0] );
874     while( list[i+1] ) i++;
875     frame = list[i];
876     list[i] = NULL;
877     return frame;
878 }
879
880 void x264_frame_unshift( x264_frame_t **list, x264_frame_t *frame )
881 {
882     int i = 0;
883     while( list[i] ) i++;
884     while( i-- )
885         list[i+1] = list[i];
886     list[0] = frame;
887 }
888
889 x264_frame_t *x264_frame_shift( x264_frame_t **list )
890 {
891     x264_frame_t *frame = list[0];
892     int i;
893     for( i = 0; list[i]; i++ )
894         list[i] = list[i+1];
895     assert(frame);
896     return frame;
897 }
898
899 void x264_frame_push_unused( x264_t *h, x264_frame_t *frame )
900 {
901     assert( frame->i_reference_count > 0 );
902     frame->i_reference_count--;
903     if( frame->i_reference_count == 0 )
904         x264_frame_push( h->frames.unused, frame );
905     assert( h->frames.unused[ sizeof(h->frames.unused) / sizeof(*h->frames.unused) - 1 ] == NULL );
906 }
907
908 x264_frame_t *x264_frame_pop_unused( x264_t *h )
909 {
910     x264_frame_t *frame;
911     if( h->frames.unused[0] )
912         frame = x264_frame_pop( h->frames.unused );
913     else
914         frame = x264_frame_new( h );
915     assert( frame->i_reference_count == 0 );
916     frame->i_reference_count = 1;
917     return frame;
918 }
919
920 void x264_frame_sort( x264_frame_t **list, int b_dts )
921 {
922     int i, b_ok;
923     do {
924         b_ok = 1;
925         for( i = 0; list[i+1]; i++ )
926         {
927             int dtype = list[i]->i_type - list[i+1]->i_type;
928             int dtime = list[i]->i_frame - list[i+1]->i_frame;
929             int swap = b_dts ? dtype > 0 || ( dtype == 0 && dtime > 0 )
930                              : dtime > 0;
931             if( swap )
932             {
933                 XCHG( x264_frame_t*, list[i], list[i+1] );
934                 b_ok = 0;
935             }
936         }
937     } while( !b_ok );
938 }