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