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