Expand borders before chroma weightp analysis
[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 static int x264_frame_internal_csp( int external_csp )
46 {
47     switch( external_csp & X264_CSP_MASK )
48     {
49         case X264_CSP_NV12:
50         case X264_CSP_I420:
51         case X264_CSP_YV12:
52             return X264_CSP_NV12;
53         case X264_CSP_I444:
54         case X264_CSP_YV24:
55         case X264_CSP_BGR:
56         case X264_CSP_BGRA:
57         case X264_CSP_RGB:
58             return X264_CSP_I444;
59         default:
60             return X264_CSP_NONE;
61     }
62 }
63
64 static x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
65 {
66     x264_frame_t *frame;
67     int i_csp = x264_frame_internal_csp( h->param.i_csp );
68     int i_mb_count = h->mb.i_mb_count;
69     int i_stride, i_width, i_lines;
70     int i_padv = PADV << PARAM_INTERLACED;
71     int align = h->param.cpu&X264_CPU_CACHELINE_64 ? 64 : h->param.cpu&X264_CPU_CACHELINE_32 ? 32 : 16;
72     int disalign = h->param.cpu&X264_CPU_ALTIVEC ? 1<<9 : 1<<10;
73     int luma_plane_count = i_csp == X264_CSP_NV12 ? 1 : 3;
74
75     CHECKED_MALLOCZERO( frame, sizeof(x264_frame_t) );
76
77     /* allocate frame data (+64 for extra data for me) */
78     i_width  = h->mb.i_mb_width*16;
79     i_lines  = h->mb.i_mb_height*16;
80     i_stride = align_stride( i_width + 2*PADH, align, disalign );
81
82     if( i_csp == X264_CSP_NV12 )
83     {
84         frame->i_plane = 2;
85         for( int i = 0; i < 2; i++ )
86         {
87             frame->i_width[i] = i_width >> i;
88             frame->i_lines[i] = i_lines >> i;
89             frame->i_stride[i] = i_stride;
90         }
91     }
92     else if( i_csp == X264_CSP_I444 )
93     {
94         frame->i_plane = 3;
95         for( int i = 0; i < 3; i++ )
96         {
97             frame->i_width[i] = i_width;
98             frame->i_lines[i] = i_lines;
99             frame->i_stride[i] = i_stride;
100         }
101     }
102     else
103         goto fail;
104
105     frame->i_width_lowres = frame->i_width[0]/2;
106     frame->i_lines_lowres = frame->i_lines[0]/2;
107     frame->i_stride_lowres = align_stride( frame->i_width_lowres + 2*PADH, align, disalign<<1 );
108
109     for( int i = 0; i < h->param.i_bframe + 2; i++ )
110         for( int j = 0; j < h->param.i_bframe + 2; j++ )
111             CHECKED_MALLOC( frame->i_row_satds[i][j], i_lines/16 * sizeof(int) );
112
113     frame->i_poc = -1;
114     frame->i_type = X264_TYPE_AUTO;
115     frame->i_qpplus1 = X264_QP_AUTO;
116     frame->i_pts = -1;
117     frame->i_frame = -1;
118     frame->i_frame_num = -1;
119     frame->i_lines_completed = -1;
120     frame->b_fdec = b_fdec;
121     frame->i_pic_struct = PIC_STRUCT_AUTO;
122     frame->i_field_cnt = -1;
123     frame->i_duration =
124     frame->i_cpb_duration =
125     frame->i_dpb_output_delay =
126     frame->i_cpb_delay = 0;
127     frame->i_coded_fields_lookahead =
128     frame->i_cpb_delay_lookahead = -1;
129
130     frame->orig = frame;
131
132     if( i_csp == X264_CSP_NV12 )
133     {
134         int chroma_plane_size = (frame->i_stride[1] * (frame->i_lines[1] + i_padv));
135         CHECKED_MALLOC( frame->buffer[1], chroma_plane_size * sizeof(pixel) );
136         frame->plane[1] = frame->buffer[1] + frame->i_stride[1] * i_padv/2 + PADH;
137         if( PARAM_INTERLACED )
138         {
139             CHECKED_MALLOC( frame->buffer_fld[1], chroma_plane_size * sizeof(pixel) );
140             frame->plane_fld[1] = frame->buffer_fld[1] + frame->i_stride[1] * i_padv/2 + PADH;
141         }
142     }
143
144     /* all 4 luma planes allocated together, since the cacheline split code
145      * requires them to be in-phase wrt cacheline alignment. */
146
147     for( int p = 0; p < luma_plane_count; p++ )
148     {
149         int luma_plane_size = align_plane_size( frame->i_stride[p] * (frame->i_lines[p] + 2*i_padv), disalign );
150         if( h->param.analyse.i_subpel_refine && b_fdec )
151         {
152             /* FIXME: Don't allocate both buffers in non-adaptive MBAFF. */
153             CHECKED_MALLOC( frame->buffer[p], 4*luma_plane_size * sizeof(pixel) );
154             if( PARAM_INTERLACED )
155                 CHECKED_MALLOC( frame->buffer_fld[p], 4*luma_plane_size * sizeof(pixel) );
156             for( int i = 0; i < 4; i++ )
157             {
158                 frame->filtered[p][i] = frame->buffer[p] + i*luma_plane_size + frame->i_stride[p] * i_padv + PADH;
159                 frame->filtered_fld[p][i] = frame->buffer_fld[p] + i*luma_plane_size + frame->i_stride[p] * i_padv + PADH;
160             }
161             frame->plane[p] = frame->filtered[p][0];
162             frame->plane_fld[p] = frame->filtered_fld[p][0];
163         }
164         else
165         {
166             CHECKED_MALLOC( frame->buffer[p], luma_plane_size * sizeof(pixel) );
167             if( PARAM_INTERLACED )
168                 CHECKED_MALLOC( frame->buffer_fld[p], luma_plane_size * sizeof(pixel) );
169             frame->filtered[p][0] = frame->plane[p] = frame->buffer[p] + frame->i_stride[p] * i_padv + PADH;
170             frame->filtered_fld[p][0] = frame->plane_fld[p] = frame->buffer_fld[p] + frame->i_stride[p] * i_padv + PADH;
171         }
172     }
173
174     frame->b_duplicate = 0;
175
176     if( b_fdec ) /* fdec frame */
177     {
178         CHECKED_MALLOC( frame->mb_type, i_mb_count * sizeof(int8_t));
179         CHECKED_MALLOC( frame->mb_partition, i_mb_count * sizeof(uint8_t));
180         CHECKED_MALLOC( frame->mv[0], 2*16 * i_mb_count * sizeof(int16_t) );
181         CHECKED_MALLOC( frame->mv16x16, 2*(i_mb_count+1) * sizeof(int16_t) );
182         M32( frame->mv16x16[0] ) = 0;
183         frame->mv16x16++;
184         CHECKED_MALLOC( frame->ref[0], 4 * i_mb_count * sizeof(int8_t) );
185         if( h->param.i_bframe )
186         {
187             CHECKED_MALLOC( frame->mv[1], 2*16 * i_mb_count * sizeof(int16_t) );
188             CHECKED_MALLOC( frame->ref[1], 4 * i_mb_count * sizeof(int8_t) );
189         }
190         else
191         {
192             frame->mv[1]  = NULL;
193             frame->ref[1] = NULL;
194         }
195         CHECKED_MALLOC( frame->i_row_bits, i_lines/16 * sizeof(int) );
196         CHECKED_MALLOC( frame->f_row_qp, i_lines/16 * sizeof(float) );
197         CHECKED_MALLOC( frame->f_row_qscale, i_lines/16 * sizeof(float) );
198         if( h->param.analyse.i_me_method >= X264_ME_ESA )
199         {
200             CHECKED_MALLOC( frame->buffer[3],
201                             frame->i_stride[0] * (frame->i_lines[0] + 2*i_padv) * sizeof(uint16_t) << h->frames.b_have_sub8x8_esa );
202             frame->integral = (uint16_t*)frame->buffer[3] + frame->i_stride[0] * i_padv + PADH;
203         }
204         if( PARAM_INTERLACED )
205             CHECKED_MALLOC( frame->field, i_mb_count * sizeof(uint8_t) );
206     }
207     else /* fenc frame */
208     {
209         if( h->frames.b_have_lowres )
210         {
211             int luma_plane_size = align_plane_size( frame->i_stride_lowres * (frame->i_lines[0]/2 + 2*PADV), disalign );
212
213             CHECKED_MALLOC( frame->buffer_lowres[0], 4 * luma_plane_size * sizeof(pixel) );
214             for( int i = 0; i < 4; i++ )
215                 frame->lowres[i] = frame->buffer_lowres[0] + (frame->i_stride_lowres * PADV + PADH) + i * luma_plane_size;
216
217             for( int j = 0; j <= !!h->param.i_bframe; j++ )
218                 for( int i = 0; i <= h->param.i_bframe; i++ )
219                 {
220                     CHECKED_MALLOCZERO( frame->lowres_mvs[j][i], 2*h->mb.i_mb_count*sizeof(int16_t) );
221                     CHECKED_MALLOC( frame->lowres_mv_costs[j][i], h->mb.i_mb_count*sizeof(int) );
222                 }
223             CHECKED_MALLOC( frame->i_propagate_cost, (i_mb_count+7) * sizeof(uint16_t) );
224             for( int j = 0; j <= h->param.i_bframe+1; j++ )
225                 for( int i = 0; i <= h->param.i_bframe+1; i++ )
226                     CHECKED_MALLOC( frame->lowres_costs[j][i], (i_mb_count+3) * sizeof(uint16_t) );
227             frame->i_intra_cost = frame->lowres_costs[0][0];
228             memset( frame->i_intra_cost, -1, (i_mb_count+3) * sizeof(uint16_t) );
229         }
230         if( h->param.rc.i_aq_mode )
231         {
232             CHECKED_MALLOC( frame->f_qp_offset, h->mb.i_mb_count * sizeof(float) );
233             CHECKED_MALLOC( frame->f_qp_offset_aq, h->mb.i_mb_count * sizeof(float) );
234             if( h->frames.b_have_lowres )
235                 /* shouldn't really be initialized, just silences a valgrind false-positive in x264_mbtree_propagate_cost_sse2 */
236                 CHECKED_MALLOCZERO( frame->i_inv_qscale_factor, (h->mb.i_mb_count+3) * sizeof(uint16_t) );
237         }
238     }
239
240     if( x264_pthread_mutex_init( &frame->mutex, NULL ) )
241         goto fail;
242     if( x264_pthread_cond_init( &frame->cv, NULL ) )
243         goto fail;
244
245     return frame;
246
247 fail:
248     x264_free( frame );
249     return NULL;
250 }
251
252 void x264_frame_delete( x264_frame_t *frame )
253 {
254     /* Duplicate frames are blank copies of real frames (including pointers),
255      * so freeing those pointers would cause a double free later. */
256     if( !frame->b_duplicate )
257     {
258         for( int i = 0; i < 4; i++ )
259         {
260             x264_free( frame->buffer[i] );
261             x264_free( frame->buffer_fld[i] );
262         }
263         for( int i = 0; i < 4; i++ )
264             x264_free( frame->buffer_lowres[i] );
265         for( int i = 0; i < X264_BFRAME_MAX+2; i++ )
266             for( int j = 0; j < X264_BFRAME_MAX+2; j++ )
267                 x264_free( frame->i_row_satds[i][j] );
268         for( int j = 0; j < 2; j++ )
269             for( int i = 0; i <= X264_BFRAME_MAX; i++ )
270             {
271                 x264_free( frame->lowres_mvs[j][i] );
272                 x264_free( frame->lowres_mv_costs[j][i] );
273             }
274         x264_free( frame->i_propagate_cost );
275         for( int j = 0; j <= X264_BFRAME_MAX+1; j++ )
276             for( int i = 0; i <= X264_BFRAME_MAX+1; i++ )
277                 x264_free( frame->lowres_costs[j][i] );
278         x264_free( frame->f_qp_offset );
279         x264_free( frame->f_qp_offset_aq );
280         x264_free( frame->i_inv_qscale_factor );
281         x264_free( frame->i_row_bits );
282         x264_free( frame->f_row_qp );
283         x264_free( frame->f_row_qscale );
284         x264_free( frame->field );
285         x264_free( frame->mb_type );
286         x264_free( frame->mb_partition );
287         x264_free( frame->mv[0] );
288         x264_free( frame->mv[1] );
289         if( frame->mv16x16 )
290             x264_free( frame->mv16x16-1 );
291         x264_free( frame->ref[0] );
292         x264_free( frame->ref[1] );
293         x264_pthread_mutex_destroy( &frame->mutex );
294         x264_pthread_cond_destroy( &frame->cv );
295     }
296     x264_free( frame );
297 }
298
299 static int get_plane_ptr( x264_t *h, x264_picture_t *src, uint8_t **pix, int *stride, int plane, int xshift, int yshift )
300 {
301     int width = h->param.i_width >> xshift;
302     int height = h->param.i_height >> yshift;
303     *pix = src->img.plane[plane];
304     *stride = src->img.i_stride[plane];
305     if( src->img.i_csp & X264_CSP_VFLIP )
306     {
307         *pix += (height-1) * *stride;
308         *stride = -*stride;
309     }
310     if( width > abs(*stride) )
311     {
312         x264_log( h, X264_LOG_ERROR, "Input picture width (%d) is greater than stride (%d)\n", width, *stride );
313         return -1;
314     }
315     return 0;
316 }
317
318 #define get_plane_ptr(...) do{ if( get_plane_ptr(__VA_ARGS__) < 0 ) return -1; }while(0)
319
320 int x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
321 {
322     int i_csp = src->img.i_csp & X264_CSP_MASK;
323     if( i_csp <= X264_CSP_NONE || i_csp >= X264_CSP_MAX )
324     {
325         x264_log( h, X264_LOG_ERROR, "Invalid input colorspace\n" );
326         return -1;
327     }
328
329 #if HIGH_BIT_DEPTH
330     if( !(src->img.i_csp & X264_CSP_HIGH_DEPTH) )
331     {
332         x264_log( h, X264_LOG_ERROR, "This build of x264 requires high depth input. Rebuild to support 8-bit input.\n" );
333         return -1;
334     }
335 #else
336     if( src->img.i_csp & X264_CSP_HIGH_DEPTH )
337     {
338         x264_log( h, X264_LOG_ERROR, "This build of x264 requires 8-bit input. Rebuild to support high depth input.\n" );
339         return -1;
340     }
341 #endif
342
343     dst->i_type     = src->i_type;
344     dst->i_qpplus1  = src->i_qpplus1;
345     dst->i_pts      = dst->i_reordered_pts = src->i_pts;
346     dst->param      = src->param;
347     dst->i_pic_struct = src->i_pic_struct;
348     dst->extra_sei  = src->extra_sei;
349
350     uint8_t *pix[3];
351     int stride[3];
352     if ( i_csp >= X264_CSP_BGR )
353     {
354          stride[0] = src->img.i_stride[0];
355          pix[0] = src->img.plane[0];
356          if( src->img.i_csp & X264_CSP_VFLIP )
357          {
358              pix[0] += (h->param.i_height-1) * stride[0];
359              stride[0] = -stride[0];
360          }
361          int b = i_csp==X264_CSP_RGB ? 2 : 0;
362          h->mc.plane_copy_deinterleave_rgb( dst->plane[1], dst->i_stride[1],
363                                             dst->plane[b], dst->i_stride[b],
364                                             dst->plane[2-b], dst->i_stride[2-b],
365                                             (pixel*)pix[0], stride[0]/sizeof(pixel), i_csp==X264_CSP_BGRA ? 4 : 3, h->param.i_width, h->param.i_height );
366     }
367     else
368     {
369         get_plane_ptr( h, src, &pix[0], &stride[0], 0, 0, 0 );
370         h->mc.plane_copy( dst->plane[0], dst->i_stride[0], (pixel*)pix[0],
371                           stride[0]/sizeof(pixel), h->param.i_width, h->param.i_height );
372         if( i_csp == X264_CSP_NV12 )
373         {
374             get_plane_ptr( h, src, &pix[1], &stride[1], 1, 0, 1 );
375             h->mc.plane_copy( dst->plane[1], dst->i_stride[1], (pixel*)pix[1],
376                               stride[1]/sizeof(pixel), h->param.i_width, h->param.i_height>>1 );
377         }
378         else if( i_csp == X264_CSP_I420 || i_csp == X264_CSP_YV12 )
379         {
380             get_plane_ptr( h, src, &pix[1], &stride[1], i_csp==X264_CSP_I420 ? 1 : 2, 1, 1 );
381             get_plane_ptr( h, src, &pix[2], &stride[2], i_csp==X264_CSP_I420 ? 2 : 1, 1, 1 );
382             h->mc.plane_copy_interleave( dst->plane[1], dst->i_stride[1],
383                                          (pixel*)pix[1], stride[1]/sizeof(pixel),
384                                          (pixel*)pix[2], stride[2]/sizeof(pixel),
385                                          h->param.i_width>>1, h->param.i_height>>1 );
386         }
387         else //if( i_csp == X264_CSP_I444 || i_csp == X264_CSP_YV24 )
388         {
389             get_plane_ptr( h, src, &pix[1], &stride[1], i_csp==X264_CSP_I444 ? 1 : 2, 0, 0 );
390             get_plane_ptr( h, src, &pix[2], &stride[2], i_csp==X264_CSP_I444 ? 2 : 1, 0, 0 );
391             h->mc.plane_copy( dst->plane[1], dst->i_stride[1], (pixel*)pix[1],
392                               stride[1]/sizeof(pixel), h->param.i_width, h->param.i_height );
393             h->mc.plane_copy( dst->plane[2], dst->i_stride[2], (pixel*)pix[2],
394                               stride[2]/sizeof(pixel), h->param.i_width, h->param.i_height );
395         }
396     }
397     return 0;
398 }
399
400 static void ALWAYS_INLINE pixel_memset( pixel *dst, pixel *src, int len, int size )
401 {
402     uint8_t *dstp = (uint8_t*)dst;
403     uint8_t  v1 = *src;
404     uint16_t v2 = size == 1 ? v1 + (v1 <<  8) : M16( src );
405     uint32_t v4 = size <= 2 ? v2 + (v2 << 16) : M32( src );
406     int i = 0;
407     len *= size;
408
409     /* Align the input pointer if it isn't already */
410     if( (intptr_t)dstp & (WORD_SIZE - 1) )
411     {
412         if( size <= 2 && ((intptr_t)dstp & 3) )
413         {
414             if( size == 1 && ((intptr_t)dstp & 1) )
415                 dstp[i++] = v1;
416             if( (intptr_t)dstp & 2 )
417             {
418                 M16( dstp+i ) = v2;
419                 i += 2;
420             }
421         }
422         if( WORD_SIZE == 8 && (intptr_t)dstp & 4 )
423         {
424             M32( dstp+i ) = v4;
425             i += 4;
426         }
427     }
428
429     /* Main copy loop */
430     if( WORD_SIZE == 8 )
431     {
432         uint64_t v8 = v4 + ((uint64_t)v4<<32);
433         for( ; i < len - 7; i+=8 )
434             M64( dstp+i ) = v8;
435     }
436     for( ; i < len - 3; i+=4 )
437         M32( dstp+i ) = v4;
438
439     /* Finish up the last few bytes */
440     if( size <= 2 )
441     {
442         if( i < len - 1 )
443         {
444             M16( dstp+i ) = v2;
445             i += 2;
446         }
447         if( size == 1 && i != len )
448             dstp[i] = v1;
449     }
450 }
451
452 static void ALWAYS_INLINE 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 )
453 {
454 #define PPIXEL(x, y) ( pix + (x) + (y)*i_stride )
455     for( int y = 0; y < i_height; y++ )
456     {
457         /* left band */
458         pixel_memset( PPIXEL(-i_padh, y), PPIXEL(0, y), i_padh>>b_chroma, sizeof(pixel)<<b_chroma );
459         /* right band */
460         pixel_memset( PPIXEL(i_width, y), PPIXEL(i_width-1-b_chroma, y), i_padh>>b_chroma, sizeof(pixel)<<b_chroma );
461     }
462     /* upper band */
463     if( b_pad_top )
464         for( int y = 0; y < i_padv; y++ )
465             memcpy( PPIXEL(-i_padh, -y-1), PPIXEL(-i_padh, 0), (i_width+2*i_padh) * sizeof(pixel) );
466     /* lower band */
467     if( b_pad_bottom )
468         for( int y = 0; y < i_padv; y++ )
469             memcpy( PPIXEL(-i_padh, i_height+y), PPIXEL(-i_padh, i_height-1), (i_width+2*i_padh) * sizeof(pixel) );
470 #undef PPIXEL
471 }
472
473 void x264_frame_expand_border( x264_t *h, x264_frame_t *frame, int mb_y, int b_end )
474 {
475     int b_start = !mb_y;
476     if( mb_y & SLICE_MBAFF )
477         return;
478     for( int i = 0; i < frame->i_plane; i++ )
479     {
480         int shift = i && !CHROMA444;
481         int stride = frame->i_stride[i];
482         int width = 16*h->mb.i_mb_width;
483         int height = (b_end ? 16*(h->mb.i_mb_height - mb_y) >> SLICE_MBAFF : 16) >> shift;
484         int padh = PADH;
485         int padv = PADV >> shift;
486         // buffer: 2 chroma, 3 luma (rounded to 4) because deblocking goes beyond the top of the mb
487         if( b_end && !b_start )
488             height += 4 >> (shift + SLICE_MBAFF);
489         pixel *pix;
490         if( SLICE_MBAFF )
491         {
492             // border samples for each field are extended separately
493             pix = frame->plane_fld[i] + X264_MAX(0, (16*mb_y-4)*stride >> shift);
494             plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end, shift );
495             plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end, shift );
496
497             height = (b_end ? 16*(h->mb.i_mb_height - mb_y) : 32) >> shift;
498             if( b_end && !b_start )
499                 height += 4 >> shift;
500             pix = frame->plane[i] + X264_MAX(0, (16*mb_y-4)*stride >> shift);
501             plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end, shift );
502         }
503         else
504         {
505             pix = frame->plane[i] + X264_MAX(0, (16*mb_y-4)*stride >> shift);
506             plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end, shift );
507         }
508     }
509 }
510
511 void x264_frame_expand_border_filtered( x264_t *h, x264_frame_t *frame, int mb_y, int b_end )
512 {
513     /* during filtering, 8 extra pixels were filtered on each edge,
514      * but up to 3 of the horizontal ones may be wrong.
515        we want to expand border from the last filtered pixel */
516     int b_start = !mb_y;
517     int width = 16*h->mb.i_mb_width + 8;
518     int height = b_end ? (16*(h->mb.i_mb_height - mb_y) >> SLICE_MBAFF) + 16 : 16;
519     int padh = PADH - 4;
520     int padv = PADV - 8;
521     for( int p = 0; p < (CHROMA444 ? 3 : 1); p++ )
522         for( int i = 1; i < 4; i++ )
523         {
524             int stride = frame->i_stride[p];
525             // buffer: 8 luma, to match the hpel filter
526             pixel *pix;
527             if( SLICE_MBAFF )
528             {
529                 pix = frame->filtered_fld[p][i] + (16*mb_y - 16) * stride - 4;
530                 plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end, 0 );
531                 plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end, 0 );
532             }
533
534             pix = frame->filtered[p][i] + (16*mb_y - 8) * stride - 4;
535             plane_expand_border( pix, stride, width, height << SLICE_MBAFF, padh, padv, b_start, b_end, 0 );
536         }
537 }
538
539 void x264_frame_expand_border_lowres( x264_frame_t *frame )
540 {
541     for( int i = 0; i < 4; i++ )
542         plane_expand_border( frame->lowres[i], frame->i_stride_lowres, frame->i_width_lowres, frame->i_lines_lowres, PADH, PADV, 1, 1, 0 );
543 }
544
545 void x264_frame_expand_border_chroma( x264_t *h, x264_frame_t *frame, int plane )
546 {
547     int shift = !CHROMA444;
548     plane_expand_border( frame->plane[plane], frame->i_stride[plane], 16*h->mb.i_mb_width, 16*h->mb.i_mb_height>>shift,
549                          PADH, PADV>>shift, 1, 1, shift );
550 }
551
552 void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame )
553 {
554     for( int i = 0; i < frame->i_plane; i++ )
555     {
556         int i_width = h->param.i_width;
557         int shift = i && !CHROMA444;
558         int i_height = h->param.i_height >> shift;
559         int i_padx = (h->mb.i_mb_width * 16 - h->param.i_width);
560         int i_pady = (h->mb.i_mb_height * 16 - h->param.i_height) >> shift;
561
562         if( i_padx )
563         {
564             for( int y = 0; y < i_height; y++ )
565                 pixel_memset( &frame->plane[i][y*frame->i_stride[i] + i_width],
566                               &frame->plane[i][y*frame->i_stride[i] + i_width - 1-shift],
567                               i_padx>>shift, sizeof(pixel)<<shift );
568         }
569         if( i_pady )
570         {
571             for( int y = i_height; y < i_height + i_pady; y++ )
572                 memcpy( &frame->plane[i][y*frame->i_stride[i]],
573                         &frame->plane[i][(i_height-(~y&PARAM_INTERLACED)-1)*frame->i_stride[i]],
574                         (i_width + i_padx) * sizeof(pixel) );
575         }
576     }
577 }
578
579 void x264_expand_border_mbpair( x264_t *h, int mb_x, int mb_y )
580 {
581     for( int i = 0; i < h->fenc->i_plane; i++ )
582     {
583         int shift = i && !CHROMA444;
584         int stride = h->fenc->i_stride[i];
585         int height = h->param.i_height >> shift;
586         int pady = (h->mb.i_mb_height * 16 - h->param.i_height) >> shift;
587         pixel *fenc = h->fenc->plane[i] + 16*mb_x;
588         for( int y = height; y < height + pady; y++ )
589             memcpy( fenc + y*stride, fenc + (height-1)*stride, 16*sizeof(pixel) );
590     }
591 }
592
593 /* threading */
594 void x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed )
595 {
596     x264_pthread_mutex_lock( &frame->mutex );
597     frame->i_lines_completed = i_lines_completed;
598     x264_pthread_cond_broadcast( &frame->cv );
599     x264_pthread_mutex_unlock( &frame->mutex );
600 }
601
602 void x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed )
603 {
604     x264_pthread_mutex_lock( &frame->mutex );
605     while( frame->i_lines_completed < i_lines_completed )
606         x264_pthread_cond_wait( &frame->cv, &frame->mutex );
607     x264_pthread_mutex_unlock( &frame->mutex );
608 }
609
610 /* list operators */
611
612 void x264_frame_push( x264_frame_t **list, x264_frame_t *frame )
613 {
614     int i = 0;
615     while( list[i] ) i++;
616     list[i] = frame;
617 }
618
619 x264_frame_t *x264_frame_pop( x264_frame_t **list )
620 {
621     x264_frame_t *frame;
622     int i = 0;
623     assert( list[0] );
624     while( list[i+1] ) i++;
625     frame = list[i];
626     list[i] = NULL;
627     return frame;
628 }
629
630 void x264_frame_unshift( x264_frame_t **list, x264_frame_t *frame )
631 {
632     int i = 0;
633     while( list[i] ) i++;
634     while( i-- )
635         list[i+1] = list[i];
636     list[0] = frame;
637 }
638
639 x264_frame_t *x264_frame_shift( x264_frame_t **list )
640 {
641     x264_frame_t *frame = list[0];
642     int i;
643     for( i = 0; list[i]; i++ )
644         list[i] = list[i+1];
645     assert(frame);
646     return frame;
647 }
648
649 void x264_frame_push_unused( x264_t *h, x264_frame_t *frame )
650 {
651     assert( frame->i_reference_count > 0 );
652     frame->i_reference_count--;
653     if( frame->i_reference_count == 0 )
654         x264_frame_push( h->frames.unused[frame->b_fdec], frame );
655 }
656
657 x264_frame_t *x264_frame_pop_unused( x264_t *h, int b_fdec )
658 {
659     x264_frame_t *frame;
660     if( h->frames.unused[b_fdec][0] )
661         frame = x264_frame_pop( h->frames.unused[b_fdec] );
662     else
663         frame = x264_frame_new( h, b_fdec );
664     if( !frame )
665         return NULL;
666     frame->b_last_minigop_bframe = 0;
667     frame->i_reference_count = 1;
668     frame->b_intra_calculated = 0;
669     frame->b_scenecut = 1;
670     frame->b_keyframe = 0;
671     frame->b_corrupt = 0;
672
673     memset( frame->weight, 0, sizeof(frame->weight) );
674     memset( frame->f_weighted_cost_delta, 0, sizeof(frame->f_weighted_cost_delta) );
675
676     return frame;
677 }
678
679 void x264_frame_push_blank_unused( x264_t *h, x264_frame_t *frame )
680 {
681     assert( frame->i_reference_count > 0 );
682     frame->i_reference_count--;
683     if( frame->i_reference_count == 0 )
684         x264_frame_push( h->frames.blank_unused, frame );
685 }
686
687 x264_frame_t *x264_frame_pop_blank_unused( x264_t *h )
688 {
689     x264_frame_t *frame;
690     if( h->frames.blank_unused[0] )
691         frame = x264_frame_pop( h->frames.blank_unused );
692     else
693         frame = x264_malloc( sizeof(x264_frame_t) );
694     if( !frame )
695         return NULL;
696     frame->b_duplicate = 1;
697     frame->i_reference_count = 1;
698     return frame;
699 }
700
701 void x264_weight_scale_plane( x264_t *h, pixel *dst, int i_dst_stride, pixel *src, int i_src_stride,
702                          int i_width, int i_height, x264_weight_t *w )
703 {
704     /* Weight horizontal strips of height 16. This was found to be the optimal height
705      * in terms of the cache loads. */
706     while( i_height > 0 )
707     {
708         for( int x = 0; x < i_width; x += 16 )
709             w->weightfn[16>>2]( dst+x, i_dst_stride, src+x, i_src_stride, w, X264_MIN( i_height, 16 ) );
710         i_height -= 16;
711         dst += 16 * i_dst_stride;
712         src += 16 * i_src_stride;
713     }
714 }
715
716 void x264_frame_delete_list( x264_frame_t **list )
717 {
718     int i = 0;
719     if( !list )
720         return;
721     while( list[i] )
722         x264_frame_delete( list[i++] );
723     x264_free( list );
724 }
725
726 int x264_sync_frame_list_init( x264_sync_frame_list_t *slist, int max_size )
727 {
728     if( max_size < 0 )
729         return -1;
730     slist->i_max_size = max_size;
731     slist->i_size = 0;
732     CHECKED_MALLOCZERO( slist->list, (max_size+1) * sizeof(x264_frame_t*) );
733     if( x264_pthread_mutex_init( &slist->mutex, NULL ) ||
734         x264_pthread_cond_init( &slist->cv_fill, NULL ) ||
735         x264_pthread_cond_init( &slist->cv_empty, NULL ) )
736         return -1;
737     return 0;
738 fail:
739     return -1;
740 }
741
742 void x264_sync_frame_list_delete( x264_sync_frame_list_t *slist )
743 {
744     x264_pthread_mutex_destroy( &slist->mutex );
745     x264_pthread_cond_destroy( &slist->cv_fill );
746     x264_pthread_cond_destroy( &slist->cv_empty );
747     x264_frame_delete_list( slist->list );
748 }
749
750 void x264_sync_frame_list_push( x264_sync_frame_list_t *slist, x264_frame_t *frame )
751 {
752     x264_pthread_mutex_lock( &slist->mutex );
753     while( slist->i_size == slist->i_max_size )
754         x264_pthread_cond_wait( &slist->cv_empty, &slist->mutex );
755     slist->list[ slist->i_size++ ] = frame;
756     x264_pthread_mutex_unlock( &slist->mutex );
757     x264_pthread_cond_broadcast( &slist->cv_fill );
758 }
759
760 x264_frame_t *x264_sync_frame_list_pop( x264_sync_frame_list_t *slist )
761 {
762     x264_frame_t *frame;
763     x264_pthread_mutex_lock( &slist->mutex );
764     while( !slist->i_size )
765         x264_pthread_cond_wait( &slist->cv_fill, &slist->mutex );
766     frame = slist->list[ --slist->i_size ];
767     slist->list[ slist->i_size ] = NULL;
768     x264_pthread_cond_broadcast( &slist->cv_empty );
769     x264_pthread_mutex_unlock( &slist->mutex );
770     return frame;
771 }