MBAFF: Save interlace decision for all macroblocks
[x262.git] / common / frame.c
1 /*****************************************************************************
2  * frame.c: frame handling
3  *****************************************************************************
4  * Copyright (C) 2003-2011 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  * This program is also available under a commercial proprietary license.
25  * For more information, contact us at licensing@x264.com.
26  *****************************************************************************/
27
28 #include "common.h"
29
30 static int align_stride( int x, int align, int disalign )
31 {
32     x = ALIGN( x, align );
33     if( !(x&(disalign-1)) )
34         x += align;
35     return x;
36 }
37
38 static int align_plane_size( int x, int disalign )
39 {
40     if( !(x&(disalign-1)) )
41         x += 128;
42     return x;
43 }
44
45 x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
46 {
47     x264_frame_t *frame;
48
49     int i_mb_count = h->mb.i_mb_count;
50     int i_stride, i_width, i_lines;
51     int i_padv = PADV << h->param.b_interlaced;
52     int luma_plane_size, chroma_plane_size;
53     int align = h->param.cpu&X264_CPU_CACHELINE_64 ? 64 : h->param.cpu&X264_CPU_CACHELINE_32 ? 32 : 16;
54     int disalign = h->param.cpu&X264_CPU_ALTIVEC ? 1<<9 : 1<<10;
55
56     CHECKED_MALLOCZERO( frame, sizeof(x264_frame_t) );
57
58     /* allocate frame data (+64 for extra data for me) */
59     i_width  = h->mb.i_mb_width*16;
60     i_lines  = h->mb.i_mb_height*16;
61     i_stride = align_stride( i_width + 2*PADH, align, disalign );
62
63     frame->i_plane = 2;
64     for( int i = 0; i < 2; i++ )
65     {
66         frame->i_width[i] = i_width >> i;
67         frame->i_lines[i] = i_lines >> i;
68         frame->i_stride[i] = i_stride;
69     }
70
71     frame->i_width_lowres = frame->i_width[0]/2;
72     frame->i_lines_lowres = frame->i_lines[0]/2;
73     frame->i_stride_lowres = align_stride( frame->i_width_lowres + 2*PADH, align, disalign<<1 );
74
75     for( int i = 0; i < h->param.i_bframe + 2; i++ )
76         for( int j = 0; j < h->param.i_bframe + 2; j++ )
77             CHECKED_MALLOC( frame->i_row_satds[i][j], i_lines/16 * sizeof(int) );
78
79     frame->i_poc = -1;
80     frame->i_type = X264_TYPE_AUTO;
81     frame->i_qpplus1 = X264_QP_AUTO;
82     frame->i_pts = -1;
83     frame->i_frame = -1;
84     frame->i_frame_num = -1;
85     frame->i_lines_completed = -1;
86     frame->b_fdec = b_fdec;
87     frame->i_pic_struct = PIC_STRUCT_AUTO;
88     frame->i_field_cnt = -1;
89     frame->i_duration =
90     frame->i_cpb_duration =
91     frame->i_dpb_output_delay =
92     frame->i_cpb_delay = 0;
93     frame->i_coded_fields_lookahead =
94     frame->i_cpb_delay_lookahead = -1;
95
96     frame->orig = frame;
97
98     luma_plane_size = align_plane_size( frame->i_stride[0] * (frame->i_lines[0] + 2*i_padv), disalign );
99     chroma_plane_size = (frame->i_stride[1] * (frame->i_lines[1] + i_padv));
100
101     CHECKED_MALLOC( frame->buffer[1], chroma_plane_size * sizeof(pixel) );
102     frame->plane[1] = frame->buffer[1] + frame->i_stride[1] * i_padv/2 + PADH;
103
104     /* all 4 luma planes allocated together, since the cacheline split code
105      * requires them to be in-phase wrt cacheline alignment. */
106     if( h->param.analyse.i_subpel_refine && b_fdec )
107     {
108         CHECKED_MALLOC( frame->buffer[0], 4*luma_plane_size * sizeof(pixel) );
109         for( int i = 0; i < 4; i++ )
110             frame->filtered[i] = frame->buffer[0] + i*luma_plane_size + frame->i_stride[0] * i_padv + PADH;
111         frame->plane[0] = frame->filtered[0];
112     }
113     else
114     {
115         CHECKED_MALLOC( frame->buffer[0], luma_plane_size * sizeof(pixel) );
116         frame->filtered[0] = frame->plane[0] = frame->buffer[0] + frame->i_stride[0] * i_padv + PADH;
117     }
118
119     frame->b_duplicate = 0;
120
121     if( b_fdec ) /* fdec frame */
122     {
123         CHECKED_MALLOC( frame->mb_type, i_mb_count * sizeof(int8_t));
124         CHECKED_MALLOC( frame->mb_partition, i_mb_count * sizeof(uint8_t));
125         CHECKED_MALLOC( frame->mv[0], 2*16 * i_mb_count * sizeof(int16_t) );
126         CHECKED_MALLOC( frame->mv16x16, 2*(i_mb_count+1) * sizeof(int16_t) );
127         M32( frame->mv16x16[0] ) = 0;
128         frame->mv16x16++;
129         CHECKED_MALLOC( frame->ref[0], 4 * i_mb_count * sizeof(int8_t) );
130         if( h->param.i_bframe )
131         {
132             CHECKED_MALLOC( frame->mv[1], 2*16 * i_mb_count * sizeof(int16_t) );
133             CHECKED_MALLOC( frame->ref[1], 4 * i_mb_count * sizeof(int8_t) );
134         }
135         else
136         {
137             frame->mv[1]  = NULL;
138             frame->ref[1] = NULL;
139         }
140         CHECKED_MALLOC( frame->i_row_bits, i_lines/16 * sizeof(int) );
141         CHECKED_MALLOC( frame->f_row_qp, i_lines/16 * sizeof(float) );
142         if( h->param.analyse.i_me_method >= X264_ME_ESA )
143         {
144             CHECKED_MALLOC( frame->buffer[3],
145                             frame->i_stride[0] * (frame->i_lines[0] + 2*i_padv) * sizeof(uint16_t) << h->frames.b_have_sub8x8_esa );
146             frame->integral = (uint16_t*)frame->buffer[3] + frame->i_stride[0] * i_padv + PADH;
147         }
148         if( h->param.b_interlaced )
149             CHECKED_MALLOC( frame->field, i_mb_count * sizeof(uint8_t) );
150     }
151     else /* fenc frame */
152     {
153         if( h->frames.b_have_lowres )
154         {
155             luma_plane_size = align_plane_size( frame->i_stride_lowres * (frame->i_lines[0]/2 + 2*PADV), disalign );
156
157             CHECKED_MALLOC( frame->buffer_lowres[0], 4 * luma_plane_size * sizeof(pixel) );
158             for( int i = 0; i < 4; i++ )
159                 frame->lowres[i] = frame->buffer_lowres[0] + (frame->i_stride_lowres * PADV + PADH) + i * luma_plane_size;
160
161             for( int j = 0; j <= !!h->param.i_bframe; j++ )
162                 for( int i = 0; i <= h->param.i_bframe; i++ )
163                 {
164                     CHECKED_MALLOCZERO( frame->lowres_mvs[j][i], 2*h->mb.i_mb_count*sizeof(int16_t) );
165                     CHECKED_MALLOC( frame->lowres_mv_costs[j][i], h->mb.i_mb_count*sizeof(int) );
166                 }
167             CHECKED_MALLOC( frame->i_propagate_cost, (i_mb_count+3) * sizeof(uint16_t) );
168             for( int j = 0; j <= h->param.i_bframe+1; j++ )
169                 for( int i = 0; i <= h->param.i_bframe+1; i++ )
170                     CHECKED_MALLOC( frame->lowres_costs[j][i], (i_mb_count+3) * sizeof(uint16_t) );
171             frame->i_intra_cost = frame->lowres_costs[0][0];
172             memset( frame->i_intra_cost, -1, (i_mb_count+3) * sizeof(uint16_t) );
173         }
174         if( h->param.rc.i_aq_mode )
175         {
176             CHECKED_MALLOC( frame->f_qp_offset, h->mb.i_mb_count * sizeof(float) );
177             CHECKED_MALLOC( frame->f_qp_offset_aq, h->mb.i_mb_count * sizeof(float) );
178             if( h->frames.b_have_lowres )
179                 /* shouldn't really be initialized, just silences a valgrind false-positive in x264_mbtree_propagate_cost_sse2 */
180                 CHECKED_MALLOCZERO( frame->i_inv_qscale_factor, (h->mb.i_mb_count+3) * sizeof(uint16_t) );
181         }
182     }
183
184     if( x264_pthread_mutex_init( &frame->mutex, NULL ) )
185         goto fail;
186     if( x264_pthread_cond_init( &frame->cv, NULL ) )
187         goto fail;
188
189     return frame;
190
191 fail:
192     x264_free( frame );
193     return NULL;
194 }
195
196 void x264_frame_delete( x264_frame_t *frame )
197 {
198     /* Duplicate frames are blank copies of real frames (including pointers),
199      * so freeing those pointers would cause a double free later. */
200     if( !frame->b_duplicate )
201     {
202         for( int i = 0; i < 4; i++ )
203             x264_free( frame->buffer[i] );
204         for( int i = 0; i < 4; i++ )
205             x264_free( frame->buffer_lowres[i] );
206         for( int i = 0; i < X264_BFRAME_MAX+2; i++ )
207             for( int j = 0; j < X264_BFRAME_MAX+2; j++ )
208                 x264_free( frame->i_row_satds[i][j] );
209         for( int j = 0; j < 2; j++ )
210             for( int i = 0; i <= X264_BFRAME_MAX; i++ )
211             {
212                 x264_free( frame->lowres_mvs[j][i] );
213                 x264_free( frame->lowres_mv_costs[j][i] );
214             }
215         x264_free( frame->i_propagate_cost );
216         for( int j = 0; j <= X264_BFRAME_MAX+1; j++ )
217             for( int i = 0; i <= X264_BFRAME_MAX+1; i++ )
218                 x264_free( frame->lowres_costs[j][i] );
219         x264_free( frame->f_qp_offset );
220         x264_free( frame->f_qp_offset_aq );
221         x264_free( frame->i_inv_qscale_factor );
222         x264_free( frame->i_row_bits );
223         x264_free( frame->f_row_qp );
224         x264_free( frame->field );
225         x264_free( frame->mb_type );
226         x264_free( frame->mb_partition );
227         x264_free( frame->mv[0] );
228         x264_free( frame->mv[1] );
229         if( frame->mv16x16 )
230             x264_free( frame->mv16x16-1 );
231         x264_free( frame->ref[0] );
232         x264_free( frame->ref[1] );
233         x264_pthread_mutex_destroy( &frame->mutex );
234         x264_pthread_cond_destroy( &frame->cv );
235     }
236     x264_free( frame );
237 }
238
239 static int get_plane_ptr( x264_t *h, x264_picture_t *src, uint8_t **pix, int *stride, int plane, int xshift, int yshift )
240 {
241     int width = h->param.i_width >> xshift;
242     int height = h->param.i_height >> yshift;
243     *pix = src->img.plane[plane];
244     *stride = src->img.i_stride[plane];
245     if( src->img.i_csp & X264_CSP_VFLIP )
246     {
247         *pix += (height-1) * *stride;
248         *stride = -*stride;
249     }
250     if( width > abs(*stride) )
251     {
252         x264_log( h, X264_LOG_ERROR, "Input picture width (%d) is greater than stride (%d)\n", width, *stride );
253         return -1;
254     }
255     return 0;
256 }
257
258 #define get_plane_ptr(...) do{ if( get_plane_ptr(__VA_ARGS__) < 0 ) return -1; }while(0)
259
260 int x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
261 {
262     int i_csp = src->img.i_csp & X264_CSP_MASK;
263     if( i_csp <= X264_CSP_NONE || i_csp >= X264_CSP_MAX )
264     {
265         x264_log( h, X264_LOG_ERROR, "Invalid input colorspace\n" );
266         return -1;
267     }
268
269 #if HIGH_BIT_DEPTH
270     if( !(src->img.i_csp & X264_CSP_HIGH_DEPTH) )
271     {
272         x264_log( h, X264_LOG_ERROR, "This build of x264 requires high depth input. Rebuild to support 8-bit input.\n" );
273         return -1;
274     }
275 #else
276     if( src->img.i_csp & X264_CSP_HIGH_DEPTH )
277     {
278         x264_log( h, X264_LOG_ERROR, "This build of x264 requires 8-bit input. Rebuild to support high depth input.\n" );
279         return -1;
280     }
281 #endif
282
283     dst->i_type     = src->i_type;
284     dst->i_qpplus1  = src->i_qpplus1;
285     dst->i_pts      = dst->i_reordered_pts = src->i_pts;
286     dst->param      = src->param;
287     dst->i_pic_struct = src->i_pic_struct;
288     dst->extra_sei  = src->extra_sei;
289
290     uint8_t *pix[3];
291     int stride[3];
292     get_plane_ptr( h, src, &pix[0], &stride[0], 0, 0, 0 );
293     h->mc.plane_copy( dst->plane[0], dst->i_stride[0], (pixel*)pix[0],
294                       stride[0]/sizeof(pixel), h->param.i_width, h->param.i_height );
295     if( i_csp == X264_CSP_NV12 )
296     {
297         get_plane_ptr( h, src, &pix[1], &stride[1], 1, 0, 1 );
298         h->mc.plane_copy( dst->plane[1], dst->i_stride[1], (pixel*)pix[1],
299                           stride[1]/sizeof(pixel), h->param.i_width, h->param.i_height>>1 );
300     }
301     else
302     {
303         get_plane_ptr( h, src, &pix[1], &stride[1], i_csp==X264_CSP_I420 ? 1 : 2, 1, 1 );
304         get_plane_ptr( h, src, &pix[2], &stride[2], i_csp==X264_CSP_I420 ? 2 : 1, 1, 1 );
305         h->mc.plane_copy_interleave( dst->plane[1], dst->i_stride[1],
306                                      (pixel*)pix[1], stride[1]/sizeof(pixel),
307                                      (pixel*)pix[2], stride[2]/sizeof(pixel),
308                                      h->param.i_width>>1, h->param.i_height>>1 );
309     }
310     return 0;
311 }
312
313 static void ALWAYS_INLINE pixel_memset( pixel *dst, pixel *src, int len, int size )
314 {
315     uint8_t *dstp = (uint8_t*)dst;
316     if( size == 1 )
317         memset(dst, *src, len);
318     else if( size == 2 )
319     {
320         int v = M16( src );
321         for( int i = 0; i < len; i++ )
322             M16( dstp+i*2 ) = v;
323     }
324     else if( size == 4 )
325     {
326         int v = M32( src );
327         for( int i = 0; i < len; i++ )
328             M32( dstp+i*4 ) = v;
329     }
330 }
331
332 static void plane_expand_border( pixel *pix, int i_stride, int i_width, int i_height, int i_padh, int i_padv, int b_pad_top, int b_pad_bottom, int b_chroma )
333 {
334 #define PPIXEL(x, y) ( pix + (x) + (y)*i_stride )
335     for( int y = 0; y < i_height; y++ )
336     {
337         /* left band */
338         pixel_memset( PPIXEL(-i_padh, y), PPIXEL(0, y), i_padh>>b_chroma, sizeof(pixel)<<b_chroma );
339         /* right band */
340         pixel_memset( PPIXEL(i_width, y), PPIXEL(i_width-1-b_chroma, y), i_padh>>b_chroma, sizeof(pixel)<<b_chroma );
341     }
342     /* upper band */
343     if( b_pad_top )
344         for( int y = 0; y < i_padv; y++ )
345             memcpy( PPIXEL(-i_padh, -y-1), PPIXEL(-i_padh, 0), (i_width+2*i_padh) * sizeof(pixel) );
346     /* lower band */
347     if( b_pad_bottom )
348         for( int y = 0; y < i_padv; y++ )
349             memcpy( PPIXEL(-i_padh, i_height+y), PPIXEL(-i_padh, i_height-1), (i_width+2*i_padh) * sizeof(pixel) );
350 #undef PPIXEL
351 }
352
353 void x264_frame_expand_border( x264_t *h, x264_frame_t *frame, int mb_y, int b_end )
354 {
355     int b_start = !mb_y;
356     if( mb_y & h->sh.b_mbaff )
357         return;
358     for( int i = 0; i < frame->i_plane; i++ )
359     {
360         int stride = frame->i_stride[i];
361         int width = 16*h->sps->i_mb_width;
362         int height = (b_end ? 16*(h->mb.i_mb_height - mb_y) >> h->sh.b_mbaff : 16) >> !!i;
363         int padh = PADH;
364         int padv = PADV >> !!i;
365         // buffer: 2 chroma, 3 luma (rounded to 4) because deblocking goes beyond the top of the mb
366         pixel *pix = frame->plane[i] + X264_MAX(0, (16*mb_y-4)*stride >> !!i);
367         if( b_end && !b_start )
368             height += 4 >> (!!i + h->sh.b_mbaff);
369         if( h->sh.b_mbaff )
370         {
371             plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end, i );
372             plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end, i );
373         }
374         else
375         {
376             plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end, i );
377         }
378     }
379 }
380
381 void x264_frame_expand_border_filtered( x264_t *h, x264_frame_t *frame, int mb_y, int b_end )
382 {
383     /* during filtering, 8 extra pixels were filtered on each edge,
384      * but up to 3 of the horizontal ones may be wrong.
385        we want to expand border from the last filtered pixel */
386     int b_start = !mb_y;
387     int stride = frame->i_stride[0];
388     int width = 16*h->mb.i_mb_width + 8;
389     int height = b_end ? (16*(h->mb.i_mb_height - mb_y) >> h->sh.b_mbaff) + 16 : 16;
390     int padh = PADH - 4;
391     int padv = PADV - 8;
392     for( int i = 1; i < 4; i++ )
393     {
394         // buffer: 8 luma, to match the hpel filter
395         pixel *pix = frame->filtered[i] + (16*mb_y - (8 << h->sh.b_mbaff)) * stride - 4;
396         if( h->sh.b_mbaff )
397         {
398             plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end, 0 );
399             plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end, 0 );
400         }
401         else
402             plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end, 0 );
403     }
404 }
405
406 void x264_frame_expand_border_lowres( x264_frame_t *frame )
407 {
408     for( int i = 0; i < 4; i++ )
409         plane_expand_border( frame->lowres[i], frame->i_stride_lowres, frame->i_width_lowres, frame->i_lines_lowres, PADH, PADV, 1, 1, 0 );
410 }
411
412 void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame )
413 {
414     for( int i = 0; i < frame->i_plane; i++ )
415     {
416         int i_width = h->param.i_width;
417         int i_height = h->param.i_height >> !!i;
418         int i_padx = (h->mb.i_mb_width * 16 - h->param.i_width);
419         int i_pady = (h->mb.i_mb_height * 16 - h->param.i_height) >> !!i;
420
421         if( i_padx )
422         {
423             for( int y = 0; y < i_height; y++ )
424                 pixel_memset( &frame->plane[i][y*frame->i_stride[i] + i_width],
425                               &frame->plane[i][y*frame->i_stride[i] + i_width - 1-i],
426                               i_padx>>i, sizeof(pixel)<<i );
427         }
428         if( i_pady )
429         {
430             for( int y = i_height; y < i_height + i_pady; y++ )
431                 memcpy( &frame->plane[i][y*frame->i_stride[i]],
432                         &frame->plane[i][(i_height-(~y&h->param.b_interlaced)-1)*frame->i_stride[i]],
433                         (i_width + i_padx) * sizeof(pixel) );
434         }
435     }
436 }
437
438 /* threading */
439 void x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed )
440 {
441     x264_pthread_mutex_lock( &frame->mutex );
442     frame->i_lines_completed = i_lines_completed;
443     x264_pthread_cond_broadcast( &frame->cv );
444     x264_pthread_mutex_unlock( &frame->mutex );
445 }
446
447 void x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed )
448 {
449     x264_pthread_mutex_lock( &frame->mutex );
450     while( frame->i_lines_completed < i_lines_completed )
451         x264_pthread_cond_wait( &frame->cv, &frame->mutex );
452     x264_pthread_mutex_unlock( &frame->mutex );
453 }
454
455 /* list operators */
456
457 void x264_frame_push( x264_frame_t **list, x264_frame_t *frame )
458 {
459     int i = 0;
460     while( list[i] ) i++;
461     list[i] = frame;
462 }
463
464 x264_frame_t *x264_frame_pop( x264_frame_t **list )
465 {
466     x264_frame_t *frame;
467     int i = 0;
468     assert( list[0] );
469     while( list[i+1] ) i++;
470     frame = list[i];
471     list[i] = NULL;
472     return frame;
473 }
474
475 void x264_frame_unshift( x264_frame_t **list, x264_frame_t *frame )
476 {
477     int i = 0;
478     while( list[i] ) i++;
479     while( i-- )
480         list[i+1] = list[i];
481     list[0] = frame;
482 }
483
484 x264_frame_t *x264_frame_shift( x264_frame_t **list )
485 {
486     x264_frame_t *frame = list[0];
487     int i;
488     for( i = 0; list[i]; i++ )
489         list[i] = list[i+1];
490     assert(frame);
491     return frame;
492 }
493
494 void x264_frame_push_unused( x264_t *h, x264_frame_t *frame )
495 {
496     assert( frame->i_reference_count > 0 );
497     frame->i_reference_count--;
498     if( frame->i_reference_count == 0 )
499         x264_frame_push( h->frames.unused[frame->b_fdec], frame );
500 }
501
502 x264_frame_t *x264_frame_pop_unused( x264_t *h, int b_fdec )
503 {
504     x264_frame_t *frame;
505     if( h->frames.unused[b_fdec][0] )
506         frame = x264_frame_pop( h->frames.unused[b_fdec] );
507     else
508         frame = x264_frame_new( h, b_fdec );
509     if( !frame )
510         return NULL;
511     frame->b_last_minigop_bframe = 0;
512     frame->i_reference_count = 1;
513     frame->b_intra_calculated = 0;
514     frame->b_scenecut = 1;
515     frame->b_keyframe = 0;
516     frame->b_corrupt = 0;
517
518     memset( frame->weight, 0, sizeof(frame->weight) );
519     memset( frame->f_weighted_cost_delta, 0, sizeof(frame->f_weighted_cost_delta) );
520
521     return frame;
522 }
523
524 void x264_frame_push_blank_unused( x264_t *h, x264_frame_t *frame )
525 {
526     assert( frame->i_reference_count > 0 );
527     frame->i_reference_count--;
528     if( frame->i_reference_count == 0 )
529         x264_frame_push( h->frames.blank_unused, frame );
530 }
531
532 x264_frame_t *x264_frame_pop_blank_unused( x264_t *h )
533 {
534     x264_frame_t *frame;
535     if( h->frames.blank_unused[0] )
536         frame = x264_frame_pop( h->frames.blank_unused );
537     else
538         frame = x264_malloc( sizeof(x264_frame_t) );
539     if( !frame )
540         return NULL;
541     frame->b_duplicate = 1;
542     frame->i_reference_count = 1;
543     return frame;
544 }
545
546 void x264_frame_sort( x264_frame_t **list, int b_dts )
547 {
548     int b_ok;
549     do {
550         b_ok = 1;
551         for( int i = 0; list[i+1]; i++ )
552         {
553             int dtype = list[i]->i_type - list[i+1]->i_type;
554             int dtime = list[i]->i_frame - list[i+1]->i_frame;
555             int swap = b_dts ? dtype > 0 || ( dtype == 0 && dtime > 0 )
556                              : dtime > 0;
557             if( swap )
558             {
559                 XCHG( x264_frame_t*, list[i], list[i+1] );
560                 b_ok = 0;
561             }
562         }
563     } while( !b_ok );
564 }
565
566 void x264_weight_scale_plane( x264_t *h, pixel *dst, int i_dst_stride, pixel *src, int i_src_stride,
567                          int i_width, int i_height, x264_weight_t *w )
568 {
569     /* Weight horizontal strips of height 16. This was found to be the optimal height
570      * in terms of the cache loads. */
571     while( i_height > 0 )
572     {
573         for( int x = 0; x < i_width; x += 16 )
574             w->weightfn[16>>2]( dst+x, i_dst_stride, src+x, i_src_stride, w, X264_MIN( i_height, 16 ) );
575         i_height -= 16;
576         dst += 16 * i_dst_stride;
577         src += 16 * i_src_stride;
578     }
579 }
580
581 void x264_frame_delete_list( x264_frame_t **list )
582 {
583     int i = 0;
584     if( !list )
585         return;
586     while( list[i] )
587         x264_frame_delete( list[i++] );
588     x264_free( list );
589 }
590
591 int x264_sync_frame_list_init( x264_sync_frame_list_t *slist, int max_size )
592 {
593     if( max_size < 0 )
594         return -1;
595     slist->i_max_size = max_size;
596     slist->i_size = 0;
597     CHECKED_MALLOCZERO( slist->list, (max_size+1) * sizeof(x264_frame_t*) );
598     if( x264_pthread_mutex_init( &slist->mutex, NULL ) ||
599         x264_pthread_cond_init( &slist->cv_fill, NULL ) ||
600         x264_pthread_cond_init( &slist->cv_empty, NULL ) )
601         return -1;
602     return 0;
603 fail:
604     return -1;
605 }
606
607 void x264_sync_frame_list_delete( x264_sync_frame_list_t *slist )
608 {
609     x264_pthread_mutex_destroy( &slist->mutex );
610     x264_pthread_cond_destroy( &slist->cv_fill );
611     x264_pthread_cond_destroy( &slist->cv_empty );
612     x264_frame_delete_list( slist->list );
613 }
614
615 void x264_sync_frame_list_push( x264_sync_frame_list_t *slist, x264_frame_t *frame )
616 {
617     x264_pthread_mutex_lock( &slist->mutex );
618     while( slist->i_size == slist->i_max_size )
619         x264_pthread_cond_wait( &slist->cv_empty, &slist->mutex );
620     slist->list[ slist->i_size++ ] = frame;
621     x264_pthread_mutex_unlock( &slist->mutex );
622     x264_pthread_cond_broadcast( &slist->cv_fill );
623 }
624
625 x264_frame_t *x264_sync_frame_list_pop( x264_sync_frame_list_t *slist )
626 {
627     x264_frame_t *frame;
628     x264_pthread_mutex_lock( &slist->mutex );
629     while( !slist->i_size )
630         x264_pthread_cond_wait( &slist->cv_fill, &slist->mutex );
631     frame = slist->list[ --slist->i_size ];
632     slist->list[ slist->i_size ] = NULL;
633     x264_pthread_cond_broadcast( &slist->cv_empty );
634     x264_pthread_mutex_unlock( &slist->mutex );
635     return frame;
636 }