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