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