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