]> git.sesse.net Git - vlc/blob - src/video_decoder/vdec_motion.c
The input-II. (more info by mail in about an hour)
[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 "stream_control.h"
42 #include "input_ext-dec.h"
43
44 #include "video.h"
45 #include "video_output.h"
46
47 #include "vdec_idct.h"
48 #include "video_decoder.h"
49 #include "vdec_motion.h"
50
51 #include "vpar_blocks.h"
52 #include "vpar_headers.h"
53 #include "vpar_synchro.h"
54 #include "video_parser.h"
55 #include "video_fifo.h"
56
57 #define __MotionComponents(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_copy_##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 void MotionComponent_X_Y_avg_##width##_##height ();
66
67 __MotionComponents (16,16)      /* 444, 422, 420 */
68 __MotionComponents (16,8)       /* 444, 422, 420 */
69 __MotionComponents (8,8)        /* 422, 420 */
70 __MotionComponents (8,4)        /* 420 */
71 #if 0
72 __MotionComponents (8,16)       /* 422 */
73 #endif
74
75 #define ___callTheRightOne(width,height)                                     \
76     if ((i_width == width) && (i_height == height))                          \
77     {                                                                        \
78         if (!b_average)                                                      \
79         {                                                                    \
80             switch (i_select)                                                \
81             {                                                                \
82             case 0:                                                          \
83                 MotionComponent_x_y_copy_##width##_##height (p_src, p_dest,  \
84                                                              i_stride);      \
85                 break;                                                       \
86             case 1:                                                          \
87                 MotionComponent_X_y_copy_##width##_##height (p_src, p_dest,  \
88                                                              i_stride);      \
89                 break;                                                       \
90             case 2:                                                          \
91                 MotionComponent_x_Y_copy_##width##_##height (p_src, p_dest,  \
92                                                              i_stride);      \
93                 break;                                                       \
94             case 3:                                                          \
95                 MotionComponent_X_Y_copy_##width##_##height (p_src, p_dest,  \
96                                                              i_stride);      \
97                 break;                                                       \
98             }                                                                \
99         }                                                                    \
100         else                                                                 \
101         {                                                                    \
102             switch (i_select)                                                \
103             {                                                                \
104             case 0:                                                          \
105                 MotionComponent_x_y_avg_##width##_##height (p_src, p_dest,   \
106                                                             i_stride);       \
107                 break;                                                       \
108             case 1:                                                          \
109                 MotionComponent_X_y_avg_##width##_##height (p_src, p_dest,   \
110                                                             i_stride);       \
111                 break;                                                       \
112             case 2:                                                          \
113                 MotionComponent_x_Y_avg_##width##_##height (p_src, p_dest,   \
114                                                             i_stride);       \
115                 break;                                                       \
116             case 3:                                                          \
117                 MotionComponent_X_Y_avg_##width##_##height (p_src, p_dest,   \
118                                                             i_stride);       \
119                 break;                                                       \
120             }                                                                \
121         }                                                                    \
122     }
123
124 /*****************************************************************************
125  * vdec_MotionComponent : last stage of motion compensation
126  *****************************************************************************/
127 static __inline__ void MotionComponent(
128                     yuv_data_t * p_src,     /* source block */
129                     yuv_data_t * p_dest,    /* dest block */
130                     int i_width,            /* (explicit) width of block */
131                     int i_height,           /* (explicit) height of block */
132                     int i_stride,           /* number of coeffs to jump
133                                              * between each predicted line */
134                     int i_select,           /* half-pel vectors */
135                     boolean_t b_average     /* (explicit) averaging of several
136                                              * predictions */ )
137 {
138 ___callTheRightOne (16,16)
139 ___callTheRightOne (16,8)
140 ___callTheRightOne (8,8)
141 ___callTheRightOne (8,4)
142 #if 0
143 ___callTheRightOne (8,16)
144 #endif
145 }
146
147 /*****************************************************************************
148  * Motion420 : motion compensation for a 4:2:0 macroblock
149  *****************************************************************************/
150 static __inline__ void Motion420(
151                     macroblock_t * p_mb,        /* destination macroblock */
152                     picture_t * p_source,       /* source picture */
153                     boolean_t b_source_field,   /* source field */
154                     boolean_t b_dest_field,     /* destination field */
155                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
156                                                  * in half pels */
157                     int i_l_stride,             /* number of coeffs to jump to
158                                                  * go to the next predicted
159                                                  * line */
160                     int i_c_stride,
161                     int i_height,               /* height of the block to
162                                                  * predict, in luminance
163                                                  * (explicit) */
164                     int i_offset,               /* position of the first
165                                                  * predicted line (explicit) */
166                     boolean_t b_average         /* (explicit) averaging of
167                                                  * several predictions */ )
168 {
169     /* Temporary variables to avoid recalculating things twice */
170     int     i_source_offset, i_dest_offset, i_c_height, i_c_select;
171
172     i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
173                        + (p_mb->i_motion_l_y + i_offset
174                          + b_source_field)
175                        * p_mb->p_picture->i_width
176                        + (i_mv_y >> 1) * i_l_stride;
177     if( i_source_offset >= p_source->i_width * p_source->i_height )
178     {
179         intf_ErrMsg( "vdec error: bad motion vector (lum)\n" );
180         return;
181     }
182
183     /* Luminance */
184     MotionComponent( /* source */
185                      p_source->p_y + i_source_offset,
186                      /* destination */
187                      p_mb->p_picture->p_y
188                        + (p_mb->i_l_x)
189                        + (p_mb->i_motion_l_y + b_dest_field + i_offset)
190                          * p_mb->p_picture->i_width,
191                      /* prediction width and height */
192                      16, i_height,
193                      /* stride */
194                      i_l_stride,
195                      /* select */
196                      ((i_mv_y & 1) << 1) | (i_mv_x & 1),
197                      b_average );
198
199     i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
200                         + (p_mb->i_motion_c_y + (i_offset >> 1)
201                            + b_source_field)
202                           * p_mb->p_picture->i_chroma_width
203                         + ((i_mv_y/2) >> 1) * i_c_stride;
204     if( i_source_offset >= (p_source->i_width * p_source->i_height) / 4 )
205     {
206         intf_ErrMsg( "vdec error: bad motion vector (chroma)\n" );
207         return;
208     }
209
210     i_dest_offset = (p_mb->i_c_x)
211                       + (p_mb->i_motion_c_y + b_dest_field
212                           + (i_offset >> 1))
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,
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,
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                           + b_source_field)
265                        * p_mb->p_picture->i_width
266                        + (i_mv_y >> 1) * p_mb->i_l_stride,
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,
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                            + b_source_field)
283                         * p_mb->p_picture->i_chroma_width
284                         + (i_mv_y) >> 1) * p_mb->i_c_stride;
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,
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,
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                            + b_source_field)
336                         * p_mb->p_picture->i_width
337                         + (i_mv_y >> 1) * p_mb->i_l_stride;
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,
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,
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,
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 {                                                                       \
375     picture_t *     p_pred;                                             \
376                                                                         \
377     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
378     {                                                                   \
379         if( p_mb->b_P_second                                            \
380              && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
381             p_pred = p_mb->p_picture;                                   \
382         else                                                            \
383             p_pred = p_mb->p_forward;                                   \
384                                                                         \
385         MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0],             \
386                 p_mb->b_motion_field,                                   \
387                 p_mb->pppi_motion_vectors[0][0][0],                     \
388                 p_mb->pppi_motion_vectors[0][0][1],                     \
389                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
390                                                                         \
391         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
392         {                                                               \
393             MOTION( p_mb, p_mb->p_backward,                             \
394                     p_mb->ppi_field_select[0][1],                       \
395                     p_mb->b_motion_field,                               \
396                     p_mb->pppi_motion_vectors[0][1][0],                 \
397                     p_mb->pppi_motion_vectors[0][1][1],                 \
398                     p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );     \
399         }                                                               \
400     }                                                                   \
401                                                                         \
402     else /* MB_MOTION_BACKWARD */                                       \
403     {                                                                   \
404         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1],   \
405                 p_mb->b_motion_field,                                   \
406                 p_mb->pppi_motion_vectors[0][1][0],                     \
407                 p_mb->pppi_motion_vectors[0][1][1],                     \
408                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
409     }                                                                   \
410 }
411
412 void vdec_MotionFieldField420( macroblock_t * p_mb )
413 {
414     FIELDFIELD( Motion420 )
415 }
416
417 void vdec_MotionFieldField422( macroblock_t * p_mb )
418 {
419     //FIELDFIELD( Motion422 )
420 }
421
422 void vdec_MotionFieldField444( macroblock_t * p_mb )
423 {
424     //FIELDFIELD( Motion444 )
425 }
426
427 /*****************************************************************************
428  * vdec_MotionField16x8XXX: motion compensation for 16x8 motion type (field)
429  *****************************************************************************/
430 #define FIELD16X8( MOTION )                                             \
431 {                                                                       \
432     picture_t *     p_pred;                                             \
433                                                                         \
434     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
435     {                                                                   \
436         if( p_mb->b_P_second                                            \
437              && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
438             p_pred = p_mb->p_picture;                                   \
439         else                                                            \
440             p_pred = p_mb->p_forward;                                   \
441                                                                         \
442         MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0],             \
443                 p_mb->b_motion_field,                                   \
444                 p_mb->pppi_motion_vectors[0][0][0],                     \
445                 p_mb->pppi_motion_vectors[0][0][1],                     \
446                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 );          \
447                                                                         \
448         if( p_mb->b_P_second                                            \
449              && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\
450             p_pred = p_mb->p_picture;                                   \
451         else                                                            \
452             p_pred = p_mb->p_forward;                                   \
453                                                                         \
454         MOTION( p_mb, p_pred, p_mb->ppi_field_select[1][0],             \
455                 p_mb->b_motion_field,                                   \
456                 p_mb->pppi_motion_vectors[1][0][0],                     \
457                 p_mb->pppi_motion_vectors[1][0][1],                     \
458                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 );          \
459                                                                         \
460         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
461         {                                                               \
462             MOTION( p_mb, p_mb->p_backward,                             \
463                     p_mb->ppi_field_select[0][1],                       \
464                     p_mb->b_motion_field,                               \
465                     p_mb->pppi_motion_vectors[0][1][0],                 \
466                     p_mb->pppi_motion_vectors[0][1][1],                 \
467                     p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 1 );      \
468                                                                         \
469             MOTION( p_mb, p_mb->p_backward,                             \
470                     p_mb->ppi_field_select[1][1],                       \
471                     p_mb->b_motion_field,                               \
472                     p_mb->pppi_motion_vectors[1][1][0],                 \
473                     p_mb->pppi_motion_vectors[1][1][1],                 \
474                     p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 1 );      \
475         }                                                               \
476     }                                                                   \
477                                                                         \
478     else /* MB_MOTION_BACKWARD */                                       \
479     {                                                                   \
480         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1],   \
481                 p_mb->b_motion_field,                                   \
482                 p_mb->pppi_motion_vectors[0][1][0],                     \
483                 p_mb->pppi_motion_vectors[0][1][1],                     \
484                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 );          \
485                                                                         \
486         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1],   \
487                 p_mb->b_motion_field,                                   \
488                 p_mb->pppi_motion_vectors[1][1][0],                     \
489                 p_mb->pppi_motion_vectors[1][1][1],                     \
490                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 );          \
491     }                                                                   \
492 }
493
494 void vdec_MotionField16x8420( macroblock_t * p_mb )
495 {
496     FIELD16X8( Motion420 )
497 }
498
499 void vdec_MotionField16x8422( macroblock_t * p_mb )
500 {
501     //FIELD16X8( Motion422 )
502 }
503
504 void vdec_MotionField16x8444( macroblock_t * p_mb )
505 {
506     //FIELD16X8( Motion444 )
507 }
508
509 /*****************************************************************************
510  * vdec_MotionFieldDMVXXX : motion compensation for dmv motion type (field)
511  *****************************************************************************/
512 #define FIELDDMV( MOTION )                                              \
513 {                                                                       \
514     /* This is necessarily a MOTION_FORWARD only macroblock, in a P     \
515      * picture. */                                                      \
516     picture_t *     p_pred;                                             \
517                                                                         \
518     /* predict from field of same parity */                             \
519     MOTION( p_mb, p_mb->p_forward,                                      \
520             p_mb->b_motion_field, p_mb->b_motion_field,                 \
521             p_mb->pppi_motion_vectors[0][0][0],                         \
522             p_mb->pppi_motion_vectors[0][0][1],                         \
523             p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );             \
524                                                                         \
525     if( p_mb->b_P_second )                                              \
526         p_pred = p_mb->p_picture;                                       \
527     else                                                                \
528         p_pred = p_mb->p_forward;                                       \
529                                                                         \
530     /* predict from field of opposite parity */                         \
531     MOTION( p_mb, p_pred, !p_mb->b_motion_field, p_mb->b_motion_field,  \
532             p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1],                   \
533             p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );             \
534 } /* FIELDDMV */
535
536 void vdec_MotionFieldDMV420( macroblock_t * p_mb )
537 {
538     FIELDDMV( Motion420 )
539 }
540
541 void vdec_MotionFieldDMV422( macroblock_t * p_mb )
542 {
543     //FIELDDMV( Motion422 )
544 }
545
546 void vdec_MotionFieldDMV444( macroblock_t * p_mb )
547 {
548     //FIELDDMV( Motion444 )
549 }
550
551 /*****************************************************************************
552  * vdec_MotionFrameFrameXXX?? : motion compensation for frame motion type (frame)
553  *****************************************************************************/
554 #define FRAMEFRAME( MOTION )                                            \
555 {                                                                       \
556     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
557     {                                                                   \
558         MOTION( p_mb, p_mb->p_forward, 0, 0,                            \
559                 p_mb->pppi_motion_vectors[0][0][0],                     \
560                 p_mb->pppi_motion_vectors[0][0][1],                     \
561                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
562                                                                         \
563         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
564         {                                                               \
565             MOTION( p_mb, p_mb->p_backward, 0, 0,                       \
566                     p_mb->pppi_motion_vectors[0][1][0],                 \
567                     p_mb->pppi_motion_vectors[0][1][1],                 \
568                     p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );     \
569         }                                                               \
570     }                                                                   \
571                                                                         \
572     else /* MB_MOTION_BACKWARD */                                       \
573     {                                                                   \
574         MOTION( p_mb, p_mb->p_backward, 0, 0,                           \
575                 p_mb->pppi_motion_vectors[0][1][0],                     \
576                 p_mb->pppi_motion_vectors[0][1][1],                     \
577                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
578     }                                                                   \
579 } /* FRAMEFRAME */
580
581 void vdec_MotionFrameFrame420( macroblock_t * p_mb )
582 {
583     FRAMEFRAME( Motion420 )
584 }
585
586 void vdec_MotionFrameFrame422( macroblock_t * p_mb )
587 {
588     //FRAMEFRAME( Motion422 )
589 }
590
591 void vdec_MotionFrameFrame444( macroblock_t * p_mb )
592 {
593     //FRAMEFRAME( Motion444 )
594 }
595
596 /*****************************************************************************
597  * vdec_MotionFrameFieldXXX?? : motion compensation for field motion type (frame)
598  *****************************************************************************/
599 #define FRAMEFIELD( MOTION )                                            \
600 {                                                                       \
601     int i_l_stride = p_mb->i_l_stride << 1;                             \
602     int i_c_stride = p_mb->i_c_stride << 1;                             \
603                                                                         \
604     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
605     {                                                                   \
606         MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[0][0], 0, \
607                 p_mb->pppi_motion_vectors[0][0][0],                     \
608                 p_mb->pppi_motion_vectors[0][0][1] >> 1,                \
609                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
610                                                                         \
611         MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[1][0], 1, \
612                 p_mb->pppi_motion_vectors[1][0][0],                     \
613                 p_mb->pppi_motion_vectors[1][0][1] >> 1,                \
614                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
615                                                                         \
616         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
617         {                                                               \
618             MOTION( p_mb, p_mb->p_backward,                             \
619                     p_mb->ppi_field_select[0][1], 0,                    \
620                     p_mb->pppi_motion_vectors[0][1][0],                 \
621                     p_mb->pppi_motion_vectors[0][1][1] >> 1,            \
622                     i_l_stride, i_c_stride, 8, 0, 1 );                  \
623                                                                         \
624             MOTION( p_mb, p_mb->p_backward,                             \
625                     p_mb->ppi_field_select[1][1], 1,                    \
626                     p_mb->pppi_motion_vectors[1][1][0],                 \
627                     p_mb->pppi_motion_vectors[1][1][1] >> 1,            \
628                     i_l_stride, i_c_stride, 8, 0, 1 );                  \
629         }                                                               \
630     }                                                                   \
631                                                                         \
632     else /* MB_MOTION_BACKWARD only */                                  \
633     {                                                                   \
634         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], 0,\
635                 p_mb->pppi_motion_vectors[0][1][0],                     \
636                 p_mb->pppi_motion_vectors[0][1][1] >> 1,                \
637                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
638                                                                         \
639         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], 1,\
640                 p_mb->pppi_motion_vectors[1][1][0],                     \
641                 p_mb->pppi_motion_vectors[1][1][1] >> 1,                \
642                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
643     }                                                                   \
644 } /* FRAMEFIELD */
645
646 void vdec_MotionFrameField420( macroblock_t * p_mb )
647 {
648     FRAMEFIELD( Motion420 )
649 }
650
651 void vdec_MotionFrameField422( macroblock_t * p_mb )
652 {
653     //FRAMEFIELD( Motion422 )
654 }
655
656 void vdec_MotionFrameField444( macroblock_t * p_mb )
657 {
658     //FRAMEFIELD( Motion444 )
659 }
660
661 /*****************************************************************************
662  * vdec_MotionFrameDMVXXX?? : motion compensation for dmv motion type (frame)
663  *****************************************************************************/
664 #define FRAMEDMV( MOTION )                                              \
665 {                                                                       \
666     /* This is necessarily a MOTION_FORWARD only macroblock, in a P     \
667      * picture. */                                                      \
668                                                                         \
669     /* predict top field from top field */                              \
670     MOTION( p_mb, p_mb->p_forward, 0, 0,                                \
671             p_mb->pppi_motion_vectors[0][0][0],                         \
672             p_mb->pppi_motion_vectors[0][0][1],                         \
673             /* XXX?? XXX?? >> 1 ? */                                        \
674             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 );    \
675                                                                         \
676     /* predict and add to top field from bottom field */                \
677     MOTION( p_mb, p_mb->p_forward, 1, 0,                                \
678             p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1],                   \
679             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 );    \
680                                                                         \
681     /* predict bottom field from bottom field */                        \
682     MOTION( p_mb, p_mb->p_forward, 1, 1,                                \
683             p_mb->pppi_motion_vectors[0][0][0],                         \
684             p_mb->pppi_motion_vectors[0][0][1],                         \
685             /* XXX?? XXX?? >> 1 ? */                                        \
686             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 );    \
687                                                                         \
688     /* predict and add to bottom field from top field */                \
689     MOTION( p_mb, p_mb->p_forward, 1, 0,                                \
690             p_mb->ppi_dmv[1][0], p_mb->ppi_dmv[1][1],                   \
691             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 );    \
692 } /* FRAMEDMV */
693
694 void vdec_MotionFrameDMV420( macroblock_t * p_mb )
695 {
696     FRAMEDMV( Motion420 )
697 }
698
699 void vdec_MotionFrameDMV422( macroblock_t * p_mb )
700 {
701     //FRAMEDMV( Motion422 )
702 }
703
704 void vdec_MotionFrameDMV444( macroblock_t * p_mb )
705 {
706     //FRAMEDMV( Motion444 )
707 }