]> git.sesse.net Git - x264/blob - common/macroblock.c
support pkg-config.
[x264] / common / macroblock.c
1 /*****************************************************************************
2  * macroblock.c: h264 encoder library
3  *****************************************************************************
4  * Copyright (C) 2003 Laurent Aimar
5  * $Id: macroblock.c,v 1.1 2004/06/03 19:27:06 fenrir Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27
28 #include "common.h"
29
30 static const int dequant_mf[6][4][4] =
31 {
32     { {10, 13, 10, 13}, {13, 16, 13, 16}, {10, 13, 10, 13}, {13, 16, 13, 16} },
33     { {11, 14, 11, 14}, {14, 18, 14, 18}, {11, 14, 11, 14}, {14, 18, 14, 18} },
34     { {13, 16, 13, 16}, {16, 20, 16, 20}, {13, 16, 13, 16}, {16, 20, 16, 20} },
35     { {14, 18, 14, 18}, {18, 23, 18, 23}, {14, 18, 14, 18}, {18, 23, 18, 23} },
36     { {16, 20, 16, 20}, {20, 25, 20, 25}, {16, 20, 16, 20}, {20, 25, 20, 25} },
37     { {18, 23, 18, 23}, {23, 29, 23, 29}, {18, 23, 18, 23}, {23, 29, 23, 29} }
38 };
39
40 int x264_mb_predict_intra4x4_mode( x264_t *h, int idx )
41 {
42     const int ma = h->mb.cache.intra4x4_pred_mode[x264_scan8[idx] - 1];
43     const int mb = h->mb.cache.intra4x4_pred_mode[x264_scan8[idx] - 8];
44     const int m  = X264_MIN( x264_mb_pred_mode4x4_fix(ma),
45                              x264_mb_pred_mode4x4_fix(mb) );
46
47     if( m < 0 )
48         return I_PRED_4x4_DC;
49
50     return m;
51 }
52
53 int x264_mb_predict_non_zero_code( x264_t *h, int idx )
54 {
55     const int za = h->mb.cache.non_zero_count[x264_scan8[idx] - 1];
56     const int zb = h->mb.cache.non_zero_count[x264_scan8[idx] - 8];
57
58     int i_ret = za + zb;
59
60     if( i_ret < 0x80 )
61     {
62         i_ret = ( i_ret + 1 ) >> 1;
63     }
64     return i_ret & 0x7f;
65 }
66
67 int x264_mb_transform_8x8_allowed( x264_t *h )
68 {
69     if( IS_SKIP( h->mb.i_type ) )
70         return 0;
71     if( h->mb.i_type == P_8x8 || h->mb.i_type == B_8x8 )
72     {
73         int i;
74         for( i = 0; i < 4; i++ )
75             if( !IS_SUB8x8(h->mb.i_sub_partition[i])
76                 || ( h->mb.i_sub_partition[i] == D_DIRECT_8x8 && !h->sps->b_direct8x8_inference ) )
77             {
78                 return 0;
79             }
80     }
81     if( h->mb.i_type == B_DIRECT && !h->sps->b_direct8x8_inference )
82         return 0;
83
84     return 1;
85 }
86
87 void x264_mb_predict_mv( x264_t *h, int i_list, int idx, int i_width, int mvp[2] )
88 {
89     const int i8 = x264_scan8[idx];
90     const int i_ref= h->mb.cache.ref[i_list][i8];
91     int     i_refa = h->mb.cache.ref[i_list][i8 - 1];
92     int16_t *mv_a  = h->mb.cache.mv[i_list][i8 - 1];
93     int     i_refb = h->mb.cache.ref[i_list][i8 - 8];
94     int16_t *mv_b  = h->mb.cache.mv[i_list][i8 - 8];
95     int     i_refc = h->mb.cache.ref[i_list][i8 - 8 + i_width ];
96     int16_t *mv_c  = h->mb.cache.mv[i_list][i8 - 8 + i_width];
97
98     int i_count;
99
100     if( (idx&0x03) == 3 || ( i_width == 2 && (idx&0x3) == 2 )|| i_refc == -2 )
101     {
102         i_refc = h->mb.cache.ref[i_list][i8 - 8 - 1];
103         mv_c   = h->mb.cache.mv[i_list][i8 - 8 - 1];
104     }
105
106     if( h->mb.i_partition == D_16x8 )
107     {
108         if( idx == 0 && i_refb == i_ref )
109         {
110             mvp[0] = mv_b[0];
111             mvp[1] = mv_b[1];
112             return;
113         }
114         else if( idx != 0 && i_refa == i_ref )
115         {
116             mvp[0] = mv_a[0];
117             mvp[1] = mv_a[1];
118             return;
119         }
120     }
121     else if( h->mb.i_partition == D_8x16 )
122     {
123         if( idx == 0 && i_refa == i_ref )
124         {
125             mvp[0] = mv_a[0];
126             mvp[1] = mv_a[1];
127             return;
128         }
129         else if( idx != 0 && i_refc == i_ref )
130         {
131             mvp[0] = mv_c[0];
132             mvp[1] = mv_c[1];
133             return;
134         }
135     }
136
137     i_count = 0;
138     if( i_refa == i_ref ) i_count++;
139     if( i_refb == i_ref ) i_count++;
140     if( i_refc == i_ref ) i_count++;
141
142     if( i_count > 1 )
143     {
144         mvp[0] = x264_median( mv_a[0], mv_b[0], mv_c[0] );
145         mvp[1] = x264_median( mv_a[1], mv_b[1], mv_c[1] );
146     }
147     else if( i_count == 1 )
148     {
149         if( i_refa == i_ref )
150         {
151             mvp[0] = mv_a[0];
152             mvp[1] = mv_a[1];
153         }
154         else if( i_refb == i_ref )
155         {
156             mvp[0] = mv_b[0];
157             mvp[1] = mv_b[1];
158         }
159         else
160         {
161             mvp[0] = mv_c[0];
162             mvp[1] = mv_c[1];
163         }
164     }
165     else if( i_refb == -2 && i_refc == -2 && i_refa != -2 )
166     {
167         mvp[0] = mv_a[0];
168         mvp[1] = mv_a[1];
169     }
170     else
171     {
172         mvp[0] = x264_median( mv_a[0], mv_b[0], mv_c[0] );
173         mvp[1] = x264_median( mv_a[1], mv_b[1], mv_c[1] );
174     }
175 }
176
177 void x264_mb_predict_mv_16x16( x264_t *h, int i_list, int i_ref, int mvp[2] )
178 {
179     int     i_refa = h->mb.cache.ref[i_list][X264_SCAN8_0 - 1];
180     int16_t *mv_a  = h->mb.cache.mv[i_list][X264_SCAN8_0 - 1];
181     int     i_refb = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8];
182     int16_t *mv_b  = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8];
183     int     i_refc = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8 + 4];
184     int16_t *mv_c  = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8 + 4];
185
186     int i_count;
187
188     if( i_refc == -2 )
189     {
190         i_refc = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8 - 1];
191         mv_c   = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8 - 1];
192     }
193
194     i_count = 0;
195     if( i_refa == i_ref ) i_count++;
196     if( i_refb == i_ref ) i_count++;
197     if( i_refc == i_ref ) i_count++;
198
199     if( i_count > 1 )
200     {
201         mvp[0] = x264_median( mv_a[0], mv_b[0], mv_c[0] );
202         mvp[1] = x264_median( mv_a[1], mv_b[1], mv_c[1] );
203     }
204     else if( i_count == 1 )
205     {
206         if( i_refa == i_ref )
207         {
208             mvp[0] = mv_a[0];
209             mvp[1] = mv_a[1];
210         }
211         else if( i_refb == i_ref )
212         {
213             mvp[0] = mv_b[0];
214             mvp[1] = mv_b[1];
215         }
216         else
217         {
218             mvp[0] = mv_c[0];
219             mvp[1] = mv_c[1];
220         }
221     }
222     else if( i_refb == -2 && i_refc == -2 && i_refa != -2 )
223     {
224         mvp[0] = mv_a[0];
225         mvp[1] = mv_a[1];
226     }
227     else
228     {
229         mvp[0] = x264_median( mv_a[0], mv_b[0], mv_c[0] );
230         mvp[1] = x264_median( mv_a[1], mv_b[1], mv_c[1] );
231     }
232 }
233
234
235 void x264_mb_predict_mv_pskip( x264_t *h, int mv[2] )
236 {
237     int     i_refa = h->mb.cache.ref[0][X264_SCAN8_0 - 1];
238     int     i_refb = h->mb.cache.ref[0][X264_SCAN8_0 - 8];
239     int16_t *mv_a  = h->mb.cache.mv[0][X264_SCAN8_0 - 1];
240     int16_t *mv_b  = h->mb.cache.mv[0][X264_SCAN8_0 - 8];
241
242     if( i_refa == -2 || i_refb == -2 ||
243         ( i_refa == 0 && mv_a[0] == 0 && mv_a[1] == 0 ) ||
244         ( i_refb == 0 && mv_b[0] == 0 && mv_b[1] == 0 ) )
245     {
246         mv[0] = mv[1] = 0;
247     }
248     else
249     {
250         x264_mb_predict_mv_16x16( h, 0, 0, mv );
251     }
252 }
253
254 static int x264_mb_predict_mv_direct16x16_temporal( x264_t *h )
255 {
256     int i_mb_4x4 = 16 * h->mb.i_mb_stride * h->mb.i_mb_y + 4 * h->mb.i_mb_x;
257     int i_mb_8x8 =  4 * h->mb.i_mb_stride * h->mb.i_mb_y + 2 * h->mb.i_mb_x;
258     int i;
259     
260     x264_macroblock_cache_ref( h, 0, 0, 4, 4, 1, 0 );
261     
262     if( IS_INTRA( h->fref1[0]->mb_type[ h->mb.i_mb_xy ] ) )
263     {
264         x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, 0 );
265         x264_macroblock_cache_mv(  h, 0, 0, 4, 4, 0, 0, 0 );
266         x264_macroblock_cache_mv(  h, 0, 0, 4, 4, 1, 0, 0 );
267         return 1;
268     }
269
270     /* FIXME: optimize per block size */
271     for( i = 0; i < 4; i++ )
272     {
273         const int x8 = 2*(i%2);
274         const int y8 = 2*(i/2);
275         const int i_part_8x8 = i_mb_8x8 + x8/2 + y8 * h->mb.i_mb_stride;
276         const int i_ref = h->mb.map_col_to_list0[ h->fref1[0]->ref[0][ i_part_8x8 ] ];
277
278         if( i_ref >= 0 )
279         {
280             const int dist_scale_factor = h->mb.dist_scale_factor[i_ref][0];
281             int x4, y4;
282
283             x264_macroblock_cache_ref( h, x8, y8, 2, 2, 0, i_ref );
284
285             for( y4 = y8; y4 < y8+2; y4++ )
286                 for( x4 = x8; x4 < x8+2; x4++ )
287                 {
288                     const int16_t *mv_col = h->fref1[0]->mv[0][ i_mb_4x4 + x4 + y4 * 4 * h->mb.i_mb_stride ];
289                     int mv_l0[2];
290                     mv_l0[0] = ( dist_scale_factor * mv_col[0] + 128 ) >> 8;
291                     mv_l0[1] = ( dist_scale_factor * mv_col[1] + 128 ) >> 8;
292                     x264_macroblock_cache_mv( h, x4, y4, 1, 1, 0, mv_l0[0], mv_l0[1] );
293                     x264_macroblock_cache_mv( h, x4, y4, 1, 1, 1, mv_l0[0] - mv_col[0], mv_l0[1] - mv_col[1] );
294                 }
295         }
296         else
297         {
298             /* the colocated ref isn't in the current list0 */
299             /* FIXME: we might still be able to use direct_8x8 on some partitions */
300             /* FIXME: with B-pyramid + extensive ref list reordering
301              *   (not currently used), we would also have to check
302              *   l1mv1 like in spatial mode */
303             return 0;
304         }
305     }
306
307     return 1;
308 }
309
310 static int x264_mb_predict_mv_direct16x16_spatial( x264_t *h )
311 {
312     int ref[2];
313     int mv[2][2];
314     int i_list;
315     int i8, i4;
316     const int8_t *l1ref0 = &h->fref1[0]->ref[0][ h->mb.i_b8_xy ];
317     const int8_t *l1ref1 = &h->fref1[0]->ref[1][ h->mb.i_b8_xy ];
318     const int16_t (*l1mv0)[2] = (const int16_t (*)[2]) &h->fref1[0]->mv[0][ h->mb.i_b4_xy ];
319     const int16_t (*l1mv1)[2] = (const int16_t (*)[2]) &h->fref1[0]->mv[1][ h->mb.i_b4_xy ];
320     const int intra_col = IS_INTRA( h->fref1[0]->mb_type[ h->mb.i_mb_xy ] );
321
322     for( i_list=0; i_list<2; i_list++ )
323     {
324         int i_refa = h->mb.cache.ref[i_list][X264_SCAN8_0 - 1];
325         int i_refb = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8];
326         int i_refc = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8 + 4];
327         if( i_refc == -2 )
328             i_refc = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8 - 1];
329
330         ref[i_list] = i_refa;
331         if( ref[i_list] < 0 || ( i_refb < ref[i_list] && i_refb >= 0 ))
332             ref[i_list] = i_refb;
333         if( ref[i_list] < 0 || ( i_refc < ref[i_list] && i_refc >= 0 ))
334             ref[i_list] = i_refc;
335         if( ref[i_list] < 0 )
336             ref[i_list] = -1;
337     }
338
339     if( ref[0] < 0 && ref[1] < 0 )
340     {
341         ref[0] = 
342         ref[1] = 0;
343         mv[0][0] = 
344         mv[0][1] = 
345         mv[1][0] = 
346         mv[1][1] = 0;
347     }
348     else
349     {
350         for( i_list=0; i_list<2; i_list++ )
351         {
352             if( ref[i_list] >= 0 )
353                 x264_mb_predict_mv_16x16( h, i_list, ref[i_list], mv[i_list] );
354             else
355                 mv[i_list][0] = mv[i_list][1] = 0;
356         }
357     }
358
359     x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, ref[0] );
360     x264_macroblock_cache_ref( h, 0, 0, 4, 4, 1, ref[1] );
361     x264_macroblock_cache_mv(  h, 0, 0, 4, 4, 0, mv[0][0], mv[0][1] );
362     x264_macroblock_cache_mv(  h, 0, 0, 4, 4, 1, mv[1][0], mv[1][1] );
363
364     /* col_zero_flag */
365     for( i8=0; i8<4; i8++ )
366     {
367         const int x8 = i8%2;
368         const int y8 = i8/2;
369         const int o8 = x8 + y8 * h->mb.i_b8_stride;
370         if( !intra_col && ( l1ref0[o8] == 0 || ( l1ref0[o8] < 0 && l1ref1[o8] == 0 ) ) )
371         {
372             const int16_t (*l1mv)[2] = (l1ref0[o8] == 0) ? l1mv0 : l1mv1;
373             for( i4=0; i4<4; i4++ )
374             {
375                 const int x4 = i4%2 + 2*x8;
376                 const int y4 = i4/2 + 2*y8;
377                 const int16_t *mvcol = l1mv[x4 + y4 * h->mb.i_b4_stride];
378                 if( abs( mvcol[0] ) <= 1 && abs( mvcol[1] ) <= 1 )
379                 {
380                     if( ref[0] == 0 )
381                         x264_macroblock_cache_mv( h, x4, y4, 1, 1, 0, 0, 0 );
382                     if( ref[1] == 0 )
383                         x264_macroblock_cache_mv( h, x4, y4, 1, 1, 1, 0, 0 );
384                 }
385             }
386         }
387     }
388
389     return 1;
390 }
391
392 int x264_mb_predict_mv_direct16x16( x264_t *h )
393 {
394     int b_available;
395     if( h->param.analyse.i_direct_mv_pred == X264_DIRECT_PRED_NONE )
396         return 0;
397     else if( h->sh.b_direct_spatial_mv_pred )
398         b_available = x264_mb_predict_mv_direct16x16_spatial( h );
399     else
400         b_available = x264_mb_predict_mv_direct16x16_temporal( h );
401
402     /* cache ref & mv */
403     if( b_available )
404     {
405         int i, l;
406         for( l = 0; l < 2; l++ )
407             for( i = 0; i < 4; i++ )
408                 h->mb.cache.direct_ref[l][i] = h->mb.cache.ref[l][x264_scan8[i*4]];
409         memcpy(h->mb.cache.direct_mv, h->mb.cache.mv, sizeof(h->mb.cache.mv));
410     }
411
412     return b_available;
413 }
414
415 void x264_mb_load_mv_direct8x8( x264_t *h, int idx )
416 {
417     const int x = 2*(idx%2);
418     const int y = 2*(idx/2);
419     int l;
420     x264_macroblock_cache_ref( h, x, y, 2, 2, 0, h->mb.cache.direct_ref[0][idx] );
421     x264_macroblock_cache_ref( h, x, y, 2, 2, 1, h->mb.cache.direct_ref[1][idx] );
422     for( l = 0; l < 2; l++ )
423     {
424         *(uint64_t*)h->mb.cache.mv[l][x264_scan8[idx*4]] =
425         *(uint64_t*)h->mb.cache.direct_mv[l][x264_scan8[idx*4]];
426         *(uint64_t*)h->mb.cache.mv[l][x264_scan8[idx*4]+8] =
427         *(uint64_t*)h->mb.cache.direct_mv[l][x264_scan8[idx*4]+8];
428     }
429 }
430
431 /* This just improves encoder performance, it's not part of the spec */
432 void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int mvc[8][2], int *i_mvc )
433 {
434     int16_t (*mvr)[2] = h->mb.mvr[i_list][i_ref];
435     int i = 0;
436
437 #define SET_MVP(mvp) { \
438         mvc[i][0] = mvp[0]; \
439         mvc[i][1] = mvp[1]; \
440         i++; \
441     }
442
443     /* b_direct */
444     if( h->sh.i_type == SLICE_TYPE_B
445         && h->mb.cache.ref[i_list][x264_scan8[12]] == i_ref )
446     {
447         SET_MVP( h->mb.cache.mv[i_list][x264_scan8[12]] );
448     }
449
450     /* spatial predictors */
451     if( h->mb.i_neighbour & MB_LEFT )
452     {
453         int i_mb_l = h->mb.i_mb_xy - 1;
454         /* skip MBs didn't go through the whole search process, so mvr is undefined */
455         if( !IS_SKIP( h->mb.type[i_mb_l] ) )
456             SET_MVP( mvr[i_mb_l] );
457     }
458     if( h->mb.i_neighbour & MB_TOP )
459     {
460         int i_mb_t = h->mb.i_mb_xy - h->mb.i_mb_stride;
461         if( !IS_SKIP( h->mb.type[i_mb_t] ) )
462             SET_MVP( mvr[i_mb_t] );
463
464         if( h->mb.i_neighbour & MB_TOPLEFT && !IS_SKIP( h->mb.type[i_mb_t - 1] ) )
465             SET_MVP( mvr[i_mb_t-1] );
466         if( h->mb.i_mb_x < h->mb.i_mb_stride - 1 && !IS_SKIP( h->mb.type[i_mb_t + 1] ) )
467             SET_MVP( mvr[i_mb_t+1] );
468     }
469 #undef SET_MVP
470
471     /* temporal predictors */
472     if( h->fref0[0]->i_ref[0] > 0 )
473     {
474         x264_frame_t *l0 = h->fref0[0];
475         int ref_col_cur, ref_col_prev = -1;
476         int scale = 0;
477
478 #define SET_TMVP(dx, dy) { \
479             int i_b4 = h->mb.i_b4_xy + dx*4 + dy*4*h->mb.i_b4_stride; \
480             int i_b8 = h->mb.i_b8_xy + dx*2 + dy*2*h->mb.i_b8_stride; \
481             ref_col_cur = l0->ref[0][i_b8]; \
482             if( ref_col_cur >= 0 ) \
483             { \
484                 /* TODO: calc once per frame and tablize? */\
485                 if( ref_col_cur != ref_col_prev ) \
486                     scale = 256 * (h->fenc->i_poc - h->fref0[i_ref]->i_poc) \
487                                 / (l0->i_poc - l0->ref_poc[0][ref_col_cur]); \
488                 mvc[i][0] = l0->mv[0][i_b4][0] * scale / 256; \
489                 mvc[i][1] = l0->mv[0][i_b4][1] * scale / 256; \
490                 i++; \
491                 ref_col_prev = ref_col_cur; \
492             } \
493         }
494
495         SET_TMVP(0,0);
496         if( h->mb.i_mb_x < h->sps->i_mb_width-1 )
497             SET_TMVP(1,0);
498         if( h->mb.i_mb_y < h->sps->i_mb_height-1 )
499             SET_TMVP(0,1);
500 #undef SET_TMVP
501     }
502
503     *i_mvc = i;
504 }
505
506 static inline void x264_mb_mc_0xywh( x264_t *h, int x, int y, int width, int height )
507 {
508     const int i8 = x264_scan8[0]+x+8*y;
509     const int i_ref = h->mb.cache.ref[0][i8];
510     const int mvx   = x264_clip3( h->mb.cache.mv[0][i8][0], h->mb.mv_min[0], h->mb.mv_max[0] );
511     const int mvy   = x264_clip3( h->mb.cache.mv[0][i8][1], h->mb.mv_min[1], h->mb.mv_max[1] );
512
513     h->mc.mc_luma( h->mb.pic.p_fref[0][i_ref], h->mb.pic.i_stride[0],
514                     &h->mb.pic.p_fdec[0][4*y * h->mb.pic.i_stride[0]+4*x],           h->mb.pic.i_stride[0],
515                     mvx + 4*4*x, mvy + 4*4*y, 4*width, 4*height );
516
517     h->mc.mc_chroma( &h->mb.pic.p_fref[0][i_ref][4][2*y*h->mb.pic.i_stride[1]+2*x], h->mb.pic.i_stride[1],
518                       &h->mb.pic.p_fdec[1][2*y*h->mb.pic.i_stride[1]+2*x],           h->mb.pic.i_stride[1],
519                       mvx, mvy, 2*width, 2*height );
520
521     h->mc.mc_chroma( &h->mb.pic.p_fref[0][i_ref][5][2*y*h->mb.pic.i_stride[2]+2*x], h->mb.pic.i_stride[2],
522                       &h->mb.pic.p_fdec[2][2*y*h->mb.pic.i_stride[2]+2*x],           h->mb.pic.i_stride[2],
523                       mvx, mvy, 2*width, 2*height );
524 }
525 static inline void x264_mb_mc_1xywh( x264_t *h, int x, int y, int width, int height )
526 {
527     const int i8 = x264_scan8[0]+x+8*y;
528     const int i_ref = h->mb.cache.ref[1][i8];
529     const int mvx   = x264_clip3( h->mb.cache.mv[1][i8][0], h->mb.mv_min[0], h->mb.mv_max[0] );
530     const int mvy   = x264_clip3( h->mb.cache.mv[1][i8][1], h->mb.mv_min[1], h->mb.mv_max[1] );
531
532     h->mc.mc_luma( h->mb.pic.p_fref[1][i_ref], h->mb.pic.i_stride[0],
533                     &h->mb.pic.p_fdec[0][4*y *h->mb.pic.i_stride[0]+4*x],            h->mb.pic.i_stride[0],
534                     mvx + 4*4*x, mvy + 4*4*y, 4*width, 4*height );
535
536     h->mc.mc_chroma( &h->mb.pic.p_fref[1][i_ref][4][2*y*h->mb.pic.i_stride[1]+2*x], h->mb.pic.i_stride[1],
537                       &h->mb.pic.p_fdec[1][2*y*h->mb.pic.i_stride[1]+2*x],           h->mb.pic.i_stride[1],
538                       mvx, mvy, 2*width, 2*height );
539
540     h->mc.mc_chroma( &h->mb.pic.p_fref[1][i_ref][5][2*y*h->mb.pic.i_stride[2]+2*x], h->mb.pic.i_stride[2],
541                       &h->mb.pic.p_fdec[2][2*y*h->mb.pic.i_stride[2]+2*x],           h->mb.pic.i_stride[2],
542                       mvx, mvy, 2*width, 2*height );
543 }
544
545 static inline void x264_mb_mc_01xywh( x264_t *h, int x, int y, int width, int height )
546 {
547     const int i8 = x264_scan8[0]+x+8*y;
548
549     const int i_ref1 = h->mb.cache.ref[1][i8];
550     const int mvx1   = x264_clip3( h->mb.cache.mv[1][i8][0], h->mb.mv_min[0], h->mb.mv_max[0] );
551     const int mvy1   = x264_clip3( h->mb.cache.mv[1][i8][1], h->mb.mv_min[1], h->mb.mv_max[1] );
552     DECLARE_ALIGNED( uint8_t, tmp[16*16], 16 );
553     int i_mode = x264_size2pixel[height][width];
554
555     x264_mb_mc_0xywh( h, x, y, width, height );
556
557     h->mc.mc_luma( h->mb.pic.p_fref[1][i_ref1], h->mb.pic.i_stride[0],
558                     tmp, 16, mvx1 + 4*4*x, mvy1 + 4*4*y, 4*width, 4*height );
559
560     if( h->param.analyse.b_weighted_bipred )
561     {
562         const int i_ref0 = h->mb.cache.ref[0][i8];
563         const int weight = h->mb.bipred_weight[i_ref0][i_ref1];
564
565         h->mc.avg_weight[i_mode]( &h->mb.pic.p_fdec[0][4*y *h->mb.pic.i_stride[0]+4*x], h->mb.pic.i_stride[0], tmp, 16, weight );
566
567         h->mc.mc_chroma( &h->mb.pic.p_fref[1][i_ref1][4][2*y*h->mb.pic.i_stride[1]+2*x], h->mb.pic.i_stride[1],
568                           tmp, 16, mvx1, mvy1, 2*width, 2*height );
569         h->mc.avg_weight[i_mode+3]( &h->mb.pic.p_fdec[1][2*y*h->mb.pic.i_stride[1]+2*x], h->mb.pic.i_stride[1], tmp, 16, weight );
570
571         h->mc.mc_chroma( &h->mb.pic.p_fref[1][i_ref1][5][2*y*h->mb.pic.i_stride[2]+2*x], h->mb.pic.i_stride[2],
572                           tmp, 16, mvx1, mvy1, 2*width, 2*height );
573         h->mc.avg_weight[i_mode+3]( &h->mb.pic.p_fdec[2][2*y*h->mb.pic.i_stride[2]+2*x], h->mb.pic.i_stride[2], tmp, 16, weight );
574     }
575     else
576     {
577         h->mc.avg[i_mode]( &h->mb.pic.p_fdec[0][4*y *h->mb.pic.i_stride[0]+4*x], h->mb.pic.i_stride[0], tmp, 16 );
578
579         h->mc.mc_chroma( &h->mb.pic.p_fref[1][i_ref1][4][2*y*h->mb.pic.i_stride[1]+2*x], h->mb.pic.i_stride[1],
580                           tmp, 16, mvx1, mvy1, 2*width, 2*height );
581         h->mc.avg[i_mode+3]( &h->mb.pic.p_fdec[1][2*y*h->mb.pic.i_stride[1]+2*x], h->mb.pic.i_stride[1], tmp, 16 );
582
583         h->mc.mc_chroma( &h->mb.pic.p_fref[1][i_ref1][5][2*y*h->mb.pic.i_stride[2]+2*x], h->mb.pic.i_stride[2],
584                           tmp, 16, mvx1, mvy1, 2*width, 2*height );
585         h->mc.avg[i_mode+3]( &h->mb.pic.p_fdec[2][2*y*h->mb.pic.i_stride[2]+2*x], h->mb.pic.i_stride[2], tmp, 16 );
586     }
587 }
588
589 static void x264_mb_mc_direct8x8( x264_t *h, int x, int y )
590 {
591     const int i8 = x264_scan8[0] + x + 8*y;
592
593     /* FIXME: optimize based on current block size, not global settings? */
594     if( h->sps->b_direct8x8_inference )
595     {
596         if( h->mb.cache.ref[0][i8] >= 0 )
597             if( h->mb.cache.ref[1][i8] >= 0 )
598                 x264_mb_mc_01xywh( h, x, y, 2, 2 );
599             else
600                 x264_mb_mc_0xywh( h, x, y, 2, 2 );
601         else
602             x264_mb_mc_1xywh( h, x, y, 2, 2 );
603     }
604     else
605     {
606         if( h->mb.cache.ref[0][i8] >= 0 )
607         {
608             if( h->mb.cache.ref[1][i8] >= 0 )
609             {
610                 x264_mb_mc_01xywh( h, x+0, y+0, 1, 1 );
611                 x264_mb_mc_01xywh( h, x+1, y+0, 1, 1 );
612                 x264_mb_mc_01xywh( h, x+0, y+1, 1, 1 );
613                 x264_mb_mc_01xywh( h, x+1, y+1, 1, 1 );
614             }
615             else
616             {
617                 x264_mb_mc_0xywh( h, x+0, y+0, 1, 1 );
618                 x264_mb_mc_0xywh( h, x+1, y+0, 1, 1 );
619                 x264_mb_mc_0xywh( h, x+0, y+1, 1, 1 );
620                 x264_mb_mc_0xywh( h, x+1, y+1, 1, 1 );
621             }
622         }
623         else
624         {
625             x264_mb_mc_1xywh( h, x+0, y+0, 1, 1 );
626             x264_mb_mc_1xywh( h, x+1, y+0, 1, 1 );
627             x264_mb_mc_1xywh( h, x+0, y+1, 1, 1 );
628             x264_mb_mc_1xywh( h, x+1, y+1, 1, 1 );
629         }
630     }
631 }
632
633 void x264_mb_mc( x264_t *h )
634 {
635     if( h->mb.i_type == P_L0 )
636     {
637         if( h->mb.i_partition == D_16x16 )
638         {
639             x264_mb_mc_0xywh( h, 0, 0, 4, 4 );
640         }
641         else if( h->mb.i_partition == D_16x8 )
642         {
643             x264_mb_mc_0xywh( h, 0, 0, 4, 2 );
644             x264_mb_mc_0xywh( h, 0, 2, 4, 2 );
645         }
646         else if( h->mb.i_partition == D_8x16 )
647         {
648             x264_mb_mc_0xywh( h, 0, 0, 2, 4 );
649             x264_mb_mc_0xywh( h, 2, 0, 2, 4 );
650         }
651     }
652     else if( h->mb.i_type == P_8x8 || h->mb.i_type == B_8x8 )
653     {
654         int i;
655         for( i = 0; i < 4; i++ )
656         {
657             const int x = 2*(i%2);
658             const int y = 2*(i/2);
659             switch( h->mb.i_sub_partition[i] )
660             {
661                 case D_L0_8x8:
662                     x264_mb_mc_0xywh( h, x, y, 2, 2 );
663                     break;
664                 case D_L0_8x4:
665                     x264_mb_mc_0xywh( h, x, y+0, 2, 1 );
666                     x264_mb_mc_0xywh( h, x, y+1, 2, 1 );
667                     break;
668                 case D_L0_4x8:
669                     x264_mb_mc_0xywh( h, x+0, y, 1, 2 );
670                     x264_mb_mc_0xywh( h, x+1, y, 1, 2 );
671                     break;
672                 case D_L0_4x4:
673                     x264_mb_mc_0xywh( h, x+0, y+0, 1, 1 );
674                     x264_mb_mc_0xywh( h, x+1, y+0, 1, 1 );
675                     x264_mb_mc_0xywh( h, x+0, y+1, 1, 1 );
676                     x264_mb_mc_0xywh( h, x+1, y+1, 1, 1 );
677                     break;
678                 case D_L1_8x8:
679                     x264_mb_mc_1xywh( h, x, y, 2, 2 );
680                     break;
681                 case D_L1_8x4:
682                     x264_mb_mc_1xywh( h, x, y+0, 2, 1 );
683                     x264_mb_mc_1xywh( h, x, y+1, 2, 1 );
684                     break;
685                 case D_L1_4x8:
686                     x264_mb_mc_1xywh( h, x+0, y, 1, 2 );
687                     x264_mb_mc_1xywh( h, x+1, y, 1, 2 );
688                     break;
689                 case D_L1_4x4:
690                     x264_mb_mc_1xywh( h, x+0, y+0, 1, 1 );
691                     x264_mb_mc_1xywh( h, x+1, y+0, 1, 1 );
692                     x264_mb_mc_1xywh( h, x+0, y+1, 1, 1 );
693                     x264_mb_mc_1xywh( h, x+1, y+1, 1, 1 );
694                     break;
695                 case D_BI_8x8:
696                     x264_mb_mc_01xywh( h, x, y, 2, 2 );
697                     break;
698                 case D_BI_8x4:
699                     x264_mb_mc_01xywh( h, x, y+0, 2, 1 );
700                     x264_mb_mc_01xywh( h, x, y+1, 2, 1 );
701                     break;
702                 case D_BI_4x8:
703                     x264_mb_mc_01xywh( h, x+0, y, 1, 2 );
704                     x264_mb_mc_01xywh( h, x+1, y, 1, 2 );
705                     break;
706                 case D_BI_4x4:
707                     x264_mb_mc_01xywh( h, x+0, y+0, 1, 1 );
708                     x264_mb_mc_01xywh( h, x+1, y+0, 1, 1 );
709                     x264_mb_mc_01xywh( h, x+0, y+1, 1, 1 );
710                     x264_mb_mc_01xywh( h, x+1, y+1, 1, 1 );
711                     break;
712                 case D_DIRECT_8x8:
713                     x264_mb_mc_direct8x8( h, x, y );
714                     break;
715             }
716         }
717     }
718     else if( h->mb.i_type == B_SKIP || h->mb.i_type == B_DIRECT )
719     {
720         x264_mb_mc_direct8x8( h, 0, 0 );
721         x264_mb_mc_direct8x8( h, 2, 0 );
722         x264_mb_mc_direct8x8( h, 0, 2 );
723         x264_mb_mc_direct8x8( h, 2, 2 );
724     }
725     else    /* B_*x* */
726     {
727         int b_list0[2];
728         int b_list1[2];
729
730         int i;
731
732         /* init ref list utilisations */
733         for( i = 0; i < 2; i++ )
734         {
735             b_list0[i] = x264_mb_type_list0_table[h->mb.i_type][i];
736             b_list1[i] = x264_mb_type_list1_table[h->mb.i_type][i];
737         }
738         if( h->mb.i_partition == D_16x16 )
739         {
740             if( b_list0[0] && b_list1[0] ) x264_mb_mc_01xywh( h, 0, 0, 4, 4 );
741             else if( b_list0[0] )          x264_mb_mc_0xywh ( h, 0, 0, 4, 4 );
742             else if( b_list1[0] )          x264_mb_mc_1xywh ( h, 0, 0, 4, 4 );
743         }
744         else if( h->mb.i_partition == D_16x8 )
745         {
746             if( b_list0[0] && b_list1[0] ) x264_mb_mc_01xywh( h, 0, 0, 4, 2 );
747             else if( b_list0[0] )          x264_mb_mc_0xywh ( h, 0, 0, 4, 2 );
748             else if( b_list1[0] )          x264_mb_mc_1xywh ( h, 0, 0, 4, 2 );
749
750             if( b_list0[1] && b_list1[1] ) x264_mb_mc_01xywh( h, 0, 2, 4, 2 );
751             else if( b_list0[1] )          x264_mb_mc_0xywh ( h, 0, 2, 4, 2 );
752             else if( b_list1[1] )          x264_mb_mc_1xywh ( h, 0, 2, 4, 2 );
753         }
754         else if( h->mb.i_partition == D_8x16 )
755         {
756             if( b_list0[0] && b_list1[0] ) x264_mb_mc_01xywh( h, 0, 0, 2, 4 );
757             else if( b_list0[0] )          x264_mb_mc_0xywh ( h, 0, 0, 2, 4 );
758             else if( b_list1[0] )          x264_mb_mc_1xywh ( h, 0, 0, 2, 4 );
759
760             if( b_list0[1] && b_list1[1] ) x264_mb_mc_01xywh( h, 2, 0, 2, 4 );
761             else if( b_list0[1] )          x264_mb_mc_0xywh ( h, 2, 0, 2, 4 );
762             else if( b_list1[1] )          x264_mb_mc_1xywh ( h, 2, 0, 2, 4 );
763         }
764     }
765 }
766
767 void x264_macroblock_cache_init( x264_t *h )
768 {
769     int i, j;
770     int i_mb_count = h->mb.i_mb_count;
771
772     h->mb.i_mb_stride = h->sps->i_mb_width;
773     h->mb.i_b8_stride = h->sps->i_mb_width * 2;
774     h->mb.i_b4_stride = h->sps->i_mb_width * 4;
775
776     h->mb.qp  = x264_malloc( i_mb_count * sizeof(int8_t) );
777     h->mb.cbp = x264_malloc( i_mb_count * sizeof(int16_t) );
778     h->mb.skipbp = x264_malloc( i_mb_count * sizeof(int8_t) );
779     h->mb.mb_transform_size = x264_malloc( i_mb_count * sizeof(int8_t) );
780
781     /* 0 -> 3 top(4), 4 -> 6 : left(3) */
782     h->mb.intra4x4_pred_mode = x264_malloc( i_mb_count * 7 * sizeof( int8_t ) );
783
784     /* all coeffs */
785     h->mb.non_zero_count = x264_malloc( i_mb_count * 24 * sizeof( uint8_t ) );
786
787     if( h->param.b_cabac )
788     {
789         h->mb.chroma_pred_mode = x264_malloc( i_mb_count * sizeof( int8_t) );
790         h->mb.mvd[0] = x264_malloc( 2*16 * i_mb_count * sizeof( int16_t ) );
791         h->mb.mvd[1] = x264_malloc( 2*16 * i_mb_count * sizeof( int16_t ) );
792     }
793
794     for( i=0; i<2; i++ )
795     {
796         int i_refs = (i ? 1 : h->param.i_frame_reference) + h->param.b_bframe_pyramid;
797         for( j=0; j < i_refs && j < 16; j++ )
798             h->mb.mvr[i][j] = x264_malloc( 2 * i_mb_count * sizeof( int16_t ) );
799     }
800
801     /* init with not avaiable (for top right idx=7,15) */
802     memset( h->mb.cache.ref[0], -2, X264_SCAN8_SIZE * sizeof( int8_t ) );
803     memset( h->mb.cache.ref[1], -2, X264_SCAN8_SIZE * sizeof( int8_t ) );
804 }
805 void x264_macroblock_cache_end( x264_t *h )
806 {
807     int i, j;
808     for( i=0; i<2; i++ )
809     {
810         int i_refs = i ? 1 + h->param.b_bframe_pyramid : h->param.i_frame_reference;
811         for( j=0; j < i_refs; j++ )
812             x264_free( h->mb.mvr[i][j] );
813     }
814     if( h->param.b_cabac )
815     {
816         x264_free( h->mb.chroma_pred_mode );
817         x264_free( h->mb.mvd[0] );
818         x264_free( h->mb.mvd[1] );
819     }
820     x264_free( h->mb.intra4x4_pred_mode );
821     x264_free( h->mb.non_zero_count );
822     x264_free( h->mb.mb_transform_size );
823     x264_free( h->mb.skipbp );
824     x264_free( h->mb.cbp );
825     x264_free( h->mb.qp );
826 }
827 void x264_macroblock_slice_init( x264_t *h )
828 {
829     int i, j;
830
831     h->mb.mv[0] = h->fdec->mv[0];
832     h->mb.mv[1] = h->fdec->mv[1];
833     h->mb.ref[0] = h->fdec->ref[0];
834     h->mb.ref[1] = h->fdec->ref[1];
835     h->mb.type = h->fdec->mb_type;
836
837     h->fdec->i_ref[0] = h->i_ref0;
838     h->fdec->i_ref[1] = h->i_ref1;
839     for( i = 0; i < h->i_ref0; i++ )
840         h->fdec->ref_poc[0][i] = h->fref0[i]->i_poc;
841     if( h->sh.i_type == SLICE_TYPE_B )
842     {
843         for( i = 0; i < h->i_ref1; i++ )
844             h->fdec->ref_poc[1][i] = h->fref1[i]->i_poc;
845
846         h->mb.map_col_to_list0[-1] = -1;
847         h->mb.map_col_to_list0[-2] = -2;
848         for( i = 0; i < h->fref1[0]->i_ref[0]; i++ )
849         {
850             int poc = h->fref1[0]->ref_poc[0][i];
851             h->mb.map_col_to_list0[i] = -2;
852             for( j = 0; j < h->i_ref0; j++ )
853                 if( h->fref0[j]->i_poc == poc )
854                 {
855                     h->mb.map_col_to_list0[i] = j;
856                     break;
857                 }
858         }
859     }
860     if( h->sh.i_type == SLICE_TYPE_P )
861         memset( h->mb.cache.skip, 0, X264_SCAN8_SIZE * sizeof( int8_t ) );
862 }
863
864
865 void x264_macroblock_cache_load( x264_t *h, int i_mb_x, int i_mb_y )
866 {
867     const int i_mb_4x4 = 4*(i_mb_y * h->mb.i_b4_stride + i_mb_x);
868     const int i_mb_8x8 = 2*(i_mb_y * h->mb.i_b8_stride + i_mb_x);
869
870     int i_mb_xy = i_mb_y * h->mb.i_mb_stride + i_mb_x;
871     int i_top_xy = i_mb_xy - h->mb.i_mb_stride;
872     int i_left_xy = -1;
873     int i_top_type = -1;    /* gcc warn */
874     int i_left_type= -1;
875
876     int i;
877
878     /* init index */
879     h->mb.i_mb_x = i_mb_x;
880     h->mb.i_mb_y = i_mb_y;
881     h->mb.i_mb_xy = i_mb_xy;
882     h->mb.i_b8_xy = i_mb_8x8;
883     h->mb.i_b4_xy = i_mb_4x4;
884     h->mb.i_neighbour = 0;
885
886     /* load picture pointers */
887     for( i = 0; i < 3; i++ )
888     {
889         const int w = (i == 0 ? 16 : 8);
890         const int i_stride = h->fdec->i_stride[i];
891         int   j;
892
893         h->mb.pic.i_stride[i] = i_stride;
894
895         h->mb.pic.p_fenc[i] = &h->fenc->plane[i][ w * ( i_mb_x + i_mb_y * i_stride )];
896         h->mb.pic.p_fdec[i] = &h->fdec->plane[i][ w * ( i_mb_x + i_mb_y * i_stride )];
897
898         for( j = 0; j < h->i_ref0; j++ )
899         {
900             h->mb.pic.p_fref[0][j][i==0 ? 0:i+3] = &h->fref0[j]->plane[i][ w * ( i_mb_x + i_mb_y * i_stride )];
901             h->mb.pic.p_fref[0][j][i+1] = &h->fref0[j]->filtered[i+1][ 16 * ( i_mb_x + i_mb_y * h->fdec->i_stride[0] )];
902         }
903         for( j = 0; j < h->i_ref1; j++ )
904         {
905             h->mb.pic.p_fref[1][j][i==0 ? 0:i+3] = &h->fref1[j]->plane[i][ w * ( i_mb_x + i_mb_y * i_stride )];
906             h->mb.pic.p_fref[1][j][i+1] = &h->fref1[j]->filtered[i+1][ 16 * ( i_mb_x + i_mb_y * h->fdec->i_stride[0] )];
907         }
908     }
909
910     /* load cache */
911     if( i_mb_xy >= h->sh.i_first_mb + h->mb.i_mb_stride )
912     {
913         h->mb.i_mb_type_top =
914         i_top_type= h->mb.type[i_top_xy];
915
916         h->mb.i_neighbour |= MB_TOP;
917
918         /* load intra4x4 */
919         h->mb.cache.intra4x4_pred_mode[x264_scan8[0] - 8] = h->mb.intra4x4_pred_mode[i_top_xy][0];
920         h->mb.cache.intra4x4_pred_mode[x264_scan8[1] - 8] = h->mb.intra4x4_pred_mode[i_top_xy][1];
921         h->mb.cache.intra4x4_pred_mode[x264_scan8[4] - 8] = h->mb.intra4x4_pred_mode[i_top_xy][2];
922         h->mb.cache.intra4x4_pred_mode[x264_scan8[5] - 8] = h->mb.intra4x4_pred_mode[i_top_xy][3];
923
924         /* load non_zero_count */
925         h->mb.cache.non_zero_count[x264_scan8[0] - 8] = h->mb.non_zero_count[i_top_xy][10];
926         h->mb.cache.non_zero_count[x264_scan8[1] - 8] = h->mb.non_zero_count[i_top_xy][11];
927         h->mb.cache.non_zero_count[x264_scan8[4] - 8] = h->mb.non_zero_count[i_top_xy][14];
928         h->mb.cache.non_zero_count[x264_scan8[5] - 8] = h->mb.non_zero_count[i_top_xy][15];
929
930         h->mb.cache.non_zero_count[x264_scan8[16+0] - 8] = h->mb.non_zero_count[i_top_xy][16+2];
931         h->mb.cache.non_zero_count[x264_scan8[16+1] - 8] = h->mb.non_zero_count[i_top_xy][16+3];
932
933         h->mb.cache.non_zero_count[x264_scan8[16+4+0] - 8] = h->mb.non_zero_count[i_top_xy][16+4+2];
934         h->mb.cache.non_zero_count[x264_scan8[16+4+1] - 8] = h->mb.non_zero_count[i_top_xy][16+4+3];
935     }
936     else
937     {
938         h->mb.i_mb_type_top = -1;
939         
940         /* load intra4x4 */
941         h->mb.cache.intra4x4_pred_mode[x264_scan8[0] - 8] =
942         h->mb.cache.intra4x4_pred_mode[x264_scan8[1] - 8] =
943         h->mb.cache.intra4x4_pred_mode[x264_scan8[4] - 8] =
944         h->mb.cache.intra4x4_pred_mode[x264_scan8[5] - 8] = -1;
945
946         /* load non_zero_count */
947         h->mb.cache.non_zero_count[x264_scan8[0] - 8] =
948         h->mb.cache.non_zero_count[x264_scan8[1] - 8] =
949         h->mb.cache.non_zero_count[x264_scan8[4] - 8] =
950         h->mb.cache.non_zero_count[x264_scan8[5] - 8] =
951         h->mb.cache.non_zero_count[x264_scan8[16+0] - 8] =
952         h->mb.cache.non_zero_count[x264_scan8[16+1] - 8] =
953         h->mb.cache.non_zero_count[x264_scan8[16+4+0] - 8] =
954         h->mb.cache.non_zero_count[x264_scan8[16+4+1] - 8] = 0x80;
955
956     }
957
958     if( i_mb_x > 0 && i_mb_xy > h->sh.i_first_mb )
959     {
960         i_left_xy = i_mb_xy - 1;
961         h->mb.i_mb_type_left =
962         i_left_type = h->mb.type[i_left_xy];
963
964         h->mb.i_neighbour |= MB_LEFT;
965
966         /* load intra4x4 */
967         h->mb.cache.intra4x4_pred_mode[x264_scan8[0 ] - 1] = h->mb.intra4x4_pred_mode[i_left_xy][4];
968         h->mb.cache.intra4x4_pred_mode[x264_scan8[2 ] - 1] = h->mb.intra4x4_pred_mode[i_left_xy][5];
969         h->mb.cache.intra4x4_pred_mode[x264_scan8[8 ] - 1] = h->mb.intra4x4_pred_mode[i_left_xy][6];
970         h->mb.cache.intra4x4_pred_mode[x264_scan8[10] - 1] = h->mb.intra4x4_pred_mode[i_left_xy][3];
971
972         /* load non_zero_count */
973         h->mb.cache.non_zero_count[x264_scan8[0 ] - 1] = h->mb.non_zero_count[i_left_xy][5];
974         h->mb.cache.non_zero_count[x264_scan8[2 ] - 1] = h->mb.non_zero_count[i_left_xy][7];
975         h->mb.cache.non_zero_count[x264_scan8[8 ] - 1] = h->mb.non_zero_count[i_left_xy][13];
976         h->mb.cache.non_zero_count[x264_scan8[10] - 1] = h->mb.non_zero_count[i_left_xy][15];
977
978         h->mb.cache.non_zero_count[x264_scan8[16+0] - 1] = h->mb.non_zero_count[i_left_xy][16+1];
979         h->mb.cache.non_zero_count[x264_scan8[16+2] - 1] = h->mb.non_zero_count[i_left_xy][16+3];
980
981         h->mb.cache.non_zero_count[x264_scan8[16+4+0] - 1] = h->mb.non_zero_count[i_left_xy][16+4+1];
982         h->mb.cache.non_zero_count[x264_scan8[16+4+2] - 1] = h->mb.non_zero_count[i_left_xy][16+4+3];
983     }
984     else
985     {
986         h->mb.i_mb_type_left = -1;
987
988         h->mb.cache.intra4x4_pred_mode[x264_scan8[0 ] - 1] =
989         h->mb.cache.intra4x4_pred_mode[x264_scan8[2 ] - 1] =
990         h->mb.cache.intra4x4_pred_mode[x264_scan8[8 ] - 1] =
991         h->mb.cache.intra4x4_pred_mode[x264_scan8[10] - 1] = -1;
992
993         /* load non_zero_count */
994         h->mb.cache.non_zero_count[x264_scan8[0 ] - 1] =
995         h->mb.cache.non_zero_count[x264_scan8[2 ] - 1] =
996         h->mb.cache.non_zero_count[x264_scan8[8 ] - 1] =
997         h->mb.cache.non_zero_count[x264_scan8[10] - 1] =
998         h->mb.cache.non_zero_count[x264_scan8[16+0] - 1] =
999         h->mb.cache.non_zero_count[x264_scan8[16+2] - 1] =
1000         h->mb.cache.non_zero_count[x264_scan8[16+4+0] - 1] =
1001         h->mb.cache.non_zero_count[x264_scan8[16+4+2] - 1] = 0x80;
1002     }
1003
1004     if( i_mb_x < h->sps->i_mb_width - 1 && i_top_xy + 1 >= h->sh.i_first_mb )
1005     {
1006         h->mb.i_neighbour |= MB_TOPRIGHT;
1007         h->mb.i_mb_type_topright = h->mb.type[ i_top_xy + 1 ];
1008     }
1009     else
1010         h->mb.i_mb_type_topright = -1;
1011     if( i_mb_x > 0 && i_top_xy - 1 >= h->sh.i_first_mb )
1012     {
1013         h->mb.i_neighbour |= MB_TOPLEFT;
1014         h->mb.i_mb_type_topleft = h->mb.type[ i_top_xy - 1 ];
1015     }
1016     else
1017         h->mb.i_mb_type_topleft = -1;
1018
1019     if( h->param.analyse.b_transform_8x8 )
1020     {
1021         h->mb.cache.i_neighbour_transform_size =
1022             ( i_left_type >= 0 && h->mb.mb_transform_size[i_left_xy] )
1023           + ( i_top_type  >= 0 && h->mb.mb_transform_size[i_top_xy]  );
1024     }
1025
1026     /* load ref/mv/mvd */
1027     if( h->sh.i_type != SLICE_TYPE_I )
1028     {
1029         const int s8x8 = h->mb.i_b8_stride;
1030         const int s4x4 = h->mb.i_b4_stride;
1031
1032         int i_list;
1033
1034         for( i_list = 0; i_list < (h->sh.i_type == SLICE_TYPE_B ? 2  : 1 ); i_list++ )
1035         {
1036             /*
1037             h->mb.cache.ref[i_list][x264_scan8[5 ]+1] =
1038             h->mb.cache.ref[i_list][x264_scan8[7 ]+1] =
1039             h->mb.cache.ref[i_list][x264_scan8[13]+1] = -2;
1040             */
1041
1042             if( h->mb.i_neighbour & MB_TOPLEFT )
1043             {
1044                 const int i8 = x264_scan8[0] - 1 - 1*8;
1045                 const int ir = i_mb_8x8 - s8x8 - 1;
1046                 const int iv = i_mb_4x4 - s4x4 - 1;
1047                 h->mb.cache.ref[i_list][i8]  = h->mb.ref[i_list][ir];
1048                 h->mb.cache.mv[i_list][i8][0] = h->mb.mv[i_list][iv][0];
1049                 h->mb.cache.mv[i_list][i8][1] = h->mb.mv[i_list][iv][1];
1050             }
1051             else
1052             {
1053                 const int i8 = x264_scan8[0] - 1 - 1*8;
1054                 h->mb.cache.ref[i_list][i8] = -2;
1055                 h->mb.cache.mv[i_list][i8][0] = 0;
1056                 h->mb.cache.mv[i_list][i8][1] = 0;
1057             }
1058
1059             if( h->mb.i_neighbour & MB_TOP )
1060             {
1061                 const int i8 = x264_scan8[0] - 8;
1062                 const int ir = i_mb_8x8 - s8x8;
1063                 const int iv = i_mb_4x4 - s4x4;
1064
1065                 h->mb.cache.ref[i_list][i8+0] =
1066                 h->mb.cache.ref[i_list][i8+1] = h->mb.ref[i_list][ir + 0];
1067                 h->mb.cache.ref[i_list][i8+2] =
1068                 h->mb.cache.ref[i_list][i8+3] = h->mb.ref[i_list][ir + 1];
1069
1070                 for( i = 0; i < 4; i++ )
1071                 {
1072                     h->mb.cache.mv[i_list][i8+i][0] = h->mb.mv[i_list][iv + i][0];
1073                     h->mb.cache.mv[i_list][i8+i][1] = h->mb.mv[i_list][iv + i][1];
1074                 }
1075             }
1076             else
1077             {
1078                 const int i8 = x264_scan8[0] - 8;
1079                 for( i = 0; i < 4; i++ )
1080                 {
1081                     h->mb.cache.ref[i_list][i8+i] = -2;
1082                     h->mb.cache.mv[i_list][i8+i][0] =
1083                     h->mb.cache.mv[i_list][i8+i][1] = 0;
1084                 }
1085             }
1086
1087             if( h->mb.i_neighbour & MB_TOPRIGHT )
1088             {
1089                 const int i8 = x264_scan8[0] + 4 - 1*8;
1090                 const int ir = i_mb_8x8 - s8x8 + 2;
1091                 const int iv = i_mb_4x4 - s4x4 + 4;
1092
1093                 h->mb.cache.ref[i_list][i8]  = h->mb.ref[i_list][ir];
1094                 h->mb.cache.mv[i_list][i8][0] = h->mb.mv[i_list][iv][0];
1095                 h->mb.cache.mv[i_list][i8][1] = h->mb.mv[i_list][iv][1];
1096             }
1097             else
1098             {
1099                 const int i8 = x264_scan8[0] + 4 - 1*8;
1100                 h->mb.cache.ref[i_list][i8] = -2;
1101                 h->mb.cache.mv[i_list][i8][0] = 0;
1102                 h->mb.cache.mv[i_list][i8][1] = 0;
1103             }
1104
1105             if( h->mb.i_neighbour & MB_LEFT )
1106             {
1107                 const int i8 = x264_scan8[0] - 1;
1108                 const int ir = i_mb_8x8 - 1;
1109                 const int iv = i_mb_4x4 - 1;
1110
1111                 h->mb.cache.ref[i_list][i8+0*8] =
1112                 h->mb.cache.ref[i_list][i8+1*8] = h->mb.ref[i_list][ir + 0*s8x8];
1113                 h->mb.cache.ref[i_list][i8+2*8] =
1114                 h->mb.cache.ref[i_list][i8+3*8] = h->mb.ref[i_list][ir + 1*s8x8];
1115
1116                 for( i = 0; i < 4; i++ )
1117                 {
1118                     h->mb.cache.mv[i_list][i8+i*8][0] = h->mb.mv[i_list][iv + i*s4x4][0];
1119                     h->mb.cache.mv[i_list][i8+i*8][1] = h->mb.mv[i_list][iv + i*s4x4][1];
1120                 }
1121             }
1122             else
1123             {
1124                 const int i8 = x264_scan8[0] - 1;
1125                 for( i = 0; i < 4; i++ )
1126                 {
1127                     h->mb.cache.ref[i_list][i8+i*8] = -2;
1128                     h->mb.cache.mv[i_list][i8+i*8][0] =
1129                     h->mb.cache.mv[i_list][i8+i*8][1] = 0;
1130                 }
1131             }
1132
1133             if( h->param.b_cabac )
1134             {
1135                 if( i_top_type >= 0 )
1136                 {
1137                     const int i8 = x264_scan8[0] - 8;
1138                     const int iv = i_mb_4x4 - s4x4;
1139                     for( i = 0; i < 4; i++ )
1140                     {
1141                         h->mb.cache.mvd[i_list][i8+i][0] = h->mb.mvd[i_list][iv + i][0];
1142                         h->mb.cache.mvd[i_list][i8+i][1] = h->mb.mvd[i_list][iv + i][1];
1143                     }
1144                 }
1145                 else
1146                 {
1147                     const int i8 = x264_scan8[0] - 8;
1148                     for( i = 0; i < 4; i++ )
1149                     {
1150                         h->mb.cache.mvd[i_list][i8+i][0] =
1151                         h->mb.cache.mvd[i_list][i8+i][1] = 0;
1152                     }
1153                 }
1154
1155                 if( i_left_type >= 0 )
1156                 {
1157                     const int i8 = x264_scan8[0] - 1;
1158                     const int iv = i_mb_4x4 - 1;
1159                     for( i = 0; i < 4; i++ )
1160                     {
1161                         h->mb.cache.mvd[i_list][i8+i*8][0] = h->mb.mvd[i_list][iv + i*s4x4][0];
1162                         h->mb.cache.mvd[i_list][i8+i*8][1] = h->mb.mvd[i_list][iv + i*s4x4][1];
1163                     }
1164                 }
1165                 else
1166                 {
1167                     const int i8 = x264_scan8[0] - 1;
1168                     for( i = 0; i < 4; i++ )
1169                     {
1170                         h->mb.cache.mvd[i_list][i8+i*8][0] =
1171                         h->mb.cache.mvd[i_list][i8+i*8][1] = 0;
1172                     }
1173                 }
1174             }
1175         }
1176
1177         /* load skip */
1178         if( h->sh.i_type == SLICE_TYPE_B && h->param.b_cabac )
1179         {
1180             memset( h->mb.cache.skip, 0, X264_SCAN8_SIZE * sizeof( int8_t ) );
1181             if( i_left_type >= 0 )
1182             {
1183                 h->mb.cache.skip[x264_scan8[0] - 1] = h->mb.skipbp[i_left_xy] & 0x2;
1184                 h->mb.cache.skip[x264_scan8[8] - 1] = h->mb.skipbp[i_left_xy] & 0x8;
1185             }
1186             if( i_top_type >= 0 )
1187             {
1188                 h->mb.cache.skip[x264_scan8[0] - 8] = h->mb.skipbp[i_top_xy] & 0x4;
1189                 h->mb.cache.skip[x264_scan8[4] - 8] = h->mb.skipbp[i_top_xy] & 0x8;
1190             }
1191         }
1192     }
1193
1194     h->mb.i_neighbour4[0] =
1195     h->mb.i_neighbour8[0] = (h->mb.i_neighbour & (MB_TOP|MB_LEFT|MB_TOPLEFT))
1196                             | ((h->mb.i_neighbour & MB_TOP) ? MB_TOPRIGHT : 0);
1197     h->mb.i_neighbour4[4] =
1198     h->mb.i_neighbour4[1] = MB_LEFT | ((h->mb.i_neighbour & MB_TOP) ? (MB_TOP|MB_TOPLEFT|MB_TOPRIGHT) : 0);
1199     h->mb.i_neighbour4[2] =
1200     h->mb.i_neighbour4[8] =
1201     h->mb.i_neighbour4[10] =
1202     h->mb.i_neighbour8[2] = MB_TOP|MB_TOPRIGHT | ((h->mb.i_neighbour & MB_LEFT) ? (MB_LEFT|MB_TOPLEFT) : 0);
1203     h->mb.i_neighbour4[3] =
1204     h->mb.i_neighbour4[7] =
1205     h->mb.i_neighbour4[11] =
1206     h->mb.i_neighbour4[13] =
1207     h->mb.i_neighbour4[15] =
1208     h->mb.i_neighbour8[3] = MB_LEFT|MB_TOP|MB_TOPLEFT;
1209     h->mb.i_neighbour4[5] =
1210     h->mb.i_neighbour8[1] = MB_LEFT | (h->mb.i_neighbour & MB_TOPRIGHT)
1211                             | ((h->mb.i_neighbour & MB_TOP) ? MB_TOP|MB_TOPLEFT : 0);
1212     h->mb.i_neighbour4[6] =
1213     h->mb.i_neighbour4[9] =
1214     h->mb.i_neighbour4[12] =
1215     h->mb.i_neighbour4[14] = MB_LEFT|MB_TOP|MB_TOPLEFT|MB_TOPRIGHT;
1216 }
1217
1218 void x264_macroblock_cache_save( x264_t *h )
1219 {
1220     const int i_mb_xy = h->mb.i_mb_xy;
1221     const int i_mb_type = x264_mb_type_fix[h->mb.i_type];
1222     const int s8x8 = h->mb.i_b8_stride;
1223     const int s4x4 = h->mb.i_b4_stride;
1224     const int i_mb_4x4 = h->mb.i_b4_xy;
1225     const int i_mb_8x8 = h->mb.i_b8_xy;
1226
1227     int i;
1228
1229     h->mb.type[i_mb_xy] = i_mb_type;
1230
1231     if( h->mb.i_type != I_16x16 && h->mb.i_cbp_luma == 0 && h->mb.i_cbp_chroma == 0 )
1232         h->mb.i_qp = h->mb.i_last_qp;
1233     h->mb.qp[i_mb_xy] = h->mb.i_qp;
1234
1235     h->mb.i_last_dqp = h->mb.i_qp - h->mb.i_last_qp;
1236     h->mb.i_last_qp = h->mb.i_qp;
1237
1238     /* save intra4x4 */
1239     if( i_mb_type == I_4x4 )
1240     {
1241         h->mb.intra4x4_pred_mode[i_mb_xy][0] = h->mb.cache.intra4x4_pred_mode[x264_scan8[10] ];
1242         h->mb.intra4x4_pred_mode[i_mb_xy][1] = h->mb.cache.intra4x4_pred_mode[x264_scan8[11] ];
1243         h->mb.intra4x4_pred_mode[i_mb_xy][2] = h->mb.cache.intra4x4_pred_mode[x264_scan8[14] ];
1244         h->mb.intra4x4_pred_mode[i_mb_xy][3] = h->mb.cache.intra4x4_pred_mode[x264_scan8[15] ];
1245         h->mb.intra4x4_pred_mode[i_mb_xy][4] = h->mb.cache.intra4x4_pred_mode[x264_scan8[5] ];
1246         h->mb.intra4x4_pred_mode[i_mb_xy][5] = h->mb.cache.intra4x4_pred_mode[x264_scan8[7] ];
1247         h->mb.intra4x4_pred_mode[i_mb_xy][6] = h->mb.cache.intra4x4_pred_mode[x264_scan8[13] ];
1248     }
1249     else
1250     {
1251         h->mb.intra4x4_pred_mode[i_mb_xy][0] =
1252         h->mb.intra4x4_pred_mode[i_mb_xy][1] =
1253         h->mb.intra4x4_pred_mode[i_mb_xy][2] =
1254         h->mb.intra4x4_pred_mode[i_mb_xy][3] =
1255         h->mb.intra4x4_pred_mode[i_mb_xy][4] =
1256         h->mb.intra4x4_pred_mode[i_mb_xy][5] =
1257         h->mb.intra4x4_pred_mode[i_mb_xy][6] = I_PRED_4x4_DC;
1258     }
1259
1260     if( i_mb_type == I_PCM )
1261     {
1262         h->mb.cbp[i_mb_xy] = 0x72f;   /* all set */
1263         for( i = 0; i < 16 + 2*4; i++ )
1264         {
1265             h->mb.non_zero_count[i_mb_xy][i] = 16;
1266         }
1267     }
1268     else
1269     {
1270         /* save non zero count */
1271         for( i = 0; i < 16 + 2*4; i++ )
1272         {
1273             h->mb.non_zero_count[i_mb_xy][i] = h->mb.cache.non_zero_count[x264_scan8[i]];
1274         }
1275     }
1276
1277     if( h->mb.i_cbp_luma == 0 && h->mb.i_type != I_8x8 )
1278         h->mb.b_transform_8x8 = 0;
1279     h->mb.mb_transform_size[i_mb_xy] = h->mb.b_transform_8x8;
1280
1281     if( !IS_INTRA( i_mb_type ) )
1282     {
1283         int i_list;
1284         for( i_list = 0; i_list < (h->sh.i_type == SLICE_TYPE_B ? 2  : 1 ); i_list++ )
1285         {
1286             int y,x;
1287
1288             h->mb.ref[i_list][i_mb_8x8+0+0*s8x8] = h->mb.cache.ref[i_list][x264_scan8[0]];
1289             h->mb.ref[i_list][i_mb_8x8+1+0*s8x8] = h->mb.cache.ref[i_list][x264_scan8[4]];
1290             h->mb.ref[i_list][i_mb_8x8+0+1*s8x8] = h->mb.cache.ref[i_list][x264_scan8[8]];
1291             h->mb.ref[i_list][i_mb_8x8+1+1*s8x8] = h->mb.cache.ref[i_list][x264_scan8[12]];
1292
1293             for( y = 0; y < 4; y++ )
1294             {
1295                 for( x = 0; x < 4; x++ )
1296                 {
1297                     h->mb.mv[i_list][i_mb_4x4+x+y*s4x4][0] = h->mb.cache.mv[i_list][x264_scan8[0]+x+8*y][0];
1298                     h->mb.mv[i_list][i_mb_4x4+x+y*s4x4][1] = h->mb.cache.mv[i_list][x264_scan8[0]+x+8*y][1];
1299                 }
1300             }
1301         }
1302     }
1303     else
1304     {
1305         int i_list;
1306         for( i_list = 0; i_list < (h->sh.i_type == SLICE_TYPE_B ? 2  : 1 ); i_list++ )
1307         {
1308             int y,x;
1309
1310             h->mb.ref[i_list][i_mb_8x8+0+0*s8x8] =
1311             h->mb.ref[i_list][i_mb_8x8+1+0*s8x8] =
1312             h->mb.ref[i_list][i_mb_8x8+0+1*s8x8] =
1313             h->mb.ref[i_list][i_mb_8x8+1+1*s8x8] = -1;
1314
1315             for( y = 0; y < 4; y++ )
1316             {
1317                 for( x = 0; x < 4; x++ )
1318                 {
1319                     h->mb.mv[i_list][i_mb_4x4+x+y*s4x4][0] = 0;
1320                     h->mb.mv[i_list][i_mb_4x4+x+y*s4x4][1] = 0;
1321                 }
1322             }
1323         }
1324     }
1325
1326     if( h->param.b_cabac )
1327     {
1328         if( i_mb_type == I_4x4 || i_mb_type == I_16x16 )
1329             h->mb.chroma_pred_mode[i_mb_xy] = x264_mb_pred_mode8x8c_fix[ h->mb.i_chroma_pred_mode ];
1330         else
1331             h->mb.chroma_pred_mode[i_mb_xy] = I_PRED_CHROMA_DC;
1332
1333         if( !IS_INTRA( i_mb_type ) && !IS_SKIP( i_mb_type ) && !IS_DIRECT( i_mb_type ) )
1334         {
1335             int i_list;
1336             for( i_list  = 0; i_list < 2; i_list++ )
1337             {
1338                 const int s4x4 = 4 * h->mb.i_mb_stride;
1339                 int y,x;
1340                 for( y = 0; y < 4; y++ )
1341                 {
1342                     for( x = 0; x < 4; x++ )
1343                     {
1344                         h->mb.mvd[i_list][i_mb_4x4+x+y*s4x4][0] = h->mb.cache.mvd[i_list][x264_scan8[0]+x+8*y][0];
1345                         h->mb.mvd[i_list][i_mb_4x4+x+y*s4x4][1] = h->mb.cache.mvd[i_list][x264_scan8[0]+x+8*y][1];
1346                     }
1347                 }
1348             }
1349         }
1350         else
1351         {
1352             int i_list;
1353             for( i_list  = 0; i_list < 2; i_list++ )
1354             {
1355                 const int s4x4 = 4 * h->mb.i_mb_stride;
1356                 int y,x;
1357                 for( y = 0; y < 4; y++ )
1358                 {
1359                     for( x = 0; x < 4; x++ )
1360                     {
1361                         h->mb.mvd[i_list][i_mb_4x4+x+y*s4x4][0] = 0;
1362                         h->mb.mvd[i_list][i_mb_4x4+x+y*s4x4][1] = 0;
1363                     }
1364                 }
1365             }
1366         }
1367         if( h->sh.i_type == SLICE_TYPE_B )
1368         {
1369             if( i_mb_type == B_SKIP || i_mb_type == B_DIRECT )
1370                 h->mb.skipbp[i_mb_xy] = 0xf;
1371             else if( i_mb_type == B_8x8 )
1372             {
1373                 int skipbp = 0;
1374                 for( i = 0; i < 4; i++ )
1375                     skipbp |= ( h->mb.i_sub_partition[i] == D_DIRECT_8x8 ) << i;
1376                 h->mb.skipbp[i_mb_xy] = skipbp;
1377             }
1378             else
1379                 h->mb.skipbp[i_mb_xy] = 0;
1380         }
1381     }
1382 }
1383
1384 void x264_macroblock_bipred_init( x264_t *h )
1385 {
1386     int i_ref0, i_ref1;
1387     for( i_ref0 = 0; i_ref0 < h->i_ref0; i_ref0++ )
1388     {
1389         int poc0 = h->fref0[i_ref0]->i_poc;
1390         for( i_ref1 = 0; i_ref1 < h->i_ref1; i_ref1++ )
1391         {
1392             int dist_scale_factor;
1393             int poc1 = h->fref1[i_ref1]->i_poc;
1394             int td = x264_clip3( poc1 - poc0, -128, 127 );
1395             if( td == 0 /* || pic0 is a long-term ref */ )
1396                 dist_scale_factor = 256;
1397             else
1398             {
1399                 int tb = x264_clip3( h->fdec->i_poc - poc0, -128, 127 );
1400                 int tx = (16384 + (abs(td) >> 1)) / td;
1401                 dist_scale_factor = x264_clip3( (tb * tx + 32) >> 6, -1024, 1023 );
1402             }
1403             h->mb.dist_scale_factor[i_ref0][i_ref1] = dist_scale_factor;
1404
1405             dist_scale_factor >>= 2;
1406             if( h->param.analyse.b_weighted_bipred
1407                   && dist_scale_factor >= -64
1408                   && dist_scale_factor <= 128 )
1409                 h->mb.bipred_weight[i_ref0][i_ref1] = 64 - dist_scale_factor;
1410             else
1411                 h->mb.bipred_weight[i_ref0][i_ref1] = 32;
1412         }
1413     }
1414 }