Faster deblock reference frame checks
[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  *          Jason Garrett-Glaser <darkshikari@gmail.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 #include "common.h"
26
27 #define ALIGN(x,a) (((x)+((a)-1))&~((a)-1))
28
29 x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
30 {
31     x264_frame_t *frame;
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 chroma_plane_size;
38     int align = h->param.cpu&X264_CPU_CACHELINE_64 ? 64 : h->param.cpu&X264_CPU_CACHELINE_32 ? 32 : 16;
39
40     CHECKED_MALLOCZERO( frame, sizeof(x264_frame_t) );
41
42     /* allocate frame data (+64 for extra data for me) */
43     i_width  = ALIGN( h->param.i_width, 16 );
44     i_stride = ALIGN( i_width + 2*PADH, align );
45     i_lines  = ALIGN( h->param.i_height, 16<<h->param.b_interlaced );
46
47     frame->i_plane = 3;
48     for( int i = 0; i < 3; i++ )
49     {
50         frame->i_stride[i] = ALIGN( i_stride >> !!i, align );
51         frame->i_width[i] = i_width >> !!i;
52         frame->i_lines[i] = i_lines >> !!i;
53     }
54
55     luma_plane_size = (frame->i_stride[0] * (frame->i_lines[0] + 2*i_padv));
56     chroma_plane_size = (frame->i_stride[1] * (frame->i_lines[1] + 2*i_padv));
57     for( int i = 1; i < 3; i++ )
58     {
59         CHECKED_MALLOC( frame->buffer[i], chroma_plane_size );
60         frame->plane[i] = frame->buffer[i] + (frame->i_stride[i] * i_padv + PADH)/2;
61     }
62
63     for( int i = 0; i < h->param.i_bframe + 2; i++ )
64         for( int j = 0; j < h->param.i_bframe + 2; j++ )
65             CHECKED_MALLOC( frame->i_row_satds[i][j], i_lines/16 * sizeof(int) );
66
67     frame->i_poc = -1;
68     frame->i_type = X264_TYPE_AUTO;
69     frame->i_qpplus1 = 0;
70     frame->i_pts = -1;
71     frame->i_frame = -1;
72     frame->i_frame_num = -1;
73     frame->i_lines_completed = -1;
74     frame->b_fdec = b_fdec;
75     frame->i_pic_struct = PIC_STRUCT_AUTO;
76     frame->i_field_cnt = -1;
77     frame->i_duration =
78     frame->i_cpb_duration =
79     frame->i_dpb_output_delay =
80     frame->i_cpb_delay = 0;
81     frame->i_coded_fields_lookahead =
82     frame->i_cpb_delay_lookahead = -1;
83
84     frame->orig = frame;
85
86     /* all 4 luma planes allocated together, since the cacheline split code
87      * requires them to be in-phase wrt cacheline alignment. */
88     if( h->param.analyse.i_subpel_refine && b_fdec )
89     {
90         CHECKED_MALLOC( frame->buffer[0], 4*luma_plane_size );
91         for( int i = 0; i < 4; i++ )
92             frame->filtered[i] = frame->buffer[0] + i*luma_plane_size + frame->i_stride[0] * i_padv + PADH;
93         frame->plane[0] = frame->filtered[0];
94     }
95     else
96     {
97         CHECKED_MALLOC( frame->buffer[0], luma_plane_size );
98         frame->filtered[0] = frame->plane[0] = frame->buffer[0] + frame->i_stride[0] * i_padv + PADH;
99     }
100
101     frame->b_duplicate = 0;
102
103     if( b_fdec ) /* fdec frame */
104     {
105         CHECKED_MALLOC( frame->mb_type, i_mb_count * sizeof(int8_t));
106         CHECKED_MALLOC( frame->mb_partition, i_mb_count * sizeof(uint8_t));
107         CHECKED_MALLOC( frame->mv[0], 2*16 * i_mb_count * sizeof(int16_t) );
108         CHECKED_MALLOC( frame->ref[0], 4 * i_mb_count * sizeof(int8_t) );
109         if( h->param.i_bframe )
110         {
111             CHECKED_MALLOC( frame->mv[1], 2*16 * i_mb_count * sizeof(int16_t) );
112             CHECKED_MALLOC( frame->ref[1], 4 * i_mb_count * sizeof(int8_t) );
113         }
114         else
115         {
116             frame->mv[1]  = NULL;
117             frame->ref[1] = NULL;
118         }
119         CHECKED_MALLOC( frame->i_row_bits, i_lines/16 * sizeof(int) );
120         CHECKED_MALLOC( frame->i_row_qp, i_lines/16 * sizeof(int) );
121         if( h->param.analyse.i_me_method >= X264_ME_ESA )
122         {
123             CHECKED_MALLOC( frame->buffer[3],
124                             frame->i_stride[0] * (frame->i_lines[0] + 2*i_padv) * sizeof(uint16_t) << h->frames.b_have_sub8x8_esa );
125             frame->integral = (uint16_t*)frame->buffer[3] + frame->i_stride[0] * i_padv + PADH;
126         }
127     }
128     else /* fenc frame */
129     {
130         if( h->frames.b_have_lowres )
131         {
132             frame->i_width_lowres = frame->i_width[0]/2;
133             frame->i_stride_lowres = ALIGN( frame->i_width_lowres + 2*PADH, align );
134             frame->i_lines_lowres = frame->i_lines[0]/2;
135
136             luma_plane_size = frame->i_stride_lowres * (frame->i_lines[0]/2 + 2*PADV);
137
138             CHECKED_MALLOC( frame->buffer_lowres[0], 4 * luma_plane_size );
139             for( int i = 0; i < 4; i++ )
140                 frame->lowres[i] = frame->buffer_lowres[0] + (frame->i_stride_lowres * PADV + PADH) + i * luma_plane_size;
141
142             for( int j = 0; j <= !!h->param.i_bframe; j++ )
143                 for( int i = 0; i <= h->param.i_bframe; i++ )
144                 {
145                     CHECKED_MALLOCZERO( frame->lowres_mvs[j][i], 2*h->mb.i_mb_count*sizeof(int16_t) );
146                     CHECKED_MALLOC( frame->lowres_mv_costs[j][i], h->mb.i_mb_count*sizeof(int) );
147                 }
148             CHECKED_MALLOC( frame->i_propagate_cost, (i_mb_count+3) * sizeof(uint16_t) );
149             for( int j = 0; j <= h->param.i_bframe+1; j++ )
150                 for( int i = 0; i <= h->param.i_bframe+1; i++ )
151                 {
152                     CHECKED_MALLOC( frame->lowres_costs[j][i], (i_mb_count+3) * sizeof(uint16_t) );
153                     CHECKED_MALLOC( frame->lowres_inter_types[j][i], (i_mb_count+3)/4 * sizeof(uint8_t) );
154                 }
155             frame->i_intra_cost = frame->lowres_costs[0][0];
156             memset( frame->i_intra_cost, -1, (i_mb_count+3) * sizeof(uint16_t) );
157         }
158         if( h->param.rc.i_aq_mode )
159         {
160             CHECKED_MALLOC( frame->f_qp_offset, h->mb.i_mb_count * sizeof(float) );
161             CHECKED_MALLOC( frame->f_qp_offset_aq, h->mb.i_mb_count * sizeof(float) );
162             if( h->frames.b_have_lowres )
163                 /* shouldn't really be initialized, just silences a valgrind false-positive in x264_mbtree_propagate_cost_sse2 */
164                 CHECKED_MALLOCZERO( frame->i_inv_qscale_factor, (h->mb.i_mb_count+3) * sizeof(uint16_t) );
165         }
166     }
167
168     if( x264_pthread_mutex_init( &frame->mutex, NULL ) )
169         goto fail;
170     if( x264_pthread_cond_init( &frame->cv, NULL ) )
171         goto fail;
172
173     return frame;
174
175 fail:
176     x264_free( frame );
177     return NULL;
178 }
179
180 void x264_frame_delete( x264_frame_t *frame )
181 {
182     /* Duplicate frames are blank copies of real frames (including pointers),
183      * so freeing those pointers would cause a double free later. */
184     if( !frame->b_duplicate )
185     {
186         for( int i = 0; i < 4; i++ )
187             x264_free( frame->buffer[i] );
188         for( int i = 0; i < 4; i++ )
189             x264_free( frame->buffer_lowres[i] );
190         for( int i = 0; i < X264_BFRAME_MAX+2; i++ )
191             for( int j = 0; j < X264_BFRAME_MAX+2; j++ )
192                 x264_free( frame->i_row_satds[i][j] );
193         for( int j = 0; j < 2; j++ )
194             for( int i = 0; i <= X264_BFRAME_MAX; i++ )
195             {
196                 x264_free( frame->lowres_mvs[j][i] );
197                 x264_free( frame->lowres_mv_costs[j][i] );
198             }
199         x264_free( frame->i_propagate_cost );
200         for( int j = 0; j <= X264_BFRAME_MAX+1; j++ )
201             for( int i = 0; i <= X264_BFRAME_MAX+1; i++ )
202             {
203                 x264_free( frame->lowres_costs[j][i] );
204                 x264_free( frame->lowres_inter_types[j][i] );
205             }
206         x264_free( frame->f_qp_offset );
207         x264_free( frame->f_qp_offset_aq );
208         x264_free( frame->i_inv_qscale_factor );
209         x264_free( frame->i_row_bits );
210         x264_free( frame->i_row_qp );
211         x264_free( frame->mb_type );
212         x264_free( frame->mb_partition );
213         x264_free( frame->mv[0] );
214         x264_free( frame->mv[1] );
215         x264_free( frame->ref[0] );
216         x264_free( frame->ref[1] );
217         x264_pthread_mutex_destroy( &frame->mutex );
218         x264_pthread_cond_destroy( &frame->cv );
219     }
220     x264_free( frame );
221 }
222
223 int x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
224 {
225     int i_csp = src->img.i_csp & X264_CSP_MASK;
226     if( i_csp != X264_CSP_I420 && i_csp != X264_CSP_YV12 )
227     {
228         x264_log( h, X264_LOG_ERROR, "Arg invalid CSP\n" );
229         return -1;
230     }
231
232     dst->i_type     = src->i_type;
233     dst->i_qpplus1  = src->i_qpplus1;
234     dst->i_pts      = dst->i_reordered_pts = src->i_pts;
235     dst->param      = src->param;
236     dst->i_pic_struct = src->i_pic_struct;
237
238     for( int i = 0; i < 3; i++ )
239     {
240         int s = (i_csp == X264_CSP_YV12 && i) ? i^3 : i;
241         uint8_t *plane = src->img.plane[s];
242         int stride = src->img.i_stride[s];
243         int width = h->param.i_width >> !!i;
244         int height = h->param.i_height >> !!i;
245         if( src->img.i_csp & X264_CSP_VFLIP )
246         {
247             plane += (height-1)*stride;
248             stride = -stride;
249         }
250         h->mc.plane_copy( dst->plane[i], dst->i_stride[i], plane, stride, width, height );
251     }
252     return 0;
253 }
254
255
256
257 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 )
258 {
259 #define PPIXEL(x, y) ( pix + (x) + (y)*i_stride )
260     for( int y = 0; y < i_height; y++ )
261     {
262         /* left band */
263         memset( PPIXEL(-i_padh, y), PPIXEL(0, y)[0], i_padh );
264         /* right band */
265         memset( PPIXEL(i_width, y), PPIXEL(i_width-1, y)[0], i_padh );
266     }
267     /* upper band */
268     if( b_pad_top )
269         for( int y = 0; y < i_padv; y++ )
270             memcpy( PPIXEL(-i_padh, -y-1), PPIXEL(-i_padh, 0), i_width+2*i_padh );
271     /* lower band */
272     if( b_pad_bottom )
273         for( int y = 0; y < i_padv; y++ )
274             memcpy( PPIXEL(-i_padh, i_height+y), PPIXEL(-i_padh, i_height-1), i_width+2*i_padh );
275 #undef PPIXEL
276 }
277
278 void x264_frame_expand_border( x264_t *h, x264_frame_t *frame, int mb_y, int b_end )
279 {
280     int b_start = !mb_y;
281     if( mb_y & h->sh.b_mbaff )
282         return;
283     for( int i = 0; i < frame->i_plane; i++ )
284     {
285         int stride = frame->i_stride[i];
286         int width = 16*h->sps->i_mb_width >> !!i;
287         int height = (b_end ? 16*(h->sps->i_mb_height - mb_y) >> h->sh.b_mbaff : 16) >> !!i;
288         int padh = PADH >> !!i;
289         int padv = PADV >> !!i;
290         // buffer: 2 chroma, 3 luma (rounded to 4) because deblocking goes beyond the top of the mb
291         uint8_t *pix = frame->plane[i] + X264_MAX(0, (16*mb_y-4)*stride >> !!i);
292         if( b_end && !b_start )
293             height += 4 >> (!!i + h->sh.b_mbaff);
294         if( h->sh.b_mbaff )
295         {
296             plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end );
297             plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end );
298         }
299         else
300         {
301             plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end );
302         }
303     }
304 }
305
306 void x264_frame_expand_border_filtered( x264_t *h, x264_frame_t *frame, int mb_y, int b_end )
307 {
308     /* during filtering, 8 extra pixels were filtered on each edge,
309      * but up to 3 of the horizontal ones may be wrong.
310        we want to expand border from the last filtered pixel */
311     int b_start = !mb_y;
312     int stride = frame->i_stride[0];
313     int width = 16*h->sps->i_mb_width + 8;
314     int height = b_end ? (16*(h->sps->i_mb_height - mb_y) >> h->sh.b_mbaff) + 16 : 16;
315     int padh = PADH - 4;
316     int padv = PADV - 8;
317     for( int i = 1; i < 4; i++ )
318     {
319         // buffer: 8 luma, to match the hpel filter
320         uint8_t *pix = frame->filtered[i] + (16*mb_y - (8 << h->sh.b_mbaff)) * stride - 4;
321         if( h->sh.b_mbaff )
322         {
323             plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end );
324             plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end );
325         }
326         else
327             plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end );
328     }
329 }
330
331 void x264_frame_expand_border_lowres( x264_frame_t *frame )
332 {
333     for( int i = 0; i < 4; i++ )
334         plane_expand_border( frame->lowres[i], frame->i_stride_lowres, frame->i_width_lowres, frame->i_lines_lowres, PADH, PADV, 1, 1 );
335 }
336
337 void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame )
338 {
339     for( int i = 0; i < frame->i_plane; i++ )
340     {
341         int i_subsample = i ? 1 : 0;
342         int i_width = h->param.i_width >> i_subsample;
343         int i_height = h->param.i_height >> i_subsample;
344         int i_padx = (h->sps->i_mb_width * 16 - h->param.i_width) >> i_subsample;
345         int i_pady = (h->sps->i_mb_height * 16 - h->param.i_height) >> i_subsample;
346
347         if( i_padx )
348         {
349             for( int y = 0; y < i_height; y++ )
350                 memset( &frame->plane[i][y*frame->i_stride[i] + i_width],
351                          frame->plane[i][y*frame->i_stride[i] + i_width - 1],
352                          i_padx );
353         }
354         if( i_pady )
355         {
356             for( int y = i_height; y < i_height + i_pady; y++ )
357                 memcpy( &frame->plane[i][y*frame->i_stride[i]],
358                         &frame->plane[i][(i_height-(~y&h->param.b_interlaced)-1)*frame->i_stride[i]],
359                         i_width + i_padx );
360         }
361     }
362 }
363
364
365 /* cavlc + 8x8 transform stores nnz per 16 coeffs for the purpose of
366  * entropy coding, but per 64 coeffs for the purpose of deblocking */
367 static void munge_cavlc_nnz_row( x264_t *h, int mb_y, uint8_t (*buf)[16] )
368 {
369     uint32_t (*src)[6] = (uint32_t(*)[6])h->mb.non_zero_count + mb_y * h->sps->i_mb_width;
370     int8_t *transform = h->mb.mb_transform_size + mb_y * h->sps->i_mb_width;
371     for( int x = 0; x<h->sps->i_mb_width; x++ )
372     {
373         memcpy( buf+x, src+x, 16 );
374         if( transform[x] )
375         {
376             int nnz = src[x][0] | src[x][1];
377             src[x][0] = src[x][1] = ((uint16_t)nnz ? 0x0101 : 0) + (nnz>>16 ? 0x01010000 : 0);
378             nnz = src[x][2] | src[x][3];
379             src[x][2] = src[x][3] = ((uint16_t)nnz ? 0x0101 : 0) + (nnz>>16 ? 0x01010000 : 0);
380         }
381     }
382 }
383
384 static void restore_cavlc_nnz_row( x264_t *h, int mb_y, uint8_t (*buf)[16] )
385 {
386     uint8_t (*dst)[24] = h->mb.non_zero_count + mb_y * h->sps->i_mb_width;
387     for( int x = 0; x < h->sps->i_mb_width; x++ )
388         memcpy( dst+x, buf+x, 16 );
389 }
390
391 static void munge_cavlc_nnz( x264_t *h, int mb_y, uint8_t (*buf)[16], void (*func)(x264_t*, int, uint8_t (*)[16]) )
392 {
393     func( h, mb_y, buf );
394     if( mb_y > 0 )
395         func( h, mb_y-1, buf + h->sps->i_mb_width );
396     if( h->sh.b_mbaff )
397     {
398         func( h, mb_y+1, buf + h->sps->i_mb_width * 2 );
399         if( mb_y > 0 )
400             func( h, mb_y-2, buf + h->sps->i_mb_width * 3 );
401     }
402 }
403
404
405 /* Deblocking filter */
406 static const uint8_t i_alpha_table[52+12*2] =
407 {
408      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
409      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
410      0,  0,  0,  0,  0,  0,  4,  4,  5,  6,
411      7,  8,  9, 10, 12, 13, 15, 17, 20, 22,
412     25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
413     80, 90,101,113,127,144,162,182,203,226,
414    255,255,
415    255,255,255,255,255,255,255,255,255,255,255,255,
416 };
417 static const uint8_t i_beta_table[52+12*2] =
418 {
419      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
420      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
421      0,  0,  0,  0,  0,  0,  2,  2,  2,  3,
422      3,  3,  3,  4,  4,  4,  6,  6,  7,  7,
423      8,  8,  9,  9, 10, 10, 11, 11, 12, 12,
424     13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
425     18, 18,
426     18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
427 };
428 static const int8_t i_tc0_table[52+12*2][4] =
429 {
430     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
431     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
432     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
433     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
434     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 1 },
435     {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 1, 1 }, {-1, 0, 1, 1 }, {-1, 1, 1, 1 },
436     {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 },
437     {-1, 1, 1, 2 }, {-1, 1, 2, 3 }, {-1, 1, 2, 3 }, {-1, 2, 2, 3 }, {-1, 2, 2, 4 }, {-1, 2, 3, 4 },
438     {-1, 2, 3, 4 }, {-1, 3, 3, 5 }, {-1, 3, 4, 6 }, {-1, 3, 4, 6 }, {-1, 4, 5, 7 }, {-1, 4, 5, 8 },
439     {-1, 4, 6, 9 }, {-1, 5, 7,10 }, {-1, 6, 8,11 }, {-1, 6, 8,13 }, {-1, 7,10,14 }, {-1, 8,11,16 },
440     {-1, 9,12,18 }, {-1,10,13,20 }, {-1,11,15,23 }, {-1,13,17,25 },
441     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
442     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
443 };
444 #define alpha_table(x) i_alpha_table[(x)+12]
445 #define beta_table(x)  i_beta_table[(x)+12]
446 #define tc0_table(x)   i_tc0_table[(x)+12]
447
448 /* From ffmpeg */
449 static inline void deblock_luma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
450 {
451     for( int i = 0; i < 4; i++ )
452     {
453         if( tc0[i] < 0 )
454         {
455             pix += 4*ystride;
456             continue;
457         }
458         for( int d = 0; d < 4; d++ )
459         {
460             int p2 = pix[-3*xstride];
461             int p1 = pix[-2*xstride];
462             int p0 = pix[-1*xstride];
463             int q0 = pix[ 0*xstride];
464             int q1 = pix[ 1*xstride];
465             int q2 = pix[ 2*xstride];
466
467             if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta )
468             {
469                 int tc = tc0[i];
470                 int delta;
471                 if( abs( p2 - p0 ) < beta )
472                 {
473                     if( tc0[i] )
474                         pix[-2*xstride] = p1 + x264_clip3( (( p2 + ((p0 + q0 + 1) >> 1)) >> 1) - p1, -tc0[i], tc0[i] );
475                     tc++;
476                 }
477                 if( abs( q2 - q0 ) < beta )
478                 {
479                     if( tc0[i] )
480                         pix[ 1*xstride] = q1 + x264_clip3( (( q2 + ((p0 + q0 + 1) >> 1)) >> 1) - q1, -tc0[i], tc0[i] );
481                     tc++;
482                 }
483
484                 delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
485                 pix[-1*xstride] = x264_clip_uint8( p0 + delta );    /* p0' */
486                 pix[ 0*xstride] = x264_clip_uint8( q0 - delta );    /* q0' */
487             }
488             pix += ystride;
489         }
490     }
491 }
492 static void deblock_v_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
493 {
494     deblock_luma_c( pix, stride, 1, alpha, beta, tc0 );
495 }
496 static void deblock_h_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
497 {
498     deblock_luma_c( pix, 1, stride, alpha, beta, tc0 );
499 }
500
501 static inline void deblock_chroma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
502 {
503     for( int i = 0; i < 4; i++ )
504     {
505         int tc = tc0[i];
506         if( tc <= 0 )
507         {
508             pix += 2*ystride;
509             continue;
510         }
511         for( int d = 0; d < 2; d++ )
512         {
513             int p1 = pix[-2*xstride];
514             int p0 = pix[-1*xstride];
515             int q0 = pix[ 0*xstride];
516             int q1 = pix[ 1*xstride];
517
518             if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta )
519             {
520                 int delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
521                 pix[-1*xstride] = x264_clip_uint8( p0 + delta );    /* p0' */
522                 pix[ 0*xstride] = x264_clip_uint8( q0 - delta );    /* q0' */
523             }
524             pix += ystride;
525         }
526     }
527 }
528 static void deblock_v_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
529 {
530     deblock_chroma_c( pix, stride, 1, alpha, beta, tc0 );
531 }
532 static void deblock_h_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
533 {
534     deblock_chroma_c( pix, 1, stride, alpha, beta, tc0 );
535 }
536
537 static inline void deblock_luma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
538 {
539     for( int d = 0; d < 16; d++ )
540     {
541         int p2 = pix[-3*xstride];
542         int p1 = pix[-2*xstride];
543         int p0 = pix[-1*xstride];
544         int q0 = pix[ 0*xstride];
545         int q1 = pix[ 1*xstride];
546         int q2 = pix[ 2*xstride];
547
548         if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta )
549         {
550             if(abs( p0 - q0 ) < ((alpha >> 2) + 2) )
551             {
552                 if( abs( p2 - p0 ) < beta ) /* p0', p1', p2' */
553                 {
554                     const int p3 = pix[-4*xstride];
555                     pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
556                     pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
557                     pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
558                 }
559                 else /* p0' */
560                     pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
561                 if( abs( q2 - q0 ) < beta ) /* q0', q1', q2' */
562                 {
563                     const int q3 = pix[3*xstride];
564                     pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
565                     pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
566                     pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
567                 }
568                 else /* q0' */
569                     pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
570             }
571             else /* p0', q0' */
572             {
573                 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
574                 pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
575             }
576         }
577         pix += ystride;
578     }
579 }
580 static void deblock_v_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
581 {
582     deblock_luma_intra_c( pix, stride, 1, alpha, beta );
583 }
584 static void deblock_h_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
585 {
586     deblock_luma_intra_c( pix, 1, stride, alpha, beta );
587 }
588
589 static inline void deblock_chroma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
590 {
591     for( int d = 0; d < 8; d++ )
592     {
593         int p1 = pix[-2*xstride];
594         int p0 = pix[-1*xstride];
595         int q0 = pix[ 0*xstride];
596         int q1 = pix[ 1*xstride];
597
598         if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta )
599         {
600             pix[-1*xstride] = (2*p1 + p0 + q1 + 2) >> 2;   /* p0' */
601             pix[ 0*xstride] = (2*q1 + q0 + p1 + 2) >> 2;   /* q0' */
602         }
603         pix += ystride;
604     }
605 }
606 static void deblock_v_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
607 {
608     deblock_chroma_intra_c( pix, stride, 1, alpha, beta );
609 }
610 static void deblock_h_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
611 {
612     deblock_chroma_intra_c( pix, 1, stride, alpha, beta );
613 }
614
615 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 )
616 {
617     int index_a = i_qp + h->sh.i_alpha_c0_offset;
618     int alpha = alpha_table(index_a);
619     int beta  = beta_table(i_qp + h->sh.i_beta_offset);
620     int8_t tc[4];
621
622     if( !alpha || !beta )
623         return;
624
625     tc[0] = tc0_table(index_a)[bS[0]] + b_chroma;
626     tc[1] = tc0_table(index_a)[bS[1]] + b_chroma;
627     tc[2] = tc0_table(index_a)[bS[2]] + b_chroma;
628     tc[3] = tc0_table(index_a)[bS[3]] + b_chroma;
629
630     pf_inter( pix1, i_stride, alpha, beta, tc );
631     if( b_chroma )
632         pf_inter( pix2, i_stride, alpha, beta, tc );
633 }
634
635 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 )
636 {
637     int alpha = alpha_table(i_qp + h->sh.i_alpha_c0_offset);
638     int beta  = beta_table(i_qp + h->sh.i_beta_offset);
639
640     if( !alpha || !beta )
641         return;
642
643     pf_intra( pix1, i_stride, alpha, beta );
644     if( b_chroma )
645         pf_intra( pix2, i_stride, alpha, beta );
646 }
647
648 void x264_frame_deblock_row( x264_t *h, int mb_y )
649 {
650     int s8x8 = 2 * h->mb.i_mb_stride;
651     int s4x4 = 4 * h->mb.i_mb_stride;
652     int b_interlaced = h->sh.b_mbaff;
653     int mvy_limit = 4 >> b_interlaced;
654     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);
655     int no_sub8x8 = !(h->param.analyse.inter & X264_ANALYSE_PSUB8x8);
656     int mb_x;
657     int stridey   = h->fdec->i_stride[0];
658     int stride2y  = stridey << b_interlaced;
659     int strideuv  = h->fdec->i_stride[1];
660     int stride2uv = strideuv << b_interlaced;
661     int deblock_on_slice_edges = h->sh.i_disable_deblocking_filter_idc != 2;
662     int ref_table[32+2];
663     #define ref_table(x) ref_table[x+2]
664     uint8_t (*nnz_backup)[16] = h->scratch_buffer;
665
666     ref_table(-2) = -2;
667     ref_table(-1) = -1;
668     for( int i = 0; i < (h->i_ref0 << h->sh.b_mbaff); i++ )
669     {
670         if( !h->mb.b_interlaced )
671             ref_table(i) = h->fref0[i]->i_poc;
672         else
673             ref_table(i) = h->fref0[i>>1]->i_poc + (i&1);
674     }
675
676     if( !h->pps->b_cabac && h->pps->b_transform_8x8_mode )
677         munge_cavlc_nnz( h, mb_y, nnz_backup, munge_cavlc_nnz_row );
678
679     for( mb_x = 0; mb_x < h->sps->i_mb_width; mb_x += (~b_interlaced | mb_y)&1, mb_y ^= b_interlaced )
680     {
681         int mb_xy  = mb_y * h->mb.i_mb_stride + mb_x;
682         int mb_8x8 = 2 * s8x8 * mb_y + 2 * mb_x;
683         int mb_4x4 = 4 * s4x4 * mb_y + 4 * mb_x;
684         int b_8x8_transform = h->mb.mb_transform_size[mb_xy];
685         int i_qp = h->mb.qp[mb_xy];
686         int i_edge_end = (h->mb.type[mb_xy] == P_SKIP) ? 1 : 4;
687         uint8_t *pixy = h->fdec->plane[0] + 16*mb_y*stridey  + 16*mb_x;
688         uint8_t *pixu = h->fdec->plane[1] +  8*mb_y*strideuv +  8*mb_x;
689         uint8_t *pixv = h->fdec->plane[2] +  8*mb_y*strideuv +  8*mb_x;
690         if( b_interlaced && (mb_y&1) )
691         {
692             pixy -= 15*stridey;
693             pixu -=  7*strideuv;
694             pixv -=  7*strideuv;
695         }
696
697         x264_prefetch_fenc( h, h->fdec, mb_x, mb_y );
698
699         if( i_qp <= qp_thresh )
700             i_edge_end = 1;
701
702         #define FILTER_DIR(intra, i_dir)\
703         {\
704             /* Y plane */\
705             i_qpn= h->mb.qp[mbn_xy];\
706             if( i_dir == 0 )\
707             {\
708                 /* vertical edge */\
709                 deblock_edge##intra( h, pixy + 4*i_edge, NULL,\
710                               stride2y, bS, (i_qp+i_qpn+1) >> 1, 0,\
711                               h->loopf.deblock_h_luma##intra );\
712                 if( !(i_edge & 1) )\
713                 {\
714                     /* U/V planes */\
715                     int i_qpc = (h->chroma_qp_table[i_qp] + h->chroma_qp_table[i_qpn] + 1) >> 1;\
716                     deblock_edge##intra( h, pixu + 2*i_edge, pixv + 2*i_edge,\
717                                   stride2uv, bS, i_qpc, 1,\
718                                   h->loopf.deblock_h_chroma##intra );\
719                 }\
720             }\
721             else\
722             {\
723                 /* horizontal edge */\
724                 deblock_edge##intra( h, pixy + 4*i_edge*stride2y, NULL,\
725                               stride2y, bS, (i_qp+i_qpn+1) >> 1, 0,\
726                               h->loopf.deblock_v_luma##intra );\
727                 /* U/V planes */\
728                 if( !(i_edge & 1) )\
729                 {\
730                     int i_qpc = (h->chroma_qp_table[i_qp] + h->chroma_qp_table[i_qpn] + 1) >> 1;\
731                     deblock_edge##intra( h, pixu + 2*i_edge*stride2uv, pixv + 2*i_edge*stride2uv,\
732                                   stride2uv, bS, i_qpc, 1,\
733                                   h->loopf.deblock_v_chroma##intra );\
734                 }\
735             }\
736         }
737
738         #define DEBLOCK_STRENGTH(i_dir)\
739         {\
740             /* *** Get bS for each 4px for the current edge *** */\
741             if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy]) )\
742                 M32( bS ) = 0x03030303;\
743             else\
744             {\
745                 M32( bS ) = 0x00000000;\
746                 for( int i = 0; i < 4; i++ )\
747                 {\
748                     int x  = i_dir == 0 ? i_edge : i;\
749                     int y  = i_dir == 0 ? i      : i_edge;\
750                     int xn = i_dir == 0 ? (x - 1)&0x03 : x;\
751                     int yn = i_dir == 0 ? y : (y - 1)&0x03;\
752                     if( h->mb.non_zero_count[mb_xy][x+y*4] != 0 ||\
753                         h->mb.non_zero_count[mbn_xy][xn+yn*4] != 0 )\
754                         bS[i] = 2;\
755                     else if(!(i_edge&no_sub8x8))\
756                     {\
757                         if((i&no_sub8x8) && bS[i-1] != 2)\
758                             bS[i] = bS[i-1];\
759                         else\
760                         {\
761                             int i8p= mb_8x8+(x>>1)+(y>>1)*s8x8;\
762                             int i8q= mbn_8x8+(xn>>1)+(yn>>1)*s8x8;\
763                             int i4p= mb_4x4+x+y*s4x4;\
764                             int i4q= mbn_4x4+xn+yn*s4x4;\
765                             if((!(ref_table(h->mb.ref[0][i8p]) == ref_table(h->mb.ref[0][i8q])) ||\
766                                 abs( h->mb.mv[0][i4p][0] - h->mb.mv[0][i4q][0] ) >= 4 ||\
767                                 abs( h->mb.mv[0][i4p][1] - h->mb.mv[0][i4q][1] ) >= mvy_limit ) ||\
768                                (h->sh.i_type == SLICE_TYPE_B &&\
769                                (h->mb.ref[1][i8p] != h->mb.ref[1][i8q] ||\
770                                 abs( h->mb.mv[1][i4p][0] - h->mb.mv[1][i4q][0] ) >= 4 ||\
771                                 abs( h->mb.mv[1][i4p][1] - h->mb.mv[1][i4q][1] ) >= mvy_limit )))\
772                             {\
773                                 bS[i] = 1;\
774                             }\
775                         }\
776                     }\
777                 }\
778             }\
779         }
780
781         /* i_dir == 0 -> vertical edge
782          * i_dir == 1 -> horizontal edge */
783         #define DEBLOCK_DIR(i_dir)\
784         {\
785             int i_edge = 0;\
786             int i_qpn, mbn_xy, mbn_8x8, mbn_4x4;\
787             ALIGNED_4( uint8_t bS[4] );  /* filtering strength */\
788             /* We don't have to consider the MBAFF case of a slice breaking in the middle\
789              * of a row because x264 doesn't support that case.  If we add support for that,\
790              * this will have to become significantly more complex. */\
791             if( i_dir == 0 && (mb_x == 0 || (!deblock_on_slice_edges &&\
792                 h->mb.slice_table[mb_xy] != h->mb.slice_table[mb_xy-1])) )\
793                 i_edge++;\
794             if( i_dir == 1 && (mb_y <= b_interlaced || (!deblock_on_slice_edges &&\
795                 h->mb.slice_table[mb_xy] != h->mb.slice_table[mb_xy-(h->mb.i_mb_stride<<b_interlaced)])) )\
796                 i_edge++;\
797             if( i_edge )\
798                 i_edge+= b_8x8_transform;\
799             else\
800             {\
801                 mbn_xy  = i_dir == 0 ? mb_xy  - 1 : mb_xy - h->mb.i_mb_stride;\
802                 mbn_8x8 = i_dir == 0 ? mb_8x8 - 2 : mb_8x8 - 2 * s8x8;\
803                 mbn_4x4 = i_dir == 0 ? mb_4x4 - 4 : mb_4x4 - 4 * s4x4;\
804                 if( b_interlaced && i_dir == 1 )\
805                 {\
806                     mbn_xy -= h->mb.i_mb_stride;\
807                     mbn_8x8 -= 2 * s8x8;\
808                     mbn_4x4 -= 4 * s4x4;\
809                 }\
810                 else if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy]) )\
811                 {\
812                     FILTER_DIR( _intra, i_dir );\
813                     goto end##i_dir;\
814                 }\
815                 DEBLOCK_STRENGTH(i_dir);\
816                 if( M32( bS ) )\
817                     FILTER_DIR( , i_dir);\
818                 end##i_dir:\
819                 i_edge += b_8x8_transform+1;\
820             }\
821             mbn_xy  = mb_xy;\
822             mbn_8x8 = mb_8x8;\
823             mbn_4x4 = mb_4x4;\
824             for( ; i_edge < i_edge_end; i_edge+=b_8x8_transform+1 )\
825             {\
826                 DEBLOCK_STRENGTH(i_dir);\
827                 if( M32( bS ) )\
828                     FILTER_DIR( , i_dir);\
829             }\
830         }
831
832         DEBLOCK_DIR(0);
833         DEBLOCK_DIR(1);
834     }
835
836     if( !h->pps->b_cabac && h->pps->b_transform_8x8_mode )
837         munge_cavlc_nnz( h, mb_y, nnz_backup, restore_cavlc_nnz_row );
838 }
839
840 void x264_frame_deblock( x264_t *h )
841 {
842     for( int mb_y = 0; mb_y < h->sps->i_mb_height; mb_y += 1 + h->sh.b_mbaff )
843         x264_frame_deblock_row( h, mb_y );
844 }
845
846 #ifdef HAVE_MMX
847 void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
848 void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
849 void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
850 void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
851
852 void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
853 void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
854 void x264_deblock_v_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta );
855 void x264_deblock_h_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta );
856 #ifdef ARCH_X86
857 void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
858 void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
859 void x264_deblock_h_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
860 void x264_deblock_v8_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
861
862 static void x264_deblock_v_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
863 {
864     x264_deblock_v8_luma_mmxext( pix,   stride, alpha, beta, tc0   );
865     x264_deblock_v8_luma_mmxext( pix+8, stride, alpha, beta, tc0+2 );
866 }
867 static void x264_deblock_v_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
868 {
869     x264_deblock_v8_luma_intra_mmxext( pix,   stride, alpha, beta );
870     x264_deblock_v8_luma_intra_mmxext( pix+8, stride, alpha, beta );
871 }
872 #endif
873 #endif
874
875 #ifdef ARCH_PPC
876 void x264_deblock_v_luma_altivec( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
877 void x264_deblock_h_luma_altivec( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
878 #endif // ARCH_PPC
879
880 #ifdef HAVE_ARMV6
881 void x264_deblock_v_luma_neon( uint8_t *, int, int, int, int8_t * );
882 void x264_deblock_h_luma_neon( uint8_t *, int, int, int, int8_t * );
883 void x264_deblock_v_chroma_neon( uint8_t *, int, int, int, int8_t * );
884 void x264_deblock_h_chroma_neon( uint8_t *, int, int, int, int8_t * );
885 #endif
886
887 void x264_deblock_init( int cpu, x264_deblock_function_t *pf )
888 {
889     pf->deblock_v_luma = deblock_v_luma_c;
890     pf->deblock_h_luma = deblock_h_luma_c;
891     pf->deblock_v_chroma = deblock_v_chroma_c;
892     pf->deblock_h_chroma = deblock_h_chroma_c;
893     pf->deblock_v_luma_intra = deblock_v_luma_intra_c;
894     pf->deblock_h_luma_intra = deblock_h_luma_intra_c;
895     pf->deblock_v_chroma_intra = deblock_v_chroma_intra_c;
896     pf->deblock_h_chroma_intra = deblock_h_chroma_intra_c;
897
898 #ifdef HAVE_MMX
899     if( cpu&X264_CPU_MMXEXT )
900     {
901         pf->deblock_v_chroma = x264_deblock_v_chroma_mmxext;
902         pf->deblock_h_chroma = x264_deblock_h_chroma_mmxext;
903         pf->deblock_v_chroma_intra = x264_deblock_v_chroma_intra_mmxext;
904         pf->deblock_h_chroma_intra = x264_deblock_h_chroma_intra_mmxext;
905 #ifdef ARCH_X86
906         pf->deblock_v_luma = x264_deblock_v_luma_mmxext;
907         pf->deblock_h_luma = x264_deblock_h_luma_mmxext;
908         pf->deblock_v_luma_intra = x264_deblock_v_luma_intra_mmxext;
909         pf->deblock_h_luma_intra = x264_deblock_h_luma_intra_mmxext;
910 #endif
911         if( (cpu&X264_CPU_SSE2) && !(cpu&X264_CPU_STACK_MOD4) )
912         {
913             pf->deblock_v_luma = x264_deblock_v_luma_sse2;
914             pf->deblock_h_luma = x264_deblock_h_luma_sse2;
915             pf->deblock_v_luma_intra = x264_deblock_v_luma_intra_sse2;
916             pf->deblock_h_luma_intra = x264_deblock_h_luma_intra_sse2;
917         }
918     }
919 #endif
920
921 #ifdef HAVE_ALTIVEC
922     if( cpu&X264_CPU_ALTIVEC )
923     {
924         pf->deblock_v_luma = x264_deblock_v_luma_altivec;
925         pf->deblock_h_luma = x264_deblock_h_luma_altivec;
926    }
927 #endif // HAVE_ALTIVEC
928
929 #ifdef HAVE_ARMV6
930    if( cpu&X264_CPU_NEON )
931    {
932         pf->deblock_v_luma   = x264_deblock_v_luma_neon;
933         pf->deblock_h_luma   = x264_deblock_h_luma_neon;
934         pf->deblock_v_chroma = x264_deblock_v_chroma_neon;
935         pf->deblock_h_chroma = x264_deblock_h_chroma_neon;
936    }
937 #endif
938 }
939
940
941 /* threading */
942 void x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed )
943 {
944     x264_pthread_mutex_lock( &frame->mutex );
945     frame->i_lines_completed = i_lines_completed;
946     x264_pthread_cond_broadcast( &frame->cv );
947     x264_pthread_mutex_unlock( &frame->mutex );
948 }
949
950 void x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed )
951 {
952     x264_pthread_mutex_lock( &frame->mutex );
953     while( frame->i_lines_completed < i_lines_completed )
954         x264_pthread_cond_wait( &frame->cv, &frame->mutex );
955     x264_pthread_mutex_unlock( &frame->mutex );
956 }
957
958 /* list operators */
959
960 void x264_frame_push( x264_frame_t **list, x264_frame_t *frame )
961 {
962     int i = 0;
963     while( list[i] ) i++;
964     list[i] = frame;
965 }
966
967 x264_frame_t *x264_frame_pop( x264_frame_t **list )
968 {
969     x264_frame_t *frame;
970     int i = 0;
971     assert( list[0] );
972     while( list[i+1] ) i++;
973     frame = list[i];
974     list[i] = NULL;
975     return frame;
976 }
977
978 void x264_frame_unshift( x264_frame_t **list, x264_frame_t *frame )
979 {
980     int i = 0;
981     while( list[i] ) i++;
982     while( i-- )
983         list[i+1] = list[i];
984     list[0] = frame;
985 }
986
987 x264_frame_t *x264_frame_shift( x264_frame_t **list )
988 {
989     x264_frame_t *frame = list[0];
990     int i;
991     for( i = 0; list[i]; i++ )
992         list[i] = list[i+1];
993     assert(frame);
994     return frame;
995 }
996
997 void x264_frame_push_unused( x264_t *h, x264_frame_t *frame )
998 {
999     assert( frame->i_reference_count > 0 );
1000     frame->i_reference_count--;
1001     if( frame->i_reference_count == 0 )
1002         x264_frame_push( h->frames.unused[frame->b_fdec], frame );
1003 }
1004
1005 x264_frame_t *x264_frame_pop_unused( x264_t *h, int b_fdec )
1006 {
1007     x264_frame_t *frame;
1008     if( h->frames.unused[b_fdec][0] )
1009         frame = x264_frame_pop( h->frames.unused[b_fdec] );
1010     else
1011         frame = x264_frame_new( h, b_fdec );
1012     if( !frame )
1013         return NULL;
1014     frame->b_last_minigop_bframe = 0;
1015     frame->i_reference_count = 1;
1016     frame->b_intra_calculated = 0;
1017     frame->b_scenecut = 1;
1018     frame->b_keyframe = 0;
1019
1020     memset( frame->weight, 0, sizeof(frame->weight) );
1021     memset( frame->f_weighted_cost_delta, 0, sizeof(frame->f_weighted_cost_delta) );
1022
1023     return frame;
1024 }
1025
1026 void x264_frame_push_blank_unused( x264_t *h, x264_frame_t *frame )
1027 {
1028     assert( frame->i_reference_count > 0 );
1029     frame->i_reference_count--;
1030     if( frame->i_reference_count == 0 )
1031         x264_frame_push( h->frames.blank_unused, frame );
1032 }
1033
1034 x264_frame_t *x264_frame_pop_blank_unused( x264_t *h )
1035 {
1036     x264_frame_t *frame;
1037     if( h->frames.blank_unused[0] )
1038         frame = x264_frame_pop( h->frames.blank_unused );
1039     else
1040         frame = x264_malloc( sizeof(x264_frame_t) );
1041     if( !frame )
1042         return NULL;
1043     frame->b_duplicate = 1;
1044     frame->i_reference_count = 1;
1045     return frame;
1046 }
1047
1048 void x264_frame_sort( x264_frame_t **list, int b_dts )
1049 {
1050     int b_ok;
1051     do {
1052         b_ok = 1;
1053         for( int i = 0; list[i+1]; i++ )
1054         {
1055             int dtype = list[i]->i_type - list[i+1]->i_type;
1056             int dtime = list[i]->i_frame - list[i+1]->i_frame;
1057             int swap = b_dts ? dtype > 0 || ( dtype == 0 && dtime > 0 )
1058                              : dtime > 0;
1059             if( swap )
1060             {
1061                 XCHG( x264_frame_t*, list[i], list[i+1] );
1062                 b_ok = 0;
1063             }
1064         }
1065     } while( !b_ok );
1066 }
1067
1068 void x264_weight_scale_plane( x264_t *h, uint8_t *dst, int i_dst_stride, uint8_t *src, int i_src_stride,
1069                          int i_width, int i_height, x264_weight_t *w )
1070 {
1071     /* Weight horizontal strips of height 16. This was found to be the optimal height
1072      * in terms of the cache loads. */
1073     while( i_height > 0 )
1074     {
1075         for( int x = 0; x < i_width; x += 16 )
1076             w->weightfn[16>>2]( dst+x, i_dst_stride, src+x, i_src_stride, w, X264_MIN( i_height, 16 ) );
1077         i_height -= 16;
1078         dst += 16 * i_dst_stride;
1079         src += 16 * i_src_stride;
1080     }
1081 }
1082
1083 void x264_frame_delete_list( x264_frame_t **list )
1084 {
1085     int i = 0;
1086     if( !list )
1087         return;
1088     while( list[i] )
1089         x264_frame_delete( list[i++] );
1090     x264_free( list );
1091 }
1092
1093 int x264_synch_frame_list_init( x264_synch_frame_list_t *slist, int max_size )
1094 {
1095     if( max_size < 0 )
1096         return -1;
1097     slist->i_max_size = max_size;
1098     slist->i_size = 0;
1099     CHECKED_MALLOCZERO( slist->list, (max_size+1) * sizeof(x264_frame_t*) );
1100     if( x264_pthread_mutex_init( &slist->mutex, NULL ) ||
1101         x264_pthread_cond_init( &slist->cv_fill, NULL ) ||
1102         x264_pthread_cond_init( &slist->cv_empty, NULL ) )
1103         return -1;
1104     return 0;
1105 fail:
1106     return -1;
1107 }
1108
1109 void x264_synch_frame_list_delete( x264_synch_frame_list_t *slist )
1110 {
1111     x264_pthread_mutex_destroy( &slist->mutex );
1112     x264_pthread_cond_destroy( &slist->cv_fill );
1113     x264_pthread_cond_destroy( &slist->cv_empty );
1114     x264_frame_delete_list( slist->list );
1115 }
1116
1117 void x264_synch_frame_list_push( x264_synch_frame_list_t *slist, x264_frame_t *frame )
1118 {
1119     x264_pthread_mutex_lock( &slist->mutex );
1120     while( slist->i_size == slist->i_max_size )
1121         x264_pthread_cond_wait( &slist->cv_empty, &slist->mutex );
1122     slist->list[ slist->i_size++ ] = frame;
1123     x264_pthread_mutex_unlock( &slist->mutex );
1124     x264_pthread_cond_broadcast( &slist->cv_fill );
1125 }