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