]> git.sesse.net Git - x264/blob - common/mvpred.c
Use a 16-bit buffer in hpel_filter regardless of bit depth
[x264] / common / mvpred.c
1 /*****************************************************************************
2  * mvpred.c: motion vector prediction
3  *****************************************************************************
4  * Copyright (C) 2003-2010 x264 project
5  *
6  * Authors: Loren Merritt <lorenm@u.washington.edu>
7  *          Fiona Glaser <fiona@x264.com>
8  *          Laurent Aimar <fenrir@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
23  *
24  * This program is also available under a commercial proprietary license.
25  * For more information, contact us at licensing@x264.com.
26  *****************************************************************************/
27
28 #include "common.h"
29
30 void x264_mb_predict_mv( x264_t *h, int i_list, int idx, int i_width, int16_t mvp[2] )
31 {
32     const int i8 = x264_scan8[idx];
33     const int i_ref= h->mb.cache.ref[i_list][i8];
34     int     i_refa = h->mb.cache.ref[i_list][i8 - 1];
35     int16_t *mv_a  = h->mb.cache.mv[i_list][i8 - 1];
36     int     i_refb = h->mb.cache.ref[i_list][i8 - 8];
37     int16_t *mv_b  = h->mb.cache.mv[i_list][i8 - 8];
38     int     i_refc = h->mb.cache.ref[i_list][i8 - 8 + i_width];
39     int16_t *mv_c  = h->mb.cache.mv[i_list][i8 - 8 + i_width];
40
41     if( (idx&3) >= 2 + (i_width&1) || i_refc == -2 )
42     {
43         i_refc = h->mb.cache.ref[i_list][i8 - 8 - 1];
44         mv_c   = h->mb.cache.mv[i_list][i8 - 8 - 1];
45     }
46
47     if( h->mb.i_partition == D_16x8 )
48     {
49         if( idx == 0 )
50         {
51             if( i_refb == i_ref )
52             {
53                 CP32( mvp, mv_b );
54                 return;
55             }
56         }
57         else
58         {
59             if( i_refa == i_ref )
60             {
61                 CP32( mvp, mv_a );
62                 return;
63             }
64         }
65     }
66     else if( h->mb.i_partition == D_8x16 )
67     {
68         if( idx == 0 )
69         {
70             if( i_refa == i_ref )
71             {
72                 CP32( mvp, mv_a );
73                 return;
74             }
75         }
76         else
77         {
78             if( i_refc == i_ref )
79             {
80                 CP32( mvp, mv_c );
81                 return;
82             }
83         }
84     }
85
86     int i_count = (i_refa == i_ref) + (i_refb == i_ref) + (i_refc == i_ref);
87
88     if( i_count > 1 )
89     {
90 median:
91         x264_median_mv( mvp, mv_a, mv_b, mv_c );
92     }
93     else if( i_count == 1 )
94     {
95         if( i_refa == i_ref )
96             CP32( mvp, mv_a );
97         else if( i_refb == i_ref )
98             CP32( mvp, mv_b );
99         else
100             CP32( mvp, mv_c );
101     }
102     else if( i_refb == -2 && i_refc == -2 && i_refa != -2 )
103         CP32( mvp, mv_a );
104     else
105         goto median;
106 }
107
108 void x264_mb_predict_mv_16x16( x264_t *h, int i_list, int i_ref, int16_t mvp[2] )
109 {
110     int     i_refa = h->mb.cache.ref[i_list][X264_SCAN8_0 - 1];
111     int16_t *mv_a  = h->mb.cache.mv[i_list][X264_SCAN8_0 - 1];
112     int     i_refb = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8];
113     int16_t *mv_b  = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8];
114     int     i_refc = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8 + 4];
115     int16_t *mv_c  = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8 + 4];
116     if( i_refc == -2 )
117     {
118         i_refc = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8 - 1];
119         mv_c   = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8 - 1];
120     }
121
122     int i_count = (i_refa == i_ref) + (i_refb == i_ref) + (i_refc == i_ref);
123
124     if( i_count > 1 )
125     {
126 median:
127         x264_median_mv( mvp, mv_a, mv_b, mv_c );
128     }
129     else if( i_count == 1 )
130     {
131         if( i_refa == i_ref )
132             CP32( mvp, mv_a );
133         else if( i_refb == i_ref )
134             CP32( mvp, mv_b );
135         else
136             CP32( mvp, mv_c );
137     }
138     else if( i_refb == -2 && i_refc == -2 && i_refa != -2 )
139         CP32( mvp, mv_a );
140     else
141         goto median;
142 }
143
144
145 void x264_mb_predict_mv_pskip( x264_t *h, int16_t mv[2] )
146 {
147     int     i_refa = h->mb.cache.ref[0][X264_SCAN8_0 - 1];
148     int     i_refb = h->mb.cache.ref[0][X264_SCAN8_0 - 8];
149     int16_t *mv_a  = h->mb.cache.mv[0][X264_SCAN8_0 - 1];
150     int16_t *mv_b  = h->mb.cache.mv[0][X264_SCAN8_0 - 8];
151
152     if( i_refa == -2 || i_refb == -2 ||
153         !( i_refa | M32( mv_a ) ) ||
154         !( i_refb | M32( mv_b ) ) )
155     {
156         M32( mv ) = 0;
157     }
158     else
159         x264_mb_predict_mv_16x16( h, 0, 0, mv );
160 }
161
162 static int x264_mb_predict_mv_direct16x16_temporal( x264_t *h )
163 {
164     int i_mb_4x4 = 16 * h->mb.i_mb_stride * h->mb.i_mb_y + 4 * h->mb.i_mb_x;
165     int i_mb_8x8 =  4 * h->mb.i_mb_stride * h->mb.i_mb_y + 2 * h->mb.i_mb_x;
166     const int type_col = h->fref1[0]->mb_type[h->mb.i_mb_xy];
167     const int partition_col = h->fref1[0]->mb_partition[h->mb.i_mb_xy];
168
169     x264_macroblock_cache_ref( h, 0, 0, 4, 4, 1, 0 );
170
171     h->mb.i_partition = partition_col;
172
173     if( IS_INTRA( type_col ) )
174     {
175         x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, 0 );
176         x264_macroblock_cache_mv(  h, 0, 0, 4, 4, 0, 0 );
177         x264_macroblock_cache_mv(  h, 0, 0, 4, 4, 1, 0 );
178         return 1;
179     }
180
181     /* Don't do any checks other than the ones we have to, based
182      * on the size of the colocated partitions.
183      * Depends on the enum order: D_8x8, D_16x8, D_8x16, D_16x16 */
184     int max_i8 = (D_16x16 - partition_col) + 1;
185     int step = (partition_col == D_16x8) + 1;
186     int width = 4 >> ((D_16x16 - partition_col)&1);
187     int height = 4 >> ((D_16x16 - partition_col)>>1);
188
189     for( int i8 = 0; i8 < max_i8; i8 += step )
190     {
191         int x8 = i8&1;
192         int y8 = i8>>1;
193         int i_part_8x8 = i_mb_8x8 + x8 + y8 * h->mb.i_b8_stride;
194         int i_ref1_ref = h->fref1[0]->ref[0][i_part_8x8];
195         int i_ref = (map_col_to_list0(i_ref1_ref>>h->sh.b_mbaff) << h->sh.b_mbaff) + (i_ref1_ref&h->sh.b_mbaff);
196
197         if( i_ref >= 0 )
198         {
199             int dist_scale_factor = h->mb.dist_scale_factor[i_ref][0];
200             int16_t *mv_col = h->fref1[0]->mv[0][i_mb_4x4 + 3*x8 + 3*y8 * h->mb.i_b4_stride];
201             int l0x = ( dist_scale_factor * mv_col[0] + 128 ) >> 8;
202             int l0y = ( dist_scale_factor * mv_col[1] + 128 ) >> 8;
203             if( h->param.i_threads > 1 && (l0y > h->mb.mv_max_spel[1] || l0y-mv_col[1] > h->mb.mv_max_spel[1]) )
204                 return 0;
205             x264_macroblock_cache_ref( h, 2*x8, 2*y8, width, height, 0, i_ref );
206             x264_macroblock_cache_mv( h, 2*x8, 2*y8, width, height, 0, pack16to32_mask(l0x, l0y) );
207             x264_macroblock_cache_mv( h, 2*x8, 2*y8, width, height, 1, pack16to32_mask(l0x-mv_col[0], l0y-mv_col[1]) );
208         }
209         else
210         {
211             /* the collocated ref isn't in the current list0 */
212             /* FIXME: we might still be able to use direct_8x8 on some partitions */
213             /* FIXME: with B-pyramid + extensive ref list reordering
214              *   (not currently used), we would also have to check
215              *   l1mv1 like in spatial mode */
216             return 0;
217         }
218     }
219
220     return 1;
221 }
222
223 static int x264_mb_predict_mv_direct16x16_spatial( x264_t *h )
224 {
225     int8_t ref[2];
226     ALIGNED_ARRAY_8( int16_t, mv,[2],[2] );
227     const int8_t *l1ref0 = &h->fref1[0]->ref[0][h->mb.i_b8_xy];
228     const int8_t *l1ref1 = &h->fref1[0]->ref[1][h->mb.i_b8_xy];
229     const int16_t (*l1mv[2])[2] = { (const int16_t (*)[2]) &h->fref1[0]->mv[0][h->mb.i_b4_xy],
230                                     (const int16_t (*)[2]) &h->fref1[0]->mv[1][h->mb.i_b4_xy] };
231     const int type_col = h->fref1[0]->mb_type[h->mb.i_mb_xy];
232     const int partition_col = h->fref1[0]->mb_partition[h->mb.i_mb_xy];
233
234     h->mb.i_partition = partition_col;
235
236     for( int i_list = 0; i_list < 2; i_list++ )
237     {
238         int     i_refa = h->mb.cache.ref[i_list][X264_SCAN8_0 - 1];
239         int16_t *mv_a  = h->mb.cache.mv[i_list][X264_SCAN8_0 - 1];
240         int     i_refb = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8];
241         int16_t *mv_b  = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8];
242         int     i_refc = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8 + 4];
243         int16_t *mv_c  = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8 + 4];
244         if( i_refc == -2 )
245         {
246             i_refc = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8 - 1];
247             mv_c   = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8 - 1];
248         }
249
250         int i_ref = X264_MIN3( (unsigned)i_refa, (unsigned)i_refb, (unsigned)i_refc );
251         if( i_ref < 0 )
252         {
253             i_ref = -1;
254             M32( mv[i_list] ) = 0;
255         }
256         else
257         {
258             /* Same as x264_mb_predict_mv_16x16, but simplified to eliminate cases
259              * not relevant to spatial direct. */
260             int i_count = (i_refa == i_ref) + (i_refb == i_ref) + (i_refc == i_ref);
261
262             if( i_count > 1 )
263                 x264_median_mv( mv[i_list], mv_a, mv_b, mv_c );
264             else
265             {
266                 if( i_refa == i_ref )
267                     CP32( mv[i_list], mv_a );
268                 else if( i_refb == i_ref )
269                     CP32( mv[i_list], mv_b );
270                 else
271                     CP32( mv[i_list], mv_c );
272             }
273         }
274
275         x264_macroblock_cache_ref( h, 0, 0, 4, 4, i_list, i_ref );
276         x264_macroblock_cache_mv_ptr( h, 0, 0, 4, 4, i_list, mv[i_list] );
277         ref[i_list] = i_ref;
278     }
279
280     if( (M16( ref ) & 0x8080) == 0x8080 ) /* if( ref[0] < 0 && ref[1] < 0 ) */
281     {
282         x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, 0 );
283         x264_macroblock_cache_ref( h, 0, 0, 4, 4, 1, 0 );
284         return 1;
285     }
286
287     if( h->param.i_threads > 1
288         && ( mv[0][1] > h->mb.mv_max_spel[1]
289           || mv[1][1] > h->mb.mv_max_spel[1] ) )
290     {
291 #if 0
292         fprintf(stderr, "direct_spatial: (%d,%d) (%d,%d) > %d \n",
293                 mv[0][0], mv[0][1], mv[1][0], mv[1][1],
294                 h->mb.mv_max_spel[1]);
295 #endif
296         return 0;
297     }
298
299     if( !M64( mv ) || IS_INTRA( type_col ) || (ref[0]&&ref[1]) )
300         return 1;
301
302     /* Don't do any checks other than the ones we have to, based
303      * on the size of the colocated partitions.
304      * Depends on the enum order: D_8x8, D_16x8, D_8x16, D_16x16 */
305     int max_i8 = (D_16x16 - partition_col) + 1;
306     int step = (partition_col == D_16x8) + 1;
307     int width = 4 >> ((D_16x16 - partition_col)&1);
308     int height = 4 >> ((D_16x16 - partition_col)>>1);
309
310     /* col_zero_flag */
311     for( int i8 = 0; i8 < max_i8; i8 += step )
312     {
313         const int x8 = i8&1;
314         const int y8 = i8>>1;
315         const int o8 = x8 + y8 * h->mb.i_b8_stride;
316         const int o4 = 3*(x8 + y8 * h->mb.i_b4_stride);
317         int idx;
318         if( l1ref0[o8] == 0 )
319             idx = 0;
320         else if( l1ref0[o8] < 0 && l1ref1[o8] == 0 )
321             idx = 1;
322         else
323             continue;
324
325         if( abs( l1mv[idx][o4][0] ) <= 1 && abs( l1mv[idx][o4][1] ) <= 1 )
326         {
327             if( ref[0] == 0 ) x264_macroblock_cache_mv( h, 2*x8, 2*y8, width, height, 0, 0 );
328             if( ref[1] == 0 ) x264_macroblock_cache_mv( h, 2*x8, 2*y8, width, height, 1, 0 );
329         }
330     }
331
332     return 1;
333 }
334
335 int x264_mb_predict_mv_direct16x16( x264_t *h, int *b_changed )
336 {
337     int b_available;
338     if( h->param.analyse.i_direct_mv_pred == X264_DIRECT_PRED_NONE )
339         return 0;
340     else if( h->sh.b_direct_spatial_mv_pred )
341         b_available = x264_mb_predict_mv_direct16x16_spatial( h );
342     else
343         b_available = x264_mb_predict_mv_direct16x16_temporal( h );
344
345     if( b_changed != NULL && b_available )
346     {
347         int changed;
348
349         changed  = M32( h->mb.cache.direct_mv[0][0] ) ^ M32( h->mb.cache.mv[0][x264_scan8[0]] );
350         changed |= M32( h->mb.cache.direct_mv[1][0] ) ^ M32( h->mb.cache.mv[1][x264_scan8[0]] );
351         changed |= h->mb.cache.direct_ref[0][0] ^ h->mb.cache.ref[0][x264_scan8[0]];
352         changed |= h->mb.cache.direct_ref[1][0] ^ h->mb.cache.ref[1][x264_scan8[0]];
353         if( !changed && h->mb.i_partition != D_16x16 )
354         {
355             changed |= M32( h->mb.cache.direct_mv[0][3] ) ^ M32( h->mb.cache.mv[0][x264_scan8[12]] );
356             changed |= M32( h->mb.cache.direct_mv[1][3] ) ^ M32( h->mb.cache.mv[1][x264_scan8[12]] );
357             changed |= h->mb.cache.direct_ref[0][3] ^ h->mb.cache.ref[0][x264_scan8[12]];
358             changed |= h->mb.cache.direct_ref[1][3] ^ h->mb.cache.ref[1][x264_scan8[12]];
359         }
360         if( !changed && h->mb.i_partition == D_8x8 )
361         {
362             changed |= M32( h->mb.cache.direct_mv[0][1] ) ^ M32( h->mb.cache.mv[0][x264_scan8[4]] );
363             changed |= M32( h->mb.cache.direct_mv[1][1] ) ^ M32( h->mb.cache.mv[1][x264_scan8[4]] );
364             changed |= M32( h->mb.cache.direct_mv[0][2] ) ^ M32( h->mb.cache.mv[0][x264_scan8[8]] );
365             changed |= M32( h->mb.cache.direct_mv[1][2] ) ^ M32( h->mb.cache.mv[1][x264_scan8[8]] );
366             changed |= h->mb.cache.direct_ref[0][1] ^ h->mb.cache.ref[0][x264_scan8[4]];
367             changed |= h->mb.cache.direct_ref[1][1] ^ h->mb.cache.ref[1][x264_scan8[4]];
368             changed |= h->mb.cache.direct_ref[0][2] ^ h->mb.cache.ref[0][x264_scan8[8]];
369             changed |= h->mb.cache.direct_ref[1][2] ^ h->mb.cache.ref[1][x264_scan8[8]];
370         }
371         *b_changed = changed;
372         if( !changed )
373             return b_available;
374     }
375
376     /* cache ref & mv */
377     if( b_available )
378         for( int l = 0; l < 2; l++ )
379         {
380             CP32( h->mb.cache.direct_mv[l][0], h->mb.cache.mv[l][x264_scan8[ 0]] );
381             CP32( h->mb.cache.direct_mv[l][1], h->mb.cache.mv[l][x264_scan8[ 4]] );
382             CP32( h->mb.cache.direct_mv[l][2], h->mb.cache.mv[l][x264_scan8[ 8]] );
383             CP32( h->mb.cache.direct_mv[l][3], h->mb.cache.mv[l][x264_scan8[12]] );
384             h->mb.cache.direct_ref[l][0] = h->mb.cache.ref[l][x264_scan8[ 0]];
385             h->mb.cache.direct_ref[l][1] = h->mb.cache.ref[l][x264_scan8[ 4]];
386             h->mb.cache.direct_ref[l][2] = h->mb.cache.ref[l][x264_scan8[ 8]];
387             h->mb.cache.direct_ref[l][3] = h->mb.cache.ref[l][x264_scan8[12]];
388             h->mb.cache.direct_partition = h->mb.i_partition;
389         }
390
391     return b_available;
392 }
393
394 /* This just improves encoder performance, it's not part of the spec */
395 void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int16_t mvc[9][2], int *i_mvc )
396 {
397     int16_t (*mvr)[2] = h->mb.mvr[i_list][i_ref];
398     int i = 0;
399
400 #define SET_MVP(mvp) \
401     { \
402         CP32( mvc[i], mvp ); \
403         i++; \
404     }
405
406     /* b_direct */
407     if( h->sh.i_type == SLICE_TYPE_B
408         && h->mb.cache.ref[i_list][x264_scan8[12]] == i_ref )
409     {
410         SET_MVP( h->mb.cache.mv[i_list][x264_scan8[12]] );
411     }
412
413     if( i_ref == 0 && h->frames.b_have_lowres )
414     {
415         int idx = i_list ? h->fref1[0]->i_frame-h->fenc->i_frame-1
416                          : h->fenc->i_frame-h->fref0[0]->i_frame-1;
417         if( idx <= h->param.i_bframe )
418         {
419             int16_t (*lowres_mv)[2] = h->fenc->lowres_mvs[i_list][idx];
420             if( lowres_mv[0][0] != 0x7fff )
421             {
422                 M32( mvc[i] ) = (M32( lowres_mv[h->mb.i_mb_xy] )*2)&0xfffeffff;
423                 i++;
424             }
425         }
426     }
427
428     /* spatial predictors */
429     SET_MVP( mvr[h->mb.i_mb_left_xy] );
430     SET_MVP( mvr[h->mb.i_mb_top_xy] );
431     SET_MVP( mvr[h->mb.i_mb_topleft_xy] );
432     SET_MVP( mvr[h->mb.i_mb_topright_xy] );
433 #undef SET_MVP
434
435     /* temporal predictors */
436     if( h->fref0[0]->i_ref[0] > 0 )
437     {
438         x264_frame_t *l0 = h->fref0[0];
439         x264_frame_t **fref = i_list ? h->fref1 : h->fref0;
440         int field = h->mb.i_mb_y&1;
441         int curpoc = h->fdec->i_poc + field*h->sh.i_delta_poc_bottom;
442         int refpoc = fref[i_ref>>h->sh.b_mbaff]->i_poc;
443         if( h->sh.b_mbaff && field^(i_ref&1) )
444             refpoc += h->sh.i_delta_poc_bottom;
445
446 #define SET_TMVP( dx, dy ) \
447         { \
448             int mb_index = h->mb.i_mb_xy + dx + dy*h->mb.i_mb_stride; \
449             int scale = (curpoc - refpoc) * l0->inv_ref_poc[h->mb.b_interlaced&field]; \
450             mvc[i][0] = (l0->mv16x16[mb_index][0]*scale + 128) >> 8; \
451             mvc[i][1] = (l0->mv16x16[mb_index][1]*scale + 128) >> 8; \
452             i++; \
453         }
454
455         SET_TMVP(0,0);
456         if( h->mb.i_mb_x < h->mb.i_mb_width-1 )
457             SET_TMVP(1,0);
458         if( h->mb.i_mb_y < h->mb.i_mb_height-1 )
459             SET_TMVP(0,1);
460 #undef SET_TMVP
461     }
462
463     *i_mvc = i;
464 }