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