]> git.sesse.net Git - vlc/blob - src/video_decoder/vdec_motion.c
Fix� une bonne partie du putain de bug des carr�s qui font chier � chaque
[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: Christophe Massiot <massiot@via.ecp.fr>
7  *          Jean-Marc Dressler <polux@via.ecp.fr>
8  *          Michel Lespinasse <walken@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include "defs.h"
29
30 #include <sys/types.h>                        /* on BSD, uio.h needs types.h */
31 #include <sys/uio.h>                                          /* for input.h */
32
33 #include "config.h"
34 #include "common.h"
35 #include "threads.h"
36 #include "mtime.h"
37 #include "plugins.h"
38
39 #include "intf_msg.h"
40
41 #include "input.h"
42 #include "decoder_fifo.h"
43 #include "video.h"
44 #include "video_output.h"
45
46 #include "vdec_idct.h"
47 #include "video_decoder.h"
48 #include "vdec_motion.h"
49
50 #include "vpar_blocks.h"
51 #include "vpar_headers.h"
52 #include "vpar_synchro.h"
53 #include "video_parser.h"
54 #include "video_fifo.h"
55
56 #define __MotionComponents(width,height)                \
57 void MotionComponent_x_y_copy_##width##_##height ();    \
58 void MotionComponent_X_y_copy_##width##_##height ();    \
59 void MotionComponent_x_Y_copy_##width##_##height ();    \
60 void MotionComponent_X_Y_copy_##width##_##height ();    \
61 void MotionComponent_x_y_avg_##width##_##height ();     \
62 void MotionComponent_X_y_avg_##width##_##height ();     \
63 void MotionComponent_x_Y_avg_##width##_##height ();     \
64 void MotionComponent_X_Y_avg_##width##_##height ();
65
66 __MotionComponents (16,16)      /* 444, 422, 420 */
67 __MotionComponents (16,8)       /* 444, 422, 420 */
68 __MotionComponents (8,8)        /* 422, 420 */
69 __MotionComponents (8,4)        /* 420 */
70 #if 0
71 __MotionComponents (8,16)       /* 422 */
72 #endif
73
74 #define ___callTheRightOne(width,height)                                     \
75     if ((i_width == width) && (i_height == height))                          \
76     {                                                                        \
77         if (!b_average)                                                      \
78         {                                                                    \
79             switch (i_select)                                                \
80             {                                                                \
81             case 0:                                                          \
82                 MotionComponent_x_y_copy_##width##_##height (p_src, p_dest,  \
83                                                              i_stride);      \
84                 break;                                                       \
85             case 1:                                                          \
86                 MotionComponent_X_y_copy_##width##_##height (p_src, p_dest,  \
87                                                              i_stride);      \
88                 break;                                                       \
89             case 2:                                                          \
90                 MotionComponent_x_Y_copy_##width##_##height (p_src, p_dest,  \
91                                                              i_stride);      \
92                 break;                                                       \
93             case 3:                                                          \
94                 MotionComponent_X_Y_copy_##width##_##height (p_src, p_dest,  \
95                                                              i_stride);      \
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                 break;                                                       \
115             case 3:                                                          \
116                 MotionComponent_X_Y_avg_##width##_##height (p_src, p_dest,   \
117                                                             i_stride);       \
118                 break;                                                       \
119             }                                                                \
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_select,           /* half-pel vectors */
134                     boolean_t b_average     /* (explicit) averaging of several
135                                              * predictions */ )
136 {
137 ___callTheRightOne (16,16)
138 ___callTheRightOne (16,8)
139 ___callTheRightOne (8,8)
140 ___callTheRightOne (8,4)
141 #if 0
142 ___callTheRightOne (8,16)
143 #endif
144 }
145
146 /*****************************************************************************
147  * Motion420 : motion compensation for a 4:2:0 macroblock
148  *****************************************************************************/
149 static __inline__ void Motion420(
150                     macroblock_t * p_mb,        /* destination macroblock */
151                     picture_t * p_source,       /* source picture */
152                     boolean_t b_source_field,   /* source field */
153                     boolean_t b_dest_field,     /* destination field */
154                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
155                                                  * in half pels */
156                     int i_l_stride,             /* number of coeffs to jump to
157                                                  * go to the next predicted
158                                                  * line */
159                     int i_c_stride,
160                     int i_height,               /* height of the block to
161                                                  * predict, in luminance
162                                                  * (explicit) */
163                     int i_offset,               /* position of the first
164                                                  * predicted line (explicit) */
165                     boolean_t b_average         /* (explicit) averaging of
166                                                  * several predictions */ )
167 {
168     /* Temporary variables to avoid recalculating things twice */
169     int     i_source_offset, i_dest_offset, i_c_height, i_c_select;
170
171     i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
172                        + (p_mb->i_motion_l_y + i_offset
173                          + b_source_field)
174                        * p_mb->p_picture->i_width
175                        + (i_mv_y >> 1) * i_l_stride;
176     if( i_source_offset >= p_source->i_width * p_source->i_height )
177     {
178         intf_ErrMsg( "vdec error: bad motion vector (lum)\n" );
179         return;
180     }
181
182     /* Luminance */
183     MotionComponent( /* source */
184                      p_source->p_y + i_source_offset,
185                      /* destination */
186                      p_mb->p_picture->p_y
187                        + (p_mb->i_l_x)
188                        + (p_mb->i_motion_l_y + b_dest_field + i_offset)
189                          * p_mb->p_picture->i_width,
190                      /* prediction width and height */
191                      16, i_height,
192                      /* stride */
193                      i_l_stride,
194                      /* select */
195                      ((i_mv_y & 1) << 1) | (i_mv_x & 1),
196                      b_average );
197
198     i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
199                         + (p_mb->i_motion_c_y + (i_offset >> 1)
200                            + b_source_field)
201                           * p_mb->p_picture->i_chroma_width
202                         + ((i_mv_y/2) >> 1) * i_c_stride;
203     if( i_source_offset >= (p_source->i_width * p_source->i_height) / 4 )
204     {
205         intf_ErrMsg( "vdec error: bad motion vector (chroma)\n" );
206         return;
207     }
208
209     i_dest_offset = (p_mb->i_c_x)
210                       + (p_mb->i_motion_c_y + b_dest_field
211                           + (i_offset >> 1))
212                         * p_mb->p_picture->i_chroma_width;
213     i_c_height = i_height >> 1;
214     i_c_select = (((i_mv_y/2) & 1) << 1) | ((i_mv_x/2) & 1);
215
216     /* Chrominance Cr */
217     MotionComponent( p_source->p_u
218                        + i_source_offset,
219                      p_mb->p_picture->p_u
220                        + i_dest_offset,
221                      8, i_c_height, i_c_stride,
222                      i_c_select, b_average );
223
224     /* Chrominance Cb */
225     MotionComponent( p_source->p_v
226                        + i_source_offset,
227                      p_mb->p_picture->p_v
228                        + i_dest_offset,
229                      8, i_c_height, i_c_stride,
230                      i_c_select, b_average );
231 }
232
233 /*****************************************************************************
234  * Motion422 : motion compensation for a 4:2:2 macroblock
235  *****************************************************************************/
236 static __inline__ void Motion422(
237                     macroblock_t * p_mb,        /* destination macroblock */
238                     picture_t * p_source,       /* source picture */
239                     boolean_t b_source_field,   /* source field */
240                     boolean_t b_dest_field,     /* destination field */
241                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
242                                                  * in half pels */
243                     int i_l_stride,             /* number of coeffs to jump to
244                                                  * go to the next predicted
245                                                  * line */
246                     int i_c_stride,
247                     int i_height,               /* height of the block to
248                                                  * predict, in luminance
249                                                  * (explicit) */
250                     int i_offset,               /* position of the first
251                                                  * predicted line (explicit) */
252                     boolean_t b_average         /* (explicit) averaging of
253                                                  * several predictions */ )
254 {
255 #if 0
256     int     i_source_offset, i_dest_offset, i_c_select;
257
258     /* Luminance */
259     MotionComponent( /* source */
260                      p_source->p_y
261                        + (p_mb->i_l_x + (i_mv_x >> 1))
262                        + (p_mb->i_motion_l_y + i_offset
263                           + b_source_field)
264                        * p_mb->p_picture->i_width
265                        + (i_mv_y >> 1) * p_mb->i_l_stride,
266                      /* destination */
267                      p_mb->p_picture->p_y
268                        + (p_mb->i_l_x)
269                        + (p_mb->i_motion_l_y + b_dest_field)
270                          * p_mb->p_picture->i_width,
271                      /* prediction width and height */
272                      16, i_height,
273                      /* stride */
274                      i_l_stride,
275                      /* select */
276                      ((i_mv_y & 1) << 1) | (i_mv_x & 1),
277                      b_average );
278
279     i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
280                         + (p_mb->i_motion_c_y + i_offset
281                            + b_source_field)
282                         * p_mb->p_picture->i_chroma_width
283                         + (i_mv_y) >> 1) * p_mb->i_c_stride;
284     i_dest_offset = (p_mb->i_c_x)
285                       + (p_mb->i_motion_c_y + b_dest_field)
286                         * p_mb->p_picture->i_chroma_width;
287     i_c_select = ((i_mv_y & 1) << 1) | ((i_mv_x/2) & 1);
288
289     /* Chrominance Cr */
290     MotionComponent( p_source->p_u
291                        + i_source_offset,
292                      p_mb->p_picture->p_u
293                        + i_dest_offset,
294                      8, i_height, i_c_stride,
295                      i_c_select, b_average );
296
297     /* Chrominance Cb */
298     MotionComponent( p_source->p_v
299                        + i_source_offset,
300                      p_mb->p_picture->p_u
301                        + i_dest_offset,
302                      8, i_height, i_c_stride,
303                      i_c_select, b_average );
304 #endif
305 }
306
307 /*****************************************************************************
308  * Motion444 : motion compensation for a 4:4:4 macroblock
309  *****************************************************************************/
310 static __inline__ void Motion444(
311                     macroblock_t * p_mb,        /* destination macroblock */
312                     picture_t * p_source,       /* source picture */
313                     boolean_t b_source_field,   /* source field */
314                     boolean_t b_dest_field,     /* destination field */
315                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
316                                                  * in half pels */
317                     int i_l_stride,             /* number of coeffs to jump to
318                                                  * go to the next predicted
319                                                  * line */
320                     int i_c_stride,
321                     int i_height,               /* height of the block to
322                                                  * predict, in luminance
323                                                  * (explicit) */
324                     int i_offset,               /* position of the first
325                                                  * predicted line (explicit) */
326                     boolean_t b_average         /* (explicit) averaging of
327                                                  * several predictions */ )
328 {
329 #if 0
330     int     i_source_offset, i_dest_offset, i_select;
331
332     i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
333                         + (p_mb->i_motion_l_y + i_offset
334                            + b_source_field)
335                         * p_mb->p_picture->i_width
336                         + (i_mv_y >> 1) * p_mb->i_l_stride;
337     i_dest_offset = (p_mb->i_l_x)
338                       + (p_mb->i_motion_l_y + b_dest_field)
339                         * p_mb->p_picture->i_width;
340     i_select = ((i_mv_y & 1) << 1) | (i_mv_x & 1);
341
342
343     /* Luminance */
344     MotionComponent( p_source->p_y
345                        + i_source_offset,
346                      p_mb->p_picture->p_y
347                        + i_dest_offset,
348                      16, i_height, i_l_stride,
349                      i_select, b_average );
350
351     /* Chrominance Cr */
352     MotionComponent( p_source->p_u
353                        + i_source_offset,
354                      p_mb->p_picture->p_u
355                        + i_dest_offset,
356                      16, i_height, i_l_stride,
357                      i_select, b_average );
358
359     /* Chrominance Cb */
360     MotionComponent( p_source->p_v
361                        + i_source_offset,
362                      p_mb->p_picture->p_v
363                        + i_dest_offset,
364                      16, i_height, i_l_stride,
365                      i_select, b_average );
366 #endif
367 }
368
369 /*****************************************************************************
370  * vdec_MotionFieldField : motion compensation for field motion type (field)
371  *****************************************************************************/
372 #define FIELDFIELD( MOTION )                                            \
373 {                                                                       \
374     picture_t *     p_pred;                                             \
375                                                                         \
376     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
377     {                                                                   \
378         if( p_mb->b_P_second                                            \
379              && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
380             p_pred = p_mb->p_picture;                                   \
381         else                                                            \
382             p_pred = p_mb->p_forward;                                   \
383                                                                         \
384         MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0],             \
385                 p_mb->b_motion_field,                                   \
386                 p_mb->pppi_motion_vectors[0][0][0],                     \
387                 p_mb->pppi_motion_vectors[0][0][1],                     \
388                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
389                                                                         \
390         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
391         {                                                               \
392             MOTION( p_mb, p_mb->p_backward,                             \
393                     p_mb->ppi_field_select[0][1],                       \
394                     p_mb->b_motion_field,                               \
395                     p_mb->pppi_motion_vectors[0][1][0],                 \
396                     p_mb->pppi_motion_vectors[0][1][1],                 \
397                     p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );     \
398         }                                                               \
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] >> 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] >> 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] >> 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] >> 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] >> 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] >> 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 }