]> git.sesse.net Git - vlc/blob - plugins/motion/vdec_motion_common.c
102323af1701e842f4147c75546f4e3c7d26d4ba
[vlc] / plugins / motion / vdec_motion_common.c
1 /*****************************************************************************
2  * vdec_motion_common.c : common motion compensation routines common
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  * $Id: vdec_motion_common.c,v 1.9 2001/07/17 09:48:07 massiot Exp $
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *          Jean-Marc Dressler <polux@via.ecp.fr>
9  *          Michel Lespinasse <walken@via.ecp.fr>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 /* MODULE_NAME defined in Makefile together with -DBUILTIN */
27 #ifdef BUILTIN
28 #   include "modules_inner.h"
29 #else
30 #   define _M( foo ) foo
31 #endif
32
33 /*****************************************************************************
34  * Preamble
35  *****************************************************************************/
36 #include "defs.h"
37
38 #include "config.h"
39 #include "common.h"
40 #include "threads.h"
41 #include "mtime.h"
42
43 #include "intf_msg.h"
44
45 #include "video.h"
46
47 #include "vdec_ext-plugins.h"
48
49 #include "modules.h"
50 #include "modules_export.h"
51
52 extern int _M( motion_Probe )( probedata_t *p_data );
53
54 static void vdec_MotionFieldField420  ( macroblock_t * p_mb );
55 static void vdec_MotionFieldField422  ( macroblock_t * p_mb );
56 static void vdec_MotionFieldField444  ( macroblock_t * p_mb );
57 static void vdec_MotionField16x8420   ( macroblock_t * p_mb );
58 static void vdec_MotionField16x8422   ( macroblock_t * p_mb );
59 static void vdec_MotionField16x8444   ( macroblock_t * p_mb );
60 static void vdec_MotionFieldDMV420    ( macroblock_t * p_mb );
61 static void vdec_MotionFieldDMV422    ( macroblock_t * p_mb );
62 static void vdec_MotionFieldDMV444    ( macroblock_t * p_mb );
63 static void vdec_MotionFrameFrame420  ( macroblock_t * p_mb );
64 static void vdec_MotionFrameFrame422  ( macroblock_t * p_mb );
65 static void vdec_MotionFrameFrame444  ( macroblock_t * p_mb );
66 static void vdec_MotionFrameField420  ( macroblock_t * p_mb );
67 static void vdec_MotionFrameField422  ( macroblock_t * p_mb );
68 static void vdec_MotionFrameField444  ( macroblock_t * p_mb );
69 static void vdec_MotionFrameDMV420    ( macroblock_t * p_mb );
70 static void vdec_MotionFrameDMV422    ( macroblock_t * p_mb );
71 static void vdec_MotionFrameDMV444    ( macroblock_t * p_mb );
72
73 /*****************************************************************************
74  * Functions exported as capabilities. They are declared as static so that
75  * we don't pollute the namespace too much.
76  *****************************************************************************/
77 void _M( motion_getfunctions )( function_list_t * p_function_list )
78 {
79     p_function_list->pf_probe = _M( motion_Probe );
80
81 #define list p_function_list->functions.motion
82 #define motion_functions( yuv ) \
83     list.pf_field_field_##yuv = vdec_MotionFieldField##yuv; \
84     list.pf_field_16x8_##yuv  = vdec_MotionField16x8##yuv;  \
85     list.pf_field_dmv_##yuv   = vdec_MotionFieldDMV##yuv;   \
86     list.pf_frame_field_##yuv = vdec_MotionFrameField##yuv; \
87     list.pf_frame_frame_##yuv = vdec_MotionFrameFrame##yuv; \
88     list.pf_frame_dmv_##yuv   = vdec_MotionFrameDMV##yuv;
89     motion_functions( 420 )
90     motion_functions( 422 )
91     motion_functions( 444 )
92 #undef motion_functions
93 #undef list
94
95     return;
96 }
97
98 #define __MotionComponents(width,height)                \
99 void _M( MotionComponent_x_y_copy_##width##_##height )();    \
100 void _M( MotionComponent_X_y_copy_##width##_##height )();    \
101 void _M( MotionComponent_x_Y_copy_##width##_##height )();    \
102 void _M( MotionComponent_X_Y_copy_##width##_##height )();    \
103 void _M( MotionComponent_x_y_avg_##width##_##height )();     \
104 void _M( MotionComponent_X_y_avg_##width##_##height )();     \
105 void _M( MotionComponent_x_Y_avg_##width##_##height )();     \
106 void _M( MotionComponent_X_Y_avg_##width##_##height )();
107
108 __MotionComponents (16,16)       /* 444, 422, 420 */
109 __MotionComponents (16,8)        /* 444, 422, 420 */
110 __MotionComponents (8,8)         /* 422, 420 */
111 __MotionComponents (8,4)         /* 420 */
112 #if 0
113 __MotionComponents (8,16)        /* 422 */
114 #endif
115
116 #define ___callTheRightOne(width,height)                                     \
117     if ((i_width == width) && (i_height == height))                          \
118     {                                                                        \
119         if (!b_average)                                                      \
120         {                                                                    \
121             switch (i_select)                                                \
122             {                                                                \
123             case 0:                                                          \
124                 _M( MotionComponent_x_y_copy_##width##_##height )(p_src,     \
125                                                           p_dest, i_stride); \
126                 break;                                                       \
127             case 1:                                                          \
128                 _M( MotionComponent_X_y_copy_##width##_##height )(p_src,     \
129                                                           p_dest, i_stride); \
130                 break;                                                       \
131             case 2:                                                          \
132                 _M( MotionComponent_x_Y_copy_##width##_##height )(p_src,     \
133                                                           p_dest, i_stride); \
134                 break;                                                       \
135             case 3:                                                          \
136                 _M( MotionComponent_X_Y_copy_##width##_##height )(p_src,     \
137                                                           p_dest, i_stride); \
138                 break;                                                       \
139             }                                                                \
140         }                                                                    \
141         else                                                                 \
142         {                                                                    \
143             switch (i_select)                                                \
144             {                                                                \
145             case 0:                                                          \
146                 _M( MotionComponent_x_y_avg_##width##_##height )(p_src,      \
147                                                           p_dest, i_stride); \
148                 break;                                                       \
149             case 1:                                                          \
150                 _M( MotionComponent_X_y_avg_##width##_##height )(p_src,      \
151                                                           p_dest, i_stride); \
152                 break;                                                       \
153             case 2:                                                          \
154                 _M( MotionComponent_x_Y_avg_##width##_##height )(p_src,      \
155                                                           p_dest, i_stride); \
156                 break;                                                       \
157             case 3:                                                          \
158                 _M( MotionComponent_X_Y_avg_##width##_##height )(p_src,      \
159                                                           p_dest, i_stride); \
160                 break;                                                       \
161             }                                                                \
162         }                                                                    \
163     }
164
165 /*****************************************************************************
166  * vdec_MotionComponent : last stage of motion compensation
167  *****************************************************************************/
168 static __inline__ void MotionComponent(
169                     yuv_data_t * p_src,     /* source block */
170                     yuv_data_t * p_dest,    /* dest block */
171                     int i_width,            /* (explicit) width of block */
172                     int i_height,           /* (explicit) height of block */
173                     int i_stride,           /* number of coeffs to jump
174                                              * between each predicted line */
175                     int i_select,           /* half-pel vectors */
176                     boolean_t b_average     /* (explicit) averaging of several
177                                              * predictions */ )
178 {
179     ___callTheRightOne (16,16)
180     ___callTheRightOne (16,8)
181     ___callTheRightOne (8,8)
182     ___callTheRightOne (8,4)
183 #if 0
184     ___callTheRightOne (8,16)
185 #endif
186 }
187
188 /*****************************************************************************
189  * Motion420 : motion compensation for a 4:2:0 macroblock
190  *****************************************************************************/
191 static __inline__ void Motion420(
192                     macroblock_t * p_mb,        /* destination macroblock */
193                     picture_t * p_source,       /* source picture */
194                     boolean_t b_source_field,   /* source field */
195                     boolean_t b_dest_field,     /* destination field */
196                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
197                                                  * in half pels */
198                     int i_l_stride,             /* number of coeffs to jump to
199                                                  * go to the next predicted
200                                                  * line */
201                     int i_c_stride,
202                     int i_height,               /* height of the block to
203                                                  * predict, in luminance
204                                                  * (explicit) */
205                     int i_offset,               /* position of the first
206                                                  * predicted line (explicit) */
207                     boolean_t b_average         /* (explicit) averaging of
208                                                  * several predictions */ )
209 {
210     /* Temporary variables to avoid recalculating things twice */
211     int     i_source_offset, i_dest_offset, i_c_height, i_c_select;
212
213     i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
214                        + (p_mb->i_motion_l_y + i_offset
215                          + b_source_field)
216                        * p_mb->p_picture->i_width
217                        + (i_mv_y >> 1) * i_l_stride;
218
219     if( i_source_offset >= p_source->i_size )
220     {
221         intf_WarnMsg( 2, "Bad motion vector (lum)" );
222         return;
223     }
224
225     /* Luminance */
226     MotionComponent( /* source */
227                      p_source->p_y + i_source_offset,
228                      /* destination */
229                      p_mb->p_picture->p_y
230                        + (p_mb->i_l_x)
231                        + (p_mb->i_motion_l_y + b_dest_field + i_offset)
232                          * p_mb->p_picture->i_width,
233                      /* prediction width and height */
234                      16, i_height,
235                      /* stride */
236                      i_l_stride,
237                      /* select */
238                      ((i_mv_y & 1) << 1) | (i_mv_x & 1),
239                      b_average );
240
241     i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
242                         + (p_mb->i_motion_c_y + (i_offset >> 1)
243                            + b_source_field)
244                           * p_mb->p_picture->i_chroma_width
245                         + ((i_mv_y/2) >> 1) * i_c_stride;
246
247     if( i_source_offset >= p_source->i_chroma_size )
248     {
249         intf_WarnMsg( 2, "Bad motion vector (chroma)" );
250         return;
251     }
252
253     i_dest_offset = (p_mb->i_c_x)
254                       + (p_mb->i_motion_c_y + b_dest_field
255                           + (i_offset >> 1))
256                         * p_mb->p_picture->i_chroma_width;
257     i_c_height = i_height >> 1;
258     i_c_select = (((i_mv_y/2) & 1) << 1) | ((i_mv_x/2) & 1);
259
260     /* Chrominance Cr */
261     MotionComponent( p_source->p_u
262                        + i_source_offset,
263                      p_mb->p_picture->p_u
264                        + i_dest_offset,
265                      8, i_c_height, i_c_stride,
266                      i_c_select, b_average );
267
268     /* Chrominance Cb */
269     MotionComponent( p_source->p_v
270                        + i_source_offset,
271                      p_mb->p_picture->p_v
272                        + i_dest_offset,
273                      8, i_c_height, i_c_stride,
274                      i_c_select, b_average );
275 }
276
277 /*****************************************************************************
278  * Motion422 : motion compensation for a 4:2:2 macroblock
279  *****************************************************************************/
280 static __inline__ void Motion422(
281                     macroblock_t * p_mb,        /* destination macroblock */
282                     picture_t * p_source,       /* source picture */
283                     boolean_t b_source_field,   /* source field */
284                     boolean_t b_dest_field,     /* destination field */
285                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
286                                                  * in half pels */
287                     int i_l_stride,             /* number of coeffs to jump to
288                                                  * go to the next predicted
289                                                  * line */
290                     int i_c_stride,
291                     int i_height,               /* height of the block to
292                                                  * predict, in luminance
293                                                  * (explicit) */
294                     int i_offset,               /* position of the first
295                                                  * predicted line (explicit) */
296                     boolean_t b_average         /* (explicit) averaging of
297                                                  * several predictions */ )
298 {
299 #if 0
300     int     i_source_offset, i_dest_offset, i_c_select;
301
302     /* Luminance */
303     MotionComponent( /* source */
304                      p_source->p_y
305                        + (p_mb->i_l_x + (i_mv_x >> 1))
306                        + (p_mb->i_motion_l_y + i_offset
307                           + b_source_field)
308                        * p_mb->p_picture->i_width
309                        + (i_mv_y >> 1) * p_mb->i_l_stride,
310                      /* destination */
311                      p_mb->p_picture->p_y
312                        + (p_mb->i_l_x)
313                        + (p_mb->i_motion_l_y + b_dest_field)
314                          * p_mb->p_picture->i_width,
315                      /* prediction width and height */
316                      16, i_height,
317                      /* stride */
318                      i_l_stride,
319                      /* select */
320                      ((i_mv_y & 1) << 1) | (i_mv_x & 1),
321                      b_average );
322
323     i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
324                         + (p_mb->i_motion_c_y + i_offset
325                            + b_source_field)
326                         * p_mb->p_picture->i_chroma_width
327                         + (i_mv_y) >> 1) * p_mb->i_c_stride;
328     i_dest_offset = (p_mb->i_c_x)
329                       + (p_mb->i_motion_c_y + b_dest_field)
330                         * p_mb->p_picture->i_chroma_width;
331     i_c_select = ((i_mv_y & 1) << 1) | ((i_mv_x/2) & 1);
332
333     /* Chrominance Cr */
334     MotionComponent( p_source->p_u
335                        + i_source_offset,
336                      p_mb->p_picture->p_u
337                        + i_dest_offset,
338                      8, i_height, i_c_stride,
339                      i_c_select, b_average );
340
341     /* Chrominance Cb */
342     MotionComponent( p_source->p_v
343                        + i_source_offset,
344                      p_mb->p_picture->p_u
345                        + i_dest_offset,
346                      8, i_height, i_c_stride,
347                      i_c_select, b_average );
348 #endif
349 }
350
351 /*****************************************************************************
352  * Motion444 : motion compensation for a 4:4:4 macroblock
353  *****************************************************************************/
354 static __inline__ void Motion444(
355                     macroblock_t * p_mb,        /* destination macroblock */
356                     picture_t * p_source,       /* source picture */
357                     boolean_t b_source_field,   /* source field */
358                     boolean_t b_dest_field,     /* destination field */
359                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
360                                                  * in half pels */
361                     int i_l_stride,             /* number of coeffs to jump to
362                                                  * go to the next predicted
363                                                  * line */
364                     int i_c_stride,
365                     int i_height,               /* height of the block to
366                                                  * predict, in luminance
367                                                  * (explicit) */
368                     int i_offset,               /* position of the first
369                                                  * predicted line (explicit) */
370                     boolean_t b_average         /* (explicit) averaging of
371                                                  * several predictions */ )
372 {
373 #if 0
374     int     i_source_offset, i_dest_offset, i_select;
375
376     i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
377                         + (p_mb->i_motion_l_y + i_offset
378                            + b_source_field)
379                         * p_mb->p_picture->i_width
380                         + (i_mv_y >> 1) * p_mb->i_l_stride;
381     i_dest_offset = (p_mb->i_l_x)
382                       + (p_mb->i_motion_l_y + b_dest_field)
383                         * p_mb->p_picture->i_width;
384     i_select = ((i_mv_y & 1) << 1) | (i_mv_x & 1);
385
386
387     /* Luminance */
388     MotionComponent( p_source->p_y
389                        + i_source_offset,
390                      p_mb->p_picture->p_y
391                        + i_dest_offset,
392                      16, i_height, i_l_stride,
393                      i_select, b_average );
394
395     /* Chrominance Cr */
396     MotionComponent( p_source->p_u
397                        + i_source_offset,
398                      p_mb->p_picture->p_u
399                        + i_dest_offset,
400                      16, i_height, i_l_stride,
401                      i_select, b_average );
402
403     /* Chrominance Cb */
404     MotionComponent( p_source->p_v
405                        + i_source_offset,
406                      p_mb->p_picture->p_v
407                        + i_dest_offset,
408                      16, i_height, i_l_stride,
409                      i_select, b_average );
410 #endif
411 }
412
413 /*****************************************************************************
414  * vdec_MotionFieldField : motion compensation for field motion type (field)
415  *****************************************************************************/
416 #define FIELDFIELD( MOTION )                                            \
417 {                                                                       \
418     picture_t *     p_pred;                                             \
419                                                                         \
420     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
421     {                                                                   \
422         if( p_mb->b_P_second                                            \
423              && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
424             p_pred = p_mb->p_picture;                                   \
425         else                                                            \
426             p_pred = p_mb->p_forward;                                   \
427                                                                         \
428         MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0],             \
429                 p_mb->b_motion_field,                                   \
430                 p_mb->pppi_motion_vectors[0][0][0],                     \
431                 p_mb->pppi_motion_vectors[0][0][1],                     \
432                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
433                                                                         \
434         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
435         {                                                               \
436             MOTION( p_mb, p_mb->p_backward,                             \
437                     p_mb->ppi_field_select[0][1],                       \
438                     p_mb->b_motion_field,                               \
439                     p_mb->pppi_motion_vectors[0][1][0],                 \
440                     p_mb->pppi_motion_vectors[0][1][1],                 \
441                     p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );     \
442         }                                                               \
443     }                                                                   \
444                                                                         \
445     else /* MB_MOTION_BACKWARD */                                       \
446     {                                                                   \
447         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1],   \
448                 p_mb->b_motion_field,                                   \
449                 p_mb->pppi_motion_vectors[0][1][0],                     \
450                 p_mb->pppi_motion_vectors[0][1][1],                     \
451                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
452     }                                                                   \
453 }
454
455 static void vdec_MotionFieldField420( macroblock_t * p_mb )
456 {
457     FIELDFIELD( Motion420 )
458 }
459
460 static void vdec_MotionFieldField422( macroblock_t * p_mb )
461 {
462     //FIELDFIELD( Motion422 )
463 }
464
465 static void vdec_MotionFieldField444( macroblock_t * p_mb )
466 {
467     //FIELDFIELD( Motion444 )
468 }
469
470 /*****************************************************************************
471  * vdec_MotionField16x8XXX: motion compensation for 16x8 motion type (field)
472  *****************************************************************************/
473 #define FIELD16X8( MOTION )                                             \
474 {                                                                       \
475     picture_t *     p_pred;                                             \
476                                                                         \
477     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
478     {                                                                   \
479         if( p_mb->b_P_second                                            \
480              && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
481             p_pred = p_mb->p_picture;                                   \
482         else                                                            \
483             p_pred = p_mb->p_forward;                                   \
484                                                                         \
485         MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0],             \
486                 p_mb->b_motion_field,                                   \
487                 p_mb->pppi_motion_vectors[0][0][0],                     \
488                 p_mb->pppi_motion_vectors[0][0][1],                     \
489                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 );          \
490                                                                         \
491         if( p_mb->b_P_second                                            \
492              && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\
493             p_pred = p_mb->p_picture;                                   \
494         else                                                            \
495             p_pred = p_mb->p_forward;                                   \
496                                                                         \
497         MOTION( p_mb, p_pred, p_mb->ppi_field_select[1][0],             \
498                 p_mb->b_motion_field,                                   \
499                 p_mb->pppi_motion_vectors[1][0][0],                     \
500                 p_mb->pppi_motion_vectors[1][0][1],                     \
501                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 );          \
502                                                                         \
503         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
504         {                                                               \
505             MOTION( p_mb, p_mb->p_backward,                             \
506                     p_mb->ppi_field_select[0][1],                       \
507                     p_mb->b_motion_field,                               \
508                     p_mb->pppi_motion_vectors[0][1][0],                 \
509                     p_mb->pppi_motion_vectors[0][1][1],                 \
510                     p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 1 );      \
511                                                                         \
512             MOTION( p_mb, p_mb->p_backward,                             \
513                     p_mb->ppi_field_select[1][1],                       \
514                     p_mb->b_motion_field,                               \
515                     p_mb->pppi_motion_vectors[1][1][0],                 \
516                     p_mb->pppi_motion_vectors[1][1][1],                 \
517                     p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 1 );      \
518         }                                                               \
519     }                                                                   \
520                                                                         \
521     else /* MB_MOTION_BACKWARD */                                       \
522     {                                                                   \
523         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1],   \
524                 p_mb->b_motion_field,                                   \
525                 p_mb->pppi_motion_vectors[0][1][0],                     \
526                 p_mb->pppi_motion_vectors[0][1][1],                     \
527                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 );          \
528                                                                         \
529         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1],   \
530                 p_mb->b_motion_field,                                   \
531                 p_mb->pppi_motion_vectors[1][1][0],                     \
532                 p_mb->pppi_motion_vectors[1][1][1],                     \
533                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 );          \
534     }                                                                   \
535 }
536
537 static void vdec_MotionField16x8420( macroblock_t * p_mb )
538 {
539     FIELD16X8( Motion420 )
540 }
541
542 static void vdec_MotionField16x8422( macroblock_t * p_mb )
543 {
544     //FIELD16X8( Motion422 )
545 }
546
547 static void vdec_MotionField16x8444( macroblock_t * p_mb )
548 {
549     //FIELD16X8( Motion444 )
550 }
551
552 /*****************************************************************************
553  * vdec_MotionFieldDMVXXX : motion compensation for dmv motion type (field)
554  *****************************************************************************/
555 #define FIELDDMV( MOTION )                                              \
556 {                                                                       \
557     /* This is necessarily a MOTION_FORWARD only macroblock, in a P     \
558      * picture. */                                                      \
559     picture_t *     p_pred;                                             \
560                                                                         \
561     /* predict from field of same parity */                             \
562     MOTION( p_mb, p_mb->p_forward,                                      \
563             p_mb->b_motion_field, p_mb->b_motion_field,                 \
564             p_mb->pppi_motion_vectors[0][0][0],                         \
565             p_mb->pppi_motion_vectors[0][0][1],                         \
566             p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );             \
567                                                                         \
568     if( p_mb->b_P_second )                                              \
569         p_pred = p_mb->p_picture;                                       \
570     else                                                                \
571         p_pred = p_mb->p_forward;                                       \
572                                                                         \
573     /* predict from field of opposite parity */                         \
574     MOTION( p_mb, p_pred, !p_mb->b_motion_field, p_mb->b_motion_field,  \
575             p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1],                   \
576             p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );             \
577 } /* FIELDDMV */
578
579 static void vdec_MotionFieldDMV420( macroblock_t * p_mb )
580 {
581     FIELDDMV( Motion420 )
582 }
583
584 static void vdec_MotionFieldDMV422( macroblock_t * p_mb )
585 {
586     //FIELDDMV( Motion422 )
587 }
588
589 static void vdec_MotionFieldDMV444( macroblock_t * p_mb )
590 {
591     //FIELDDMV( Motion444 )
592 }
593
594 /*****************************************************************************
595  * vdec_MotionFrameFrameXXX?? : motion compensation for frame motion type (frame)
596  *****************************************************************************/
597 #define FRAMEFRAME( MOTION )                                            \
598 {                                                                       \
599     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
600     {                                                                   \
601         MOTION( p_mb, p_mb->p_forward, 0, 0,                            \
602                 p_mb->pppi_motion_vectors[0][0][0],                     \
603                 p_mb->pppi_motion_vectors[0][0][1],                     \
604                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
605                                                                         \
606         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
607         {                                                               \
608             MOTION( p_mb, p_mb->p_backward, 0, 0,                       \
609                     p_mb->pppi_motion_vectors[0][1][0],                 \
610                     p_mb->pppi_motion_vectors[0][1][1],                 \
611                     p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );     \
612         }                                                               \
613     }                                                                   \
614                                                                         \
615     else /* MB_MOTION_BACKWARD */                                       \
616     {                                                                   \
617         MOTION( p_mb, p_mb->p_backward, 0, 0,                           \
618                 p_mb->pppi_motion_vectors[0][1][0],                     \
619                 p_mb->pppi_motion_vectors[0][1][1],                     \
620                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
621     }                                                                   \
622 } /* FRAMEFRAME */
623
624 static void vdec_MotionFrameFrame420( macroblock_t * p_mb )
625 {
626     FRAMEFRAME( Motion420 )
627 }
628
629 static void vdec_MotionFrameFrame422( macroblock_t * p_mb )
630 {
631     //FRAMEFRAME( Motion422 )
632 }
633
634 static void vdec_MotionFrameFrame444( macroblock_t * p_mb )
635 {
636     //FRAMEFRAME( Motion444 )
637 }
638
639 /*****************************************************************************
640  * vdec_MotionFrameFieldXXX?? : motion compensation for field motion type (frame)
641  *****************************************************************************/
642 #define FRAMEFIELD( MOTION )                                            \
643 {                                                                       \
644     int i_l_stride = p_mb->i_l_stride << 1;                             \
645     int i_c_stride = p_mb->i_c_stride << 1;                             \
646                                                                         \
647     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
648     {                                                                   \
649         MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[0][0], 0, \
650                 p_mb->pppi_motion_vectors[0][0][0],                     \
651                 p_mb->pppi_motion_vectors[0][0][1] >> 1,                \
652                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
653                                                                         \
654         MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[1][0], 1, \
655                 p_mb->pppi_motion_vectors[1][0][0],                     \
656                 p_mb->pppi_motion_vectors[1][0][1] >> 1,                \
657                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
658                                                                         \
659         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
660         {                                                               \
661             MOTION( p_mb, p_mb->p_backward,                             \
662                     p_mb->ppi_field_select[0][1], 0,                    \
663                     p_mb->pppi_motion_vectors[0][1][0],                 \
664                     p_mb->pppi_motion_vectors[0][1][1] >> 1,            \
665                     i_l_stride, i_c_stride, 8, 0, 1 );                  \
666                                                                         \
667             MOTION( p_mb, p_mb->p_backward,                             \
668                     p_mb->ppi_field_select[1][1], 1,                    \
669                     p_mb->pppi_motion_vectors[1][1][0],                 \
670                     p_mb->pppi_motion_vectors[1][1][1] >> 1,            \
671                     i_l_stride, i_c_stride, 8, 0, 1 );                  \
672         }                                                               \
673     }                                                                   \
674                                                                         \
675     else /* MB_MOTION_BACKWARD only */                                  \
676     {                                                                   \
677         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], 0,\
678                 p_mb->pppi_motion_vectors[0][1][0],                     \
679                 p_mb->pppi_motion_vectors[0][1][1] >> 1,                \
680                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
681                                                                         \
682         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], 1,\
683                 p_mb->pppi_motion_vectors[1][1][0],                     \
684                 p_mb->pppi_motion_vectors[1][1][1] >> 1,                \
685                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
686     }                                                                   \
687 } /* FRAMEFIELD */
688
689 static void vdec_MotionFrameField420( macroblock_t * p_mb )
690 {
691     FRAMEFIELD( Motion420 )
692 }
693
694 static void vdec_MotionFrameField422( macroblock_t * p_mb )
695 {
696     //FRAMEFIELD( Motion422 )
697 }
698
699 static void vdec_MotionFrameField444( macroblock_t * p_mb )
700 {
701     //FRAMEFIELD( Motion444 )
702 }
703
704 /*****************************************************************************
705  * vdec_MotionFrameDMVXXX?? : motion compensation for dmv motion type (frame)
706  *****************************************************************************/
707 #define FRAMEDMV( MOTION )                                              \
708 {                                                                       \
709     /* This is necessarily a MOTION_FORWARD only macroblock, in a P     \
710      * picture. */                                                      \
711                                                                         \
712     /* predict top field from top field */                              \
713     MOTION( p_mb, p_mb->p_forward, 0, 0,                                \
714             p_mb->pppi_motion_vectors[0][0][0],                         \
715             p_mb->pppi_motion_vectors[0][0][1],                         \
716             /* XXX?? XXX?? >> 1 ? */                                    \
717             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 );    \
718                                                                         \
719     /* predict and add to top field from bottom field */                \
720     MOTION( p_mb, p_mb->p_forward, 1, 0,                                \
721             p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1],                   \
722             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 );    \
723                                                                         \
724     /* predict bottom field from bottom field */                        \
725     MOTION( p_mb, p_mb->p_forward, 1, 1,                                \
726             p_mb->pppi_motion_vectors[0][0][0],                         \
727             p_mb->pppi_motion_vectors[0][0][1],                         \
728             /* XXX?? XXX?? >> 1 ? */                                    \
729             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 );    \
730                                                                         \
731     /* predict and add to bottom field from top field */                \
732     MOTION( p_mb, p_mb->p_forward, 1, 0,                                \
733             p_mb->ppi_dmv[1][0], p_mb->ppi_dmv[1][1],                   \
734             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 );    \
735 } /* FRAMEDMV */
736
737 static void vdec_MotionFrameDMV420( macroblock_t * p_mb )
738 {
739     FRAMEDMV( Motion420 )
740 }
741
742 static void vdec_MotionFrameDMV422( macroblock_t * p_mb )
743 {
744     //FRAMEDMV( Motion422 )
745 }
746
747 static void vdec_MotionFrameDMV444( macroblock_t * p_mb )
748 {
749     //FRAMEDMV( Motion444 )
750 }
751