]> git.sesse.net Git - vlc/blob - src/video_decoder/vdec_motion.c
La plupart des causes de segfault de la video ont �t� �limin�es, les messages
[vlc] / src / video_decoder / vdec_motion.c
1 /*****************************************************************************
2  * vdec_motion.c : motion compensation routines
3  * (c)1999 VideoLAN
4  *****************************************************************************/
5
6 /*****************************************************************************
7  * Preamble
8  *****************************************************************************/
9 #include <errno.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <string.h>
14 #include <sys/uio.h>
15
16 #include "config.h"
17 #include "common.h"
18 #include "mtime.h"
19 #include "vlc_thread.h"
20
21 #include "intf_msg.h"
22 #include "debug.h"                    /* ?? temporaire, requis par netlist.h */
23
24 #include "input.h"
25 #include "input_netlist.h"
26 #include "decoder_fifo.h"
27 #include "video.h"
28 #include "video_output.h"
29
30 #include "vdec_idct.h"
31 #include "video_decoder.h"
32 #include "vdec_motion.h"
33
34 #include "vpar_blocks.h"
35 #include "vpar_headers.h"
36 #include "vpar_synchro.h"
37 #include "video_parser.h"
38 #include "video_fifo.h"
39
40 /*****************************************************************************
41  * vdec_MotionComponent : last stage of motion compensation
42  *****************************************************************************/
43 static __inline__ void MotionComponent(
44                     yuv_data_t * p_src,     /* source block */
45                     yuv_data_t * p_dest,    /* dest block */
46                     int i_width,            /* (explicit) width of block */
47                     int i_height,           /* (explicit) height of block */
48                     int i_stride,           /* number of coeffs to jump
49                                              * between each predicted line */
50                     int i_step,             /* number of coeffs to jump to
51                                              * go to the next line of the
52                                              * field */
53                     int i_select,           /* half-pel vectors */
54                     boolean_t b_average     /* (explicit) averaging of several
55                                              * predictions */ )
56 {
57     int i_x, i_y, i_x1, i_y1;
58     unsigned int i_dummy;
59
60     if( !b_average )
61     {
62         /* Please note that b_average will be expanded at compile time */
63
64         switch( i_select )
65         {
66         case 0:
67             /* !xh, !yh, !average */
68             for( i_y = 0; i_y < i_height; i_y += 4 )
69             {
70                 for( i_y1 = 0; i_y1 < 4; i_y1++ )
71                 {
72                     for( i_x = 0; i_x < i_width; i_x += 8 )
73                     {
74                          for( i_x1 = 0; i_x1 < 8; i_x1++ )
75                          {
76                              p_dest[i_x+i_x1] = p_src[i_x+i_x1];
77                          }
78                     }
79                     p_dest += i_stride;
80                     p_src += i_stride;
81                 }
82             }
83             break;
84
85         case 1:
86             /* xh, !yh, !average */
87             for( i_y = 0; i_y < i_height; i_y += 4 )
88             {
89                 for( i_y1 = 0; i_y1 < 4; i_y1++ )
90                 {
91                     for( i_x = 0; i_x < i_width; i_x += 8 )
92                     {
93                          for( i_x1 = 0; i_x1 < 8; i_x1++ )
94                          {
95                              p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1]
96                                                       + p_src[i_x+i_x1 + 1] + 1)
97                                                     >> 1;
98                          }
99                     }
100                     p_dest += i_stride;
101                     p_src += i_stride;
102                 }
103             }
104             break;
105
106         case 2:
107             /* !xh, yh, !average */
108             for( i_y = 0; i_y < i_height; i_y += 4 )
109             {
110                 for( i_y1 = 0; i_y1 < 4; i_y1++ )
111                 {
112                     for( i_x = 0; i_x < i_width; i_x += 8 )
113                     {
114                          for( i_x1 = 0; i_x1 < 8; i_x1++ )
115                          {
116                              p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1] + 1
117                                                 + p_src[i_x+i_x1 + i_step])
118                                               >> 1;
119                          }
120                     }
121                     p_dest += i_stride;
122                     p_src += i_stride;
123                 }
124             }
125             break;
126
127         case 3:
128             /* xh, yh, !average (3) */
129             for( i_y = 0; i_y < i_height; i_y += 4 )
130             {
131                 for( i_y1 = 0; i_y1 < 4; i_y1++ )
132                 {
133                     for( i_x = 0; i_x < i_width; i_x += 8 )
134                     {
135                          for( i_x1 = 0; i_x1 < 8; i_x1++ )
136                          {
137                              p_dest[i_x+i_x1]
138                                 = ((unsigned int)(
139                                       p_src[i_x+i_x1]
140                                     + p_src[i_x+i_x1 + 1]
141                                     + p_src[i_x+i_x1 + i_step]
142                                     + p_src[i_x+i_x1 + i_step + 1]
143                                     + 2) >> 2);
144                          }
145                     }
146                     p_dest += i_stride;
147                     p_src += i_stride;
148                 }
149             }
150             break;
151         }
152
153     }
154     else
155     {
156         /* b_average */
157         switch( i_select )
158         {
159         case 0:
160             /* !xh, !yh, average */
161             for( i_y = 0; i_y < i_height; i_y += 4 )
162             {
163                 for( i_y1 = 0; i_y1 < 4; i_y1++ )
164                 {
165                     for( i_x = 0; i_x < i_width; i_x += 8 )
166                     {
167                          for( i_x1 = 0; i_x1 < 8; i_x1++ )
168                          {
169                              i_dummy = p_dest[i_x + i_x1] + p_src[i_x + i_x1];
170                              p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
171                          }
172                     }
173                     p_dest += i_stride;
174                     p_src += i_stride;
175                 }
176             }
177             break;
178
179         case 1:
180             /* xh, !yh, average */
181             for( i_y = 0; i_y < i_height; i_y += 4 )
182             {
183                 for( i_y1 = 0; i_y1 < 4; i_y1++ )
184                 {
185                     for( i_x = 0; i_x < i_width; i_x += 8 )
186                     {
187                          for( i_x1 = 0; i_x1 < 8; i_x1++ )
188                          {
189                              i_dummy = p_dest[i_x+i_x1]
190                                 + ((unsigned int)(p_src[i_x+i_x1]
191                                                   + p_src[i_x+i_x1 + 1] + 1) >> 1);
192                              p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
193                          }
194                     }
195                     p_dest += i_stride;
196                     p_src += i_stride;
197                 }
198             }
199             break;
200
201         case 2:
202             /* !xh, yh, average */
203             for( i_y = 0; i_y < i_height; i_y += 4 )
204             {
205                 for( i_y1 = 0; i_y1 < 4; i_y1++ )
206                 {
207                     for( i_x = 0; i_x < i_width; i_x += 8 )
208                     {
209                          for( i_x1 = 0; i_x1 < 8; i_x1++ )
210                          {
211                              i_dummy = p_dest[i_x+i_x1]
212                                 + ((unsigned int)(p_src[i_x+i_x1] + 1
213                                          + p_src[i_x+i_x1 + i_step]) >> 1);
214                              p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
215                          }
216                     }
217                     p_dest += i_stride;
218                     p_src += i_stride;
219                 }
220             }
221             break;
222
223         case 3:
224             /* xh, yh, average */
225             for( i_y = 0; i_y < i_height; i_y += 4 )
226             {
227                 for( i_y1 = 0; i_y1 < 4; i_y1++ )
228                 {
229                     for( i_x = 0; i_x < i_width; i_x += 8 )
230                     {
231                          for( i_x1 = 0; i_x1 < 8; i_x1++ )
232                          {
233                              i_dummy = p_dest[i_x+i_x1]
234                                 + ((unsigned int)(
235                                       p_src[i_x+i_x1]
236                                     + p_src[i_x+i_x1 + 1]
237                                     + p_src[i_x+i_x1 + i_step]
238                                     + p_src[i_x+i_x1 + i_step + 1]
239                                     + 2) >> 2);
240                              p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
241                          }
242                     }
243                     p_dest += i_stride;
244                     p_src += i_stride;
245                 }
246             }
247             break;
248         }
249     }
250 }
251
252 /*****************************************************************************
253  * Motion420 : motion compensation for a 4:2:0 macroblock
254  *****************************************************************************/
255 static __inline__ void Motion420(
256                     macroblock_t * p_mb,        /* destination macroblock */
257                     picture_t * p_source,       /* source picture */
258                     boolean_t b_source_field,   /* source field */
259                     boolean_t b_dest_field,     /* destination field */
260                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
261                                                  * in half pels */
262                     int i_l_stride,             /* number of coeffs to jump to
263                                                  * go to the next predicted
264                                                  * line */
265                     int i_c_stride,
266                     int i_height,               /* height of the block to
267                                                  * predict, in luminance
268                                                  * (explicit) */
269                     int i_offset,               /* position of the first
270                                                  * predicted line (explicit) */
271                     boolean_t b_average         /* (explicit) averaging of
272                                                  * several predictions */ )
273 {
274     /* Temporary variables to avoid recalculating things twice */
275     int     i_source_offset, i_dest_offset, i_c_height, i_c_select;
276
277     i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
278                        + (p_mb->i_motion_l_y + i_offset
279                          + (i_mv_y >> 1)
280                          + b_source_field)
281                          * p_mb->p_picture->i_width;
282     if( i_source_offset >= p_source->i_width * p_source->i_height )
283     {
284         fprintf( stderr, "vdec error: bad motion vector\n" );
285         return;
286     }
287
288     /* Luminance */
289     MotionComponent( /* source */
290                      p_source->p_y + i_source_offset,
291                      /* destination */
292                      p_mb->p_picture->p_y
293                        + (p_mb->i_l_x)
294                        + (p_mb->i_motion_l_y + b_dest_field)
295                          * p_mb->p_picture->i_width,
296                      /* prediction width and height */
297                      16, i_height,
298                      /* stride */
299                      i_l_stride, p_mb->i_l_stride,
300                      /* select */
301                      ((i_mv_y & 1) << 1) | (i_mv_x & 1),
302                      b_average );
303
304     i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
305                         + ((p_mb->i_motion_c_y + (i_offset >> 1)
306                            + ((i_mv_y/2) >> 1))
307                            + b_source_field)
308                           * p_mb->p_picture->i_chroma_width;
309     if( i_source_offset >= (p_source->i_width * p_source->i_height) / 4 )
310     {
311         fprintf( stderr, "vdec error: bad motion vector\n" );
312         return;
313     }
314
315     i_dest_offset = (p_mb->i_c_x)
316                       + (p_mb->i_motion_c_y + b_dest_field)
317                         * p_mb->p_picture->i_chroma_width;
318     i_c_height = i_height >> 1;
319     i_c_select = (((i_mv_y/2) & 1) << 1) | ((i_mv_x/2) & 1);
320
321     /* Chrominance Cr */
322     MotionComponent( p_source->p_u
323                        + i_source_offset,
324                      p_mb->p_picture->p_u
325                        + i_dest_offset,
326                      8, i_c_height, i_c_stride, p_mb->i_c_stride,
327                      i_c_select, b_average );
328
329     /* Chrominance Cb */
330     MotionComponent( p_source->p_v
331                        + i_source_offset,
332                      p_mb->p_picture->p_v
333                        + i_dest_offset,
334                      8, i_c_height, i_c_stride, p_mb->i_c_stride,
335                      i_c_select, b_average );
336 }
337
338 /*****************************************************************************
339  * Motion422 : motion compensation for a 4:2:2 macroblock
340  *****************************************************************************/
341 static __inline__ void Motion422(
342                     macroblock_t * p_mb,        /* destination macroblock */
343                     picture_t * p_source,       /* source picture */
344                     boolean_t b_source_field,   /* source field */
345                     boolean_t b_dest_field,     /* destination field */
346                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
347                                                  * in half pels */
348                     int i_l_stride,             /* number of coeffs to jump to
349                                                  * go to the next predicted
350                                                  * line */
351                     int i_c_stride,
352                     int i_height,               /* height of the block to
353                                                  * predict, in luminance
354                                                  * (explicit) */
355                     int i_offset,               /* position of the first
356                                                  * predicted line (explicit) */
357                     boolean_t b_average         /* (explicit) averaging of
358                                                  * several predictions */ )
359 {
360 #if 0
361     int     i_source_offset, i_dest_offset, i_c_select;
362
363     /* Luminance */
364     MotionComponent( /* source */
365                      p_source->p_y
366                        + (p_mb->i_l_x + (i_mv_x >> 1))
367                        + (p_mb->i_motion_l_y + i_offset
368                           + (i_mv_y >> 1)
369                           + b_source_field)
370                          * p_mb->p_picture->i_width,
371                      /* destination */
372                      p_mb->p_picture->p_y
373                        + (p_mb->i_l_x)
374                        + (p_mb->i_motion_l_y + b_dest_field)
375                          * p_mb->p_picture->i_width,
376                      /* prediction width and height */
377                      16, i_height,
378                      /* stride */
379                      i_l_stride, p_mb->i_l_stride,
380                      /* select */
381                      ((i_mv_y & 1) << 1) | (i_mv_x & 1),
382                      b_average );
383
384     i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
385                         + ((p_mb->i_motion_c_y + (i_offset)
386                            + ((i_mv_y) >> 1))
387                            + b_source_field)
388                           * p_mb->p_picture->i_chroma_width;
389     i_dest_offset = (p_mb->i_c_x)
390                       + (p_mb->i_motion_c_y + b_dest_field)
391                         * p_mb->p_picture->i_chroma_width;
392     i_c_select = ((i_mv_y & 1) << 1) | ((i_mv_x/2) & 1);
393
394     /* Chrominance Cr */
395     MotionComponent( p_source->p_u
396                        + i_source_offset,
397                      p_mb->p_picture->p_u
398                        + i_dest_offset,
399                      8, i_height, i_c_stride, p_mb->i_c_stride,
400                      i_c_select, b_average );
401
402     /* Chrominance Cb */
403     MotionComponent( p_source->p_v
404                        + i_source_offset,
405                      p_mb->p_picture->p_u
406                        + i_dest_offset,
407                      8, i_height, i_c_stride, p_mb->i_c_stride,
408                      i_c_select, b_average );
409 #endif
410 }
411
412 /*****************************************************************************
413  * Motion444 : motion compensation for a 4:4:4 macroblock
414  *****************************************************************************/
415 static __inline__ void Motion444(
416                     macroblock_t * p_mb,        /* destination macroblock */
417                     picture_t * p_source,       /* source picture */
418                     boolean_t b_source_field,   /* source field */
419                     boolean_t b_dest_field,     /* destination field */
420                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
421                                                  * in half pels */
422                     int i_l_stride,             /* number of coeffs to jump to
423                                                  * go to the next predicted
424                                                  * line */
425                     int i_c_stride,
426                     int i_height,               /* height of the block to
427                                                  * predict, in luminance
428                                                  * (explicit) */
429                     int i_offset,               /* position of the first
430                                                  * predicted line (explicit) */
431                     boolean_t b_average         /* (explicit) averaging of
432                                                  * several predictions */ )
433 {
434 #if 0
435     int     i_source_offset, i_dest_offset, i_select;
436
437     i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
438                         + (p_mb->i_motion_l_y + i_offset
439                            + (i_mv_y >> 1)
440                            + b_source_field)
441                           * p_mb->p_picture->i_width;
442     i_dest_offset = (p_mb->i_l_x)
443                       + (p_mb->i_motion_l_y + b_dest_field)
444                         * p_mb->p_picture->i_width;
445     i_select = ((i_mv_y & 1) << 1) | (i_mv_x & 1);
446
447
448     /* Luminance */
449     MotionComponent( p_source->p_y
450                        + i_source_offset,
451                      p_mb->p_picture->p_y
452                        + i_dest_offset,
453                      16, i_height, i_l_stride, p_mb->i_l_stride,
454                      i_select, b_average );
455
456     /* Chrominance Cr */
457     MotionComponent( p_source->p_u
458                        + i_source_offset,
459                      p_mb->p_picture->p_u
460                        + i_dest_offset,
461                      16, i_height, i_l_stride, p_mb->i_l_stride,
462                      i_select, b_average );
463
464     /* Chrominance Cb */
465     MotionComponent( p_source->p_v
466                        + i_source_offset,
467                      p_mb->p_picture->p_v
468                        + i_dest_offset,
469                      16, i_height, i_l_stride, p_mb->i_l_stride,
470                      i_select, b_average );
471 #endif
472 }
473
474 /*****************************************************************************
475  * vdec_MotionFieldField : motion compensation for field motion type (field)
476  *****************************************************************************/
477 #define FIELDFIELD( MOTION )                                            \
478     picture_t *     p_pred;                                             \
479                                                                         \
480     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
481     {                                                                   \
482         if( p_mb->b_P_second                                            \
483              && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
484             p_pred = p_mb->p_picture;                                   \
485         else                                                            \
486             p_pred = p_mb->p_forward;                                   \
487                                                                         \
488         MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0],             \
489                 p_mb->b_motion_field,                                   \
490                 p_mb->pppi_motion_vectors[0][0][0],                     \
491                 p_mb->pppi_motion_vectors[0][0][1],                     \
492                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
493                                                                         \
494         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
495         {                                                               \
496             MOTION( p_mb, p_mb->p_backward,                             \
497                     p_mb->ppi_field_select[0][1],                       \
498                     p_mb->b_motion_field,                               \
499                     p_mb->pppi_motion_vectors[0][1][0],                 \
500                     p_mb->pppi_motion_vectors[0][1][1],                 \
501                     p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );     \
502     }                                                                   \
503                                                                         \
504     else /* MB_MOTION_BACKWARD */                                       \
505     {                                                                   \
506         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1],   \
507                 p_mb->b_motion_field,                                   \
508                 p_mb->pppi_motion_vectors[0][1][0],                     \
509                 p_mb->pppi_motion_vectors[0][1][1],                     \
510                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
511     }                                                                   \
512 }
513
514 void vdec_MotionFieldField420( macroblock_t * p_mb )
515 {
516     FIELDFIELD( Motion420 )
517 }
518
519 void vdec_MotionFieldField422( macroblock_t * p_mb )
520 {
521     //FIELDFIELD( Motion422 )
522 }
523
524 void vdec_MotionFieldField444( macroblock_t * p_mb )
525 {
526     //FIELDFIELD( Motion444 )
527 }
528
529 /*****************************************************************************
530  * vdec_MotionField16x8XXX : motion compensation for 16x8 motion type (field)
531  *****************************************************************************/
532 #define FIELD16X8( MOTION )                                             \
533 {                                                                       \
534     picture_t *     p_pred;                                             \
535                                                                         \
536     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
537     {                                                                   \
538         if( p_mb->b_P_second                                            \
539              && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
540             p_pred = p_mb->p_picture;                                   \
541         else                                                            \
542             p_pred = p_mb->p_forward;                                   \
543                                                                         \
544         MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0],             \
545                 p_mb->b_motion_field,                                   \
546                 p_mb->pppi_motion_vectors[0][0][0],                     \
547                 p_mb->pppi_motion_vectors[0][0][1],                     \
548                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 );          \
549                                                                         \
550         if( p_mb->b_P_second                                            \
551              && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\
552             p_pred = p_mb->p_picture;                                   \
553         else                                                            \
554             p_pred = p_mb->p_forward;                                   \
555                                                                         \
556         MOTION( p_mb, p_pred, p_mb->ppi_field_select[1][0],             \
557                 p_mb->b_motion_field,                                   \
558                 p_mb->pppi_motion_vectors[1][0][0],                     \
559                 p_mb->pppi_motion_vectors[1][0][1],                     \
560                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 );          \
561                                                                         \
562         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
563         {                                                               \
564             MOTION( p_mb, p_mb->p_backward,                             \
565                     p_mb->ppi_field_select[0][1],                       \
566                     p_mb->b_motion_field,                               \
567                     p_mb->pppi_motion_vectors[0][1][0],                 \
568                     p_mb->pppi_motion_vectors[0][1][1],                 \
569                     p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 1 );      \
570                                                                         \
571             MOTION( p_mb, p_mb->p_backward,                             \
572                     p_mb->ppi_field_select[1][1],                       \
573                     p_mb->b_motion_field,                               \
574                     p_mb->pppi_motion_vectors[1][1][0],                 \
575                     p_mb->pppi_motion_vectors[1][1][1],                 \
576                     p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 1 );      \
577         }                                                               \
578     }                                                                   \
579                                                                         \
580     else /* MB_MOTION_BACKWARD */                                       \
581     {                                                                   \
582         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1],   \
583                 p_mb->b_motion_field,                                   \
584                 p_mb->pppi_motion_vectors[0][1][0],                     \
585                 p_mb->pppi_motion_vectors[0][1][1],                     \
586                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 );          \
587                                                                         \
588         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1],   \
589                 p_mb->b_motion_field,                                   \
590                 p_mb->pppi_motion_vectors[1][1][0],                     \
591                 p_mb->pppi_motion_vectors[1][1][1],                     \
592                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 );          \
593     }                                                                   \
594 }
595
596 void vdec_MotionField16x8420( macroblock_t * p_mb )
597 {
598     FIELD16X8( Motion420 )
599 }
600
601 void vdec_MotionField16x8422( macroblock_t * p_mb )
602 {
603     //FIELD16X8( Motion422 )
604 }
605
606 void vdec_MotionField16x8444( macroblock_t * p_mb )
607 {
608     //FIELD16X8( Motion444 )
609 }
610
611 /*****************************************************************************
612  * vdec_MotionFieldDMVXXX : motion compensation for dmv motion type (field)
613  *****************************************************************************/
614 #define FIELDDMV( MOTION )                                              \
615 {                                                                       \
616     /* This is necessarily a MOTION_FORWARD only macroblock, in a P     \
617      * picture. */                                                      \
618     picture_t *     p_pred;                                             \
619                                                                         \
620     /* predict from field of same parity */                             \
621     MOTION( p_mb, p_mb->p_forward,                                      \
622             p_mb->b_motion_field, p_mb->b_motion_field,                 \
623             p_mb->pppi_motion_vectors[0][0][0],                         \
624             p_mb->pppi_motion_vectors[0][0][1],                         \
625             p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );             \
626                                                                         \
627     if( p_mb->b_P_second )                                              \
628         p_pred = p_mb->p_picture;                                       \
629     else                                                                \
630         p_pred = p_mb->p_forward;                                       \
631                                                                         \
632     /* predict from field of opposite parity */                         \
633     MOTION( p_mb, p_pred, !p_mb->b_motion_field, p_mb->b_motion_field,  \
634             p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1],                   \
635             p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );             \
636 } /* FIELDDMV */
637
638 void vdec_MotionFieldDMV420( macroblock_t * p_mb )
639 {
640     FIELDDMV( Motion420 )
641 }
642
643 void vdec_MotionFieldDMV422( macroblock_t * p_mb )
644 {
645     //FIELDDMV( Motion422 )
646 }
647
648 void vdec_MotionFieldDMV444( macroblock_t * p_mb )
649 {
650     //FIELDDMV( Motion444 )
651 }
652
653 /*****************************************************************************
654  * vdec_MotionFrameFrameXXX : motion compensation for frame motion type (frame)
655  *****************************************************************************/
656 #define FRAMEFRAME( MOTION )                                            \
657 {                                                                       \
658     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
659     {                                                                   \
660         MOTION( p_mb, p_mb->p_forward, 0, 0,                            \
661                 p_mb->pppi_motion_vectors[0][0][0],                     \
662                 p_mb->pppi_motion_vectors[0][0][1],                     \
663                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
664                                                                         \
665         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
666         {                                                               \
667             MOTION( p_mb, p_mb->p_backward, 0, 0,                       \
668                     p_mb->pppi_motion_vectors[0][1][0],                 \
669                     p_mb->pppi_motion_vectors[0][1][1],                 \
670                     p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );     \
671         }                                                               \
672     }                                                                   \
673                                                                         \
674     else /* MB_MOTION_BACKWARD */                                       \
675     {                                                                   \
676         MOTION( p_mb, p_mb->p_backward, 0, 0,                           \
677                 p_mb->pppi_motion_vectors[0][1][0],                     \
678                 p_mb->pppi_motion_vectors[0][1][1],                     \
679                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
680     }                                                                   \
681 } /* FRAMEFRAME */
682
683 void vdec_MotionFrameFrame420( macroblock_t * p_mb )
684 {
685     FRAMEFRAME( Motion420 )
686 }
687
688 void vdec_MotionFrameFrame422( macroblock_t * p_mb )
689 {
690     //FRAMEFRAME( Motion422 )
691 }
692
693 void vdec_MotionFrameFrame444( macroblock_t * p_mb )
694 {
695     //FRAMEFRAME( Motion444 )
696 }
697
698 /*****************************************************************************
699  * vdec_MotionFrameFieldXXX : motion compensation for field motion type (frame)
700  *****************************************************************************/
701 #define FRAMEFIELD( MOTION )                                            \
702 {                                                                       \
703     int i_l_stride = p_mb->i_l_stride << 1;                             \
704     int i_c_stride = p_mb->i_c_stride << 1;                             \
705                                                                         \
706     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
707     {                                                                   \
708         MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[0][0], 0, \
709                 p_mb->pppi_motion_vectors[0][0][0],                     \
710                 p_mb->pppi_motion_vectors[0][0][1],                     \
711                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
712                                                                         \
713         MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[1][0], 1, \
714                 p_mb->pppi_motion_vectors[1][0][0],                     \
715                 p_mb->pppi_motion_vectors[1][0][1],                     \
716                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
717                                                                         \
718         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
719         {                                                               \
720             MOTION( p_mb, p_mb->p_backward,                             \
721                     p_mb->ppi_field_select[0][1], 0,                    \
722                     p_mb->pppi_motion_vectors[0][1][0],                 \
723                     p_mb->pppi_motion_vectors[0][1][1],                 \
724                     i_l_stride, i_c_stride, 8, 0, 1 );                  \
725                                                                         \
726             MOTION( p_mb, p_mb->p_backward,                             \
727                     p_mb->ppi_field_select[1][1], 1,                    \
728                     p_mb->pppi_motion_vectors[1][1][0],                 \
729                     p_mb->pppi_motion_vectors[1][1][1],                 \
730                     i_l_stride, i_c_stride, 8, 0, 1 );                  \
731         }                                                               \
732     }                                                                   \
733                                                                         \
734     else /* MB_MOTION_BACKWARD only */                                  \
735     {                                                                   \
736         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], 0,\
737                 p_mb->pppi_motion_vectors[0][1][0],                     \
738                 p_mb->pppi_motion_vectors[0][1][1],                     \
739                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
740                                                                         \
741         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], 1,\
742                 p_mb->pppi_motion_vectors[1][1][0],                     \
743                 p_mb->pppi_motion_vectors[1][1][1],                     \
744                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
745     }                                                                   \
746 } /* FRAMEFIELD */
747
748 void vdec_MotionFrameField420( macroblock_t * p_mb )
749 {
750     FRAMEFIELD( Motion420 )
751 }
752
753 void vdec_MotionFrameField422( macroblock_t * p_mb )
754 {
755     //FRAMEFIELD( Motion422 )
756 }
757
758 void vdec_MotionFrameField444( macroblock_t * p_mb )
759 {
760     //FRAMEFIELD( Motion444 )
761 }
762
763 /*****************************************************************************
764  * vdec_MotionFrameDMVXXX : motion compensation for dmv motion type (frame)
765  *****************************************************************************/
766 #define FRAMEDMV( MOTION )                                              \
767 {                                                                       \
768     /* This is necessarily a MOTION_FORWARD only macroblock, in a P     \
769      * picture. */                                                      \
770                                                                         \
771     /* predict top field from top field */                              \
772     MOTION( p_mb, p_mb->p_forward, 0, 0,                                \
773             p_mb->pppi_motion_vectors[0][0][0],                         \
774             p_mb->pppi_motion_vectors[0][0][1],                         \
775             /* ????? >> 1 ? */                                          \
776             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 );    \
777                                                                         \
778     /* predict and add to top field from bottom field */                \
779     MOTION( p_mb, p_mb->p_forward, 1, 0,                                \
780             p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1],                   \
781             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 );    \
782                                                                         \
783     /* predict bottom field from bottom field */                        \
784     MOTION( p_mb, p_mb->p_forward, 1, 1,                                \
785             p_mb->pppi_motion_vectors[0][0][0],                         \
786             p_mb->pppi_motion_vectors[0][0][1],                         \
787             /* ????? >> 1 ? */                                          \
788             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 );    \
789                                                                         \
790     /* predict and add to bottom field from top field */                \
791     MOTION( p_mb, p_mb->p_forward, 1, 0,                                \
792             p_mb->ppi_dmv[1][0], p_mb->ppi_dmv[1][1],                   \
793             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 );    \
794 } /* FRAMEDMV */
795
796 void vdec_MotionFrameDMV420( macroblock_t * p_mb )
797 {
798     FRAMEDMV( Motion420 )
799 }
800
801 void vdec_MotionFrameDMV422( macroblock_t * p_mb )
802 {
803     //FRAMEDMV( Motion422 )
804 }
805
806 void vdec_MotionFrameDMV444( macroblock_t * p_mb )
807 {
808     //FRAMEDMV( Motion444 )
809 }