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