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