]> git.sesse.net Git - vlc/blob - plugins/motion/vdec_motion_common.c
Minor optimizations in the video decoder.
[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.5 2001/02/20 15:03:00 massiot Exp $
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *          Jean-Marc Dressler <polux@via.ecp.fr>
9  *          Michel Lespinasse <walken@via.ecp.fr>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
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
211     if( i_source_offset >= p_source->i_size )
212     {
213         intf_WarnMsg( 2, "Bad motion vector (lum)" );
214         return;
215     }
216
217     /* Luminance */
218     MotionComponent( /* source */
219                      p_source->p_y + i_source_offset,
220                      /* destination */
221                      p_mb->p_picture->p_y
222                        + (p_mb->i_l_x)
223                        + (p_mb->i_motion_l_y + b_dest_field + i_offset)
224                          * p_mb->p_picture->i_width,
225                      /* prediction width and height */
226                      16, i_height,
227                      /* stride */
228                      i_l_stride,
229                      /* select */
230                      ((i_mv_y & 1) << 1) | (i_mv_x & 1),
231                      b_average );
232
233     i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
234                         + (p_mb->i_motion_c_y + (i_offset >> 1)
235                            + b_source_field)
236                           * p_mb->p_picture->i_chroma_width
237                         + ((i_mv_y/2) >> 1) * i_c_stride;
238
239     if( i_source_offset >= p_source->i_chroma_size )
240     {
241         intf_WarnMsg( 2, "Bad motion vector (chroma)" );
242         return;
243     }
244
245     i_dest_offset = (p_mb->i_c_x)
246                       + (p_mb->i_motion_c_y + b_dest_field
247                           + (i_offset >> 1))
248                         * p_mb->p_picture->i_chroma_width;
249     i_c_height = i_height >> 1;
250     i_c_select = (((i_mv_y/2) & 1) << 1) | ((i_mv_x/2) & 1);
251
252     /* Chrominance Cr */
253     MotionComponent( p_source->p_u
254                        + i_source_offset,
255                      p_mb->p_picture->p_u
256                        + i_dest_offset,
257                      8, i_c_height, i_c_stride,
258                      i_c_select, b_average );
259
260     /* Chrominance Cb */
261     MotionComponent( p_source->p_v
262                        + i_source_offset,
263                      p_mb->p_picture->p_v
264                        + i_dest_offset,
265                      8, i_c_height, i_c_stride,
266                      i_c_select, b_average );
267 }
268
269 /*****************************************************************************
270  * Motion422 : motion compensation for a 4:2:2 macroblock
271  *****************************************************************************/
272 static __inline__ void Motion422(
273                     macroblock_t * p_mb,        /* destination macroblock */
274                     picture_t * p_source,       /* source picture */
275                     boolean_t b_source_field,   /* source field */
276                     boolean_t b_dest_field,     /* destination field */
277                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
278                                                  * in half pels */
279                     int i_l_stride,             /* number of coeffs to jump to
280                                                  * go to the next predicted
281                                                  * line */
282                     int i_c_stride,
283                     int i_height,               /* height of the block to
284                                                  * predict, in luminance
285                                                  * (explicit) */
286                     int i_offset,               /* position of the first
287                                                  * predicted line (explicit) */
288                     boolean_t b_average         /* (explicit) averaging of
289                                                  * several predictions */ )
290 {
291 #if 0
292     int     i_source_offset, i_dest_offset, i_c_select;
293
294     /* Luminance */
295     MotionComponent( /* source */
296                      p_source->p_y
297                        + (p_mb->i_l_x + (i_mv_x >> 1))
298                        + (p_mb->i_motion_l_y + i_offset
299                           + b_source_field)
300                        * p_mb->p_picture->i_width
301                        + (i_mv_y >> 1) * p_mb->i_l_stride,
302                      /* destination */
303                      p_mb->p_picture->p_y
304                        + (p_mb->i_l_x)
305                        + (p_mb->i_motion_l_y + b_dest_field)
306                          * p_mb->p_picture->i_width,
307                      /* prediction width and height */
308                      16, i_height,
309                      /* stride */
310                      i_l_stride,
311                      /* select */
312                      ((i_mv_y & 1) << 1) | (i_mv_x & 1),
313                      b_average );
314
315     i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
316                         + (p_mb->i_motion_c_y + i_offset
317                            + b_source_field)
318                         * p_mb->p_picture->i_chroma_width
319                         + (i_mv_y) >> 1) * p_mb->i_c_stride;
320     i_dest_offset = (p_mb->i_c_x)
321                       + (p_mb->i_motion_c_y + b_dest_field)
322                         * p_mb->p_picture->i_chroma_width;
323     i_c_select = ((i_mv_y & 1) << 1) | ((i_mv_x/2) & 1);
324
325     /* Chrominance Cr */
326     MotionComponent( p_source->p_u
327                        + i_source_offset,
328                      p_mb->p_picture->p_u
329                        + i_dest_offset,
330                      8, i_height, i_c_stride,
331                      i_c_select, b_average );
332
333     /* Chrominance Cb */
334     MotionComponent( p_source->p_v
335                        + i_source_offset,
336                      p_mb->p_picture->p_u
337                        + i_dest_offset,
338                      8, i_height, i_c_stride,
339                      i_c_select, b_average );
340 #endif
341 }
342
343 /*****************************************************************************
344  * Motion444 : motion compensation for a 4:4:4 macroblock
345  *****************************************************************************/
346 static __inline__ void Motion444(
347                     macroblock_t * p_mb,        /* destination macroblock */
348                     picture_t * p_source,       /* source picture */
349                     boolean_t b_source_field,   /* source field */
350                     boolean_t b_dest_field,     /* destination field */
351                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
352                                                  * in half pels */
353                     int i_l_stride,             /* number of coeffs to jump to
354                                                  * go to the next predicted
355                                                  * line */
356                     int i_c_stride,
357                     int i_height,               /* height of the block to
358                                                  * predict, in luminance
359                                                  * (explicit) */
360                     int i_offset,               /* position of the first
361                                                  * predicted line (explicit) */
362                     boolean_t b_average         /* (explicit) averaging of
363                                                  * several predictions */ )
364 {
365 #if 0
366     int     i_source_offset, i_dest_offset, i_select;
367
368     i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
369                         + (p_mb->i_motion_l_y + i_offset
370                            + b_source_field)
371                         * p_mb->p_picture->i_width
372                         + (i_mv_y >> 1) * p_mb->i_l_stride;
373     i_dest_offset = (p_mb->i_l_x)
374                       + (p_mb->i_motion_l_y + b_dest_field)
375                         * p_mb->p_picture->i_width;
376     i_select = ((i_mv_y & 1) << 1) | (i_mv_x & 1);
377
378
379     /* Luminance */
380     MotionComponent( p_source->p_y
381                        + i_source_offset,
382                      p_mb->p_picture->p_y
383                        + i_dest_offset,
384                      16, i_height, i_l_stride,
385                      i_select, b_average );
386
387     /* Chrominance Cr */
388     MotionComponent( p_source->p_u
389                        + i_source_offset,
390                      p_mb->p_picture->p_u
391                        + i_dest_offset,
392                      16, i_height, i_l_stride,
393                      i_select, b_average );
394
395     /* Chrominance Cb */
396     MotionComponent( p_source->p_v
397                        + i_source_offset,
398                      p_mb->p_picture->p_v
399                        + i_dest_offset,
400                      16, i_height, i_l_stride,
401                      i_select, b_average );
402 #endif
403 }
404
405 /*****************************************************************************
406  * vdec_MotionFieldField : motion compensation for field motion type (field)
407  *****************************************************************************/
408 #define FIELDFIELD( MOTION )                                            \
409 {                                                                       \
410     picture_t *     p_pred;                                             \
411                                                                         \
412     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
413     {                                                                   \
414         if( p_mb->b_P_second                                            \
415              && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
416             p_pred = p_mb->p_picture;                                   \
417         else                                                            \
418             p_pred = p_mb->p_forward;                                   \
419                                                                         \
420         MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0],             \
421                 p_mb->b_motion_field,                                   \
422                 p_mb->pppi_motion_vectors[0][0][0],                     \
423                 p_mb->pppi_motion_vectors[0][0][1],                     \
424                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
425                                                                         \
426         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
427         {                                                               \
428             MOTION( p_mb, p_mb->p_backward,                             \
429                     p_mb->ppi_field_select[0][1],                       \
430                     p_mb->b_motion_field,                               \
431                     p_mb->pppi_motion_vectors[0][1][0],                 \
432                     p_mb->pppi_motion_vectors[0][1][1],                 \
433                     p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );     \
434         }                                                               \
435     }                                                                   \
436                                                                         \
437     else /* MB_MOTION_BACKWARD */                                       \
438     {                                                                   \
439         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1],   \
440                 p_mb->b_motion_field,                                   \
441                 p_mb->pppi_motion_vectors[0][1][0],                     \
442                 p_mb->pppi_motion_vectors[0][1][1],                     \
443                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
444     }                                                                   \
445 }
446
447 static void vdec_MotionFieldField420( macroblock_t * p_mb )
448 {
449     FIELDFIELD( Motion420 )
450 }
451
452 static void vdec_MotionFieldField422( macroblock_t * p_mb )
453 {
454     //FIELDFIELD( Motion422 )
455 }
456
457 static void vdec_MotionFieldField444( macroblock_t * p_mb )
458 {
459     //FIELDFIELD( Motion444 )
460 }
461
462 /*****************************************************************************
463  * vdec_MotionField16x8XXX: motion compensation for 16x8 motion type (field)
464  *****************************************************************************/
465 #define FIELD16X8( MOTION )                                             \
466 {                                                                       \
467     picture_t *     p_pred;                                             \
468                                                                         \
469     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
470     {                                                                   \
471         if( p_mb->b_P_second                                            \
472              && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
473             p_pred = p_mb->p_picture;                                   \
474         else                                                            \
475             p_pred = p_mb->p_forward;                                   \
476                                                                         \
477         MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0],             \
478                 p_mb->b_motion_field,                                   \
479                 p_mb->pppi_motion_vectors[0][0][0],                     \
480                 p_mb->pppi_motion_vectors[0][0][1],                     \
481                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 );          \
482                                                                         \
483         if( p_mb->b_P_second                                            \
484              && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\
485             p_pred = p_mb->p_picture;                                   \
486         else                                                            \
487             p_pred = p_mb->p_forward;                                   \
488                                                                         \
489         MOTION( p_mb, p_pred, p_mb->ppi_field_select[1][0],             \
490                 p_mb->b_motion_field,                                   \
491                 p_mb->pppi_motion_vectors[1][0][0],                     \
492                 p_mb->pppi_motion_vectors[1][0][1],                     \
493                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 );          \
494                                                                         \
495         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
496         {                                                               \
497             MOTION( p_mb, p_mb->p_backward,                             \
498                     p_mb->ppi_field_select[0][1],                       \
499                     p_mb->b_motion_field,                               \
500                     p_mb->pppi_motion_vectors[0][1][0],                 \
501                     p_mb->pppi_motion_vectors[0][1][1],                 \
502                     p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 1 );      \
503                                                                         \
504             MOTION( p_mb, p_mb->p_backward,                             \
505                     p_mb->ppi_field_select[1][1],                       \
506                     p_mb->b_motion_field,                               \
507                     p_mb->pppi_motion_vectors[1][1][0],                 \
508                     p_mb->pppi_motion_vectors[1][1][1],                 \
509                     p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 1 );      \
510         }                                                               \
511     }                                                                   \
512                                                                         \
513     else /* MB_MOTION_BACKWARD */                                       \
514     {                                                                   \
515         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1],   \
516                 p_mb->b_motion_field,                                   \
517                 p_mb->pppi_motion_vectors[0][1][0],                     \
518                 p_mb->pppi_motion_vectors[0][1][1],                     \
519                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 );          \
520                                                                         \
521         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1],   \
522                 p_mb->b_motion_field,                                   \
523                 p_mb->pppi_motion_vectors[1][1][0],                     \
524                 p_mb->pppi_motion_vectors[1][1][1],                     \
525                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 );          \
526     }                                                                   \
527 }
528
529 static void vdec_MotionField16x8420( macroblock_t * p_mb )
530 {
531     FIELD16X8( Motion420 )
532 }
533
534 static void vdec_MotionField16x8422( macroblock_t * p_mb )
535 {
536     //FIELD16X8( Motion422 )
537 }
538
539 static void vdec_MotionField16x8444( macroblock_t * p_mb )
540 {
541     //FIELD16X8( Motion444 )
542 }
543
544 /*****************************************************************************
545  * vdec_MotionFieldDMVXXX : motion compensation for dmv motion type (field)
546  *****************************************************************************/
547 #define FIELDDMV( MOTION )                                              \
548 {                                                                       \
549     /* This is necessarily a MOTION_FORWARD only macroblock, in a P     \
550      * picture. */                                                      \
551     picture_t *     p_pred;                                             \
552                                                                         \
553     /* predict from field of same parity */                             \
554     MOTION( p_mb, p_mb->p_forward,                                      \
555             p_mb->b_motion_field, p_mb->b_motion_field,                 \
556             p_mb->pppi_motion_vectors[0][0][0],                         \
557             p_mb->pppi_motion_vectors[0][0][1],                         \
558             p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );             \
559                                                                         \
560     if( p_mb->b_P_second )                                              \
561         p_pred = p_mb->p_picture;                                       \
562     else                                                                \
563         p_pred = p_mb->p_forward;                                       \
564                                                                         \
565     /* predict from field of opposite parity */                         \
566     MOTION( p_mb, p_pred, !p_mb->b_motion_field, p_mb->b_motion_field,  \
567             p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1],                   \
568             p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );             \
569 } /* FIELDDMV */
570
571 static void vdec_MotionFieldDMV420( macroblock_t * p_mb )
572 {
573     FIELDDMV( Motion420 )
574 }
575
576 static void vdec_MotionFieldDMV422( macroblock_t * p_mb )
577 {
578     //FIELDDMV( Motion422 )
579 }
580
581 static void vdec_MotionFieldDMV444( macroblock_t * p_mb )
582 {
583     //FIELDDMV( Motion444 )
584 }
585
586 /*****************************************************************************
587  * vdec_MotionFrameFrameXXX?? : motion compensation for frame motion type (frame)
588  *****************************************************************************/
589 #define FRAMEFRAME( MOTION )                                            \
590 {                                                                       \
591     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
592     {                                                                   \
593         MOTION( p_mb, p_mb->p_forward, 0, 0,                            \
594                 p_mb->pppi_motion_vectors[0][0][0],                     \
595                 p_mb->pppi_motion_vectors[0][0][1],                     \
596                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
597                                                                         \
598         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
599         {                                                               \
600             MOTION( p_mb, p_mb->p_backward, 0, 0,                       \
601                     p_mb->pppi_motion_vectors[0][1][0],                 \
602                     p_mb->pppi_motion_vectors[0][1][1],                 \
603                     p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );     \
604         }                                                               \
605     }                                                                   \
606                                                                         \
607     else /* 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, 0 );         \
613     }                                                                   \
614 } /* FRAMEFRAME */
615
616 static void vdec_MotionFrameFrame420( macroblock_t * p_mb )
617 {
618     FRAMEFRAME( Motion420 )
619 }
620
621 static void vdec_MotionFrameFrame422( macroblock_t * p_mb )
622 {
623     //FRAMEFRAME( Motion422 )
624 }
625
626 static void vdec_MotionFrameFrame444( macroblock_t * p_mb )
627 {
628     //FRAMEFRAME( Motion444 )
629 }
630
631 /*****************************************************************************
632  * vdec_MotionFrameFieldXXX?? : motion compensation for field motion type (frame)
633  *****************************************************************************/
634 #define FRAMEFIELD( MOTION )                                            \
635 {                                                                       \
636     int i_l_stride = p_mb->i_l_stride << 1;                             \
637     int i_c_stride = p_mb->i_c_stride << 1;                             \
638                                                                         \
639     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
640     {                                                                   \
641         MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[0][0], 0, \
642                 p_mb->pppi_motion_vectors[0][0][0],                     \
643                 p_mb->pppi_motion_vectors[0][0][1] >> 1,                \
644                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
645                                                                         \
646         MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[1][0], 1, \
647                 p_mb->pppi_motion_vectors[1][0][0],                     \
648                 p_mb->pppi_motion_vectors[1][0][1] >> 1,                \
649                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
650                                                                         \
651         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
652         {                                                               \
653             MOTION( p_mb, p_mb->p_backward,                             \
654                     p_mb->ppi_field_select[0][1], 0,                    \
655                     p_mb->pppi_motion_vectors[0][1][0],                 \
656                     p_mb->pppi_motion_vectors[0][1][1] >> 1,            \
657                     i_l_stride, i_c_stride, 8, 0, 1 );                  \
658                                                                         \
659             MOTION( p_mb, p_mb->p_backward,                             \
660                     p_mb->ppi_field_select[1][1], 1,                    \
661                     p_mb->pppi_motion_vectors[1][1][0],                 \
662                     p_mb->pppi_motion_vectors[1][1][1] >> 1,            \
663                     i_l_stride, i_c_stride, 8, 0, 1 );                  \
664         }                                                               \
665     }                                                                   \
666                                                                         \
667     else /* MB_MOTION_BACKWARD only */                                  \
668     {                                                                   \
669         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], 0,\
670                 p_mb->pppi_motion_vectors[0][1][0],                     \
671                 p_mb->pppi_motion_vectors[0][1][1] >> 1,                \
672                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
673                                                                         \
674         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], 1,\
675                 p_mb->pppi_motion_vectors[1][1][0],                     \
676                 p_mb->pppi_motion_vectors[1][1][1] >> 1,                \
677                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
678     }                                                                   \
679 } /* FRAMEFIELD */
680
681 static void vdec_MotionFrameField420( macroblock_t * p_mb )
682 {
683     FRAMEFIELD( Motion420 )
684 }
685
686 static void vdec_MotionFrameField422( macroblock_t * p_mb )
687 {
688     //FRAMEFIELD( Motion422 )
689 }
690
691 static void vdec_MotionFrameField444( macroblock_t * p_mb )
692 {
693     //FRAMEFIELD( Motion444 )
694 }
695
696 /*****************************************************************************
697  * vdec_MotionFrameDMVXXX?? : motion compensation for dmv motion type (frame)
698  *****************************************************************************/
699 #define FRAMEDMV( MOTION )                                              \
700 {                                                                       \
701     /* This is necessarily a MOTION_FORWARD only macroblock, in a P     \
702      * picture. */                                                      \
703                                                                         \
704     /* predict top field from top field */                              \
705     MOTION( p_mb, p_mb->p_forward, 0, 0,                                \
706             p_mb->pppi_motion_vectors[0][0][0],                         \
707             p_mb->pppi_motion_vectors[0][0][1],                         \
708             /* XXX?? XXX?? >> 1 ? */                                    \
709             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 );    \
710                                                                         \
711     /* predict and add to top field from bottom field */                \
712     MOTION( p_mb, p_mb->p_forward, 1, 0,                                \
713             p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1],                   \
714             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 );    \
715                                                                         \
716     /* predict bottom field from bottom field */                        \
717     MOTION( p_mb, p_mb->p_forward, 1, 1,                                \
718             p_mb->pppi_motion_vectors[0][0][0],                         \
719             p_mb->pppi_motion_vectors[0][0][1],                         \
720             /* XXX?? XXX?? >> 1 ? */                                    \
721             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 );    \
722                                                                         \
723     /* predict and add to bottom field from top field */                \
724     MOTION( p_mb, p_mb->p_forward, 1, 0,                                \
725             p_mb->ppi_dmv[1][0], p_mb->ppi_dmv[1][1],                   \
726             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 );    \
727 } /* FRAMEDMV */
728
729 static void vdec_MotionFrameDMV420( macroblock_t * p_mb )
730 {
731     FRAMEDMV( Motion420 )
732 }
733
734 static void vdec_MotionFrameDMV422( macroblock_t * p_mb )
735 {
736     //FRAMEDMV( Motion422 )
737 }
738
739 static void vdec_MotionFrameDMV444( macroblock_t * p_mb )
740 {
741     //FRAMEDMV( Motion444 )
742 }
743