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