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