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