]> git.sesse.net Git - vlc/blob - src/video_decoder/vdec_motion.c
46a93e3f90dcb389b6f5a5c5a6710d0b65b25044
[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     /* Luminance */
278     MotionComponent( /* source */
279                      p_source->p_y
280                        + (p_mb->i_l_x + (i_mv_x >> 1))
281                        + (p_mb->i_motion_l_y + i_offset
282                           + (i_mv_y >> 1)
283                           + b_source_field)
284                          * p_mb->p_picture->i_width,
285                      /* destination */
286                      p_mb->p_picture->p_y
287                        + (p_mb->i_l_x)
288                        + (p_mb->i_motion_l_y + b_dest_field)
289                          * p_mb->p_picture->i_width,
290                      /* prediction width and height */
291                      16, i_height,
292                      /* stride */
293                      i_l_stride, p_mb->i_l_stride,
294                      /* select */
295                      ((i_mv_y & 1) << 1) | (i_mv_x & 1),
296                      b_average );
297
298     i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
299                         + ((p_mb->i_motion_c_y + (i_offset >> 1)
300                            + ((i_mv_y/2) >> 1))
301                            + b_source_field)
302                           * p_mb->p_picture->i_chroma_width;
303     i_dest_offset = (p_mb->i_c_x)
304                       + (p_mb->i_motion_c_y + b_dest_field)
305                         * p_mb->p_picture->i_chroma_width;
306     i_c_height = i_height >> 1;
307     i_c_select = (((i_mv_y/2) & 1) << 1) | ((i_mv_x/2) & 1);
308
309     /* Chrominance Cr */
310     MotionComponent( p_source->p_u
311                        + i_source_offset,
312                      p_mb->p_picture->p_u
313                        + i_dest_offset,
314                      8, i_c_height, i_c_stride, p_mb->i_c_stride,
315                      i_c_select, b_average );
316
317     /* Chrominance Cb */
318     MotionComponent( p_source->p_v
319                        + i_source_offset,
320                      p_mb->p_picture->p_v
321                        + i_dest_offset,
322                      8, i_c_height, i_c_stride, p_mb->i_c_stride,
323                      i_c_select, b_average );
324 }
325
326 /*****************************************************************************
327  * Motion422 : motion compensation for a 4:2:2 macroblock
328  *****************************************************************************/
329 static __inline__ void Motion422(
330                     macroblock_t * p_mb,        /* destination macroblock */
331                     picture_t * p_source,       /* source picture */
332                     boolean_t b_source_field,   /* source field */
333                     boolean_t b_dest_field,     /* destination field */
334                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
335                                                  * in half pels */
336                     int i_l_stride,             /* number of coeffs to jump to
337                                                  * go to the next predicted
338                                                  * line */
339                     int i_c_stride,
340                     int i_height,               /* height of the block to
341                                                  * predict, in luminance
342                                                  * (explicit) */
343                     int i_offset,               /* position of the first
344                                                  * predicted line (explicit) */
345                     boolean_t b_average         /* (explicit) averaging of
346                                                  * several predictions */ )
347 {
348     int     i_source_offset, i_dest_offset, i_c_select;
349
350     /* Luminance */
351     MotionComponent( /* source */
352                      p_source->p_y
353                        + (p_mb->i_l_x + (i_mv_x >> 1))
354                        + (p_mb->i_motion_l_y + i_offset
355                           + (i_mv_y >> 1)
356                           + b_source_field)
357                          * p_mb->p_picture->i_width,
358                      /* destination */
359                      p_mb->p_picture->p_y
360                        + (p_mb->i_l_x)
361                        + (p_mb->i_motion_l_y + b_dest_field)
362                          * p_mb->p_picture->i_width,
363                      /* prediction width and height */
364                      16, i_height,
365                      /* stride */
366                      i_l_stride, p_mb->i_l_stride,
367                      /* select */
368                      ((i_mv_y & 1) << 1) | (i_mv_x & 1),
369                      b_average );
370
371     i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
372                         + ((p_mb->i_motion_c_y + (i_offset)
373                            + ((i_mv_y) >> 1))
374                            + b_source_field)
375                           * p_mb->p_picture->i_chroma_width;
376     i_dest_offset = (p_mb->i_c_x)
377                       + (p_mb->i_motion_c_y + b_dest_field)
378                         * p_mb->p_picture->i_chroma_width;
379     i_c_select = ((i_mv_y & 1) << 1) | ((i_mv_x/2) & 1);
380
381     /* Chrominance Cr */
382     MotionComponent( p_source->p_u
383                        + i_source_offset,
384                      p_mb->p_picture->p_u
385                        + i_dest_offset,
386                      8, i_height, i_c_stride, p_mb->i_c_stride,
387                      i_c_select, b_average );
388
389     /* Chrominance Cb */
390     MotionComponent( p_source->p_v
391                        + i_source_offset,
392                      p_mb->p_picture->p_u
393                        + i_dest_offset,
394                      8, i_height, i_c_stride, p_mb->i_c_stride,
395                      i_c_select, b_average );
396 }
397
398 /*****************************************************************************
399  * Motion444 : motion compensation for a 4:4:4 macroblock
400  *****************************************************************************/
401 static __inline__ void Motion444(
402                     macroblock_t * p_mb,        /* destination macroblock */
403                     picture_t * p_source,       /* source picture */
404                     boolean_t b_source_field,   /* source field */
405                     boolean_t b_dest_field,     /* destination field */
406                     int i_mv_x, int i_mv_y,     /* motion vector coordinates,
407                                                  * in half pels */
408                     int i_l_stride,             /* number of coeffs to jump to
409                                                  * go to the next predicted
410                                                  * line */
411                     int i_c_stride,
412                     int i_height,               /* height of the block to
413                                                  * predict, in luminance
414                                                  * (explicit) */
415                     int i_offset,               /* position of the first
416                                                  * predicted line (explicit) */
417                     boolean_t b_average         /* (explicit) averaging of
418                                                  * several predictions */ )
419 {
420     int     i_source_offset, i_dest_offset, i_select;
421
422     i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
423                         + (p_mb->i_motion_l_y + i_offset
424                            + (i_mv_y >> 1)
425                            + b_source_field)
426                           * p_mb->p_picture->i_width;
427     i_dest_offset = (p_mb->i_l_x)
428                       + (p_mb->i_motion_l_y + b_dest_field)
429                         * p_mb->p_picture->i_width;
430     i_select = ((i_mv_y & 1) << 1) | (i_mv_x & 1);
431
432
433     /* Luminance */
434     MotionComponent( p_source->p_y
435                        + i_source_offset,
436                      p_mb->p_picture->p_y
437                        + i_dest_offset,
438                      16, i_height, i_l_stride, p_mb->i_l_stride,
439                      i_select, b_average );
440
441     /* Chrominance Cr */
442     MotionComponent( p_source->p_u
443                        + i_source_offset,
444                      p_mb->p_picture->p_u
445                        + i_dest_offset,
446                      16, i_height, i_l_stride, p_mb->i_l_stride,
447                      i_select, b_average );
448
449     /* Chrominance Cb */
450     MotionComponent( p_source->p_v
451                        + i_source_offset,
452                      p_mb->p_picture->p_v
453                        + i_dest_offset,
454                      16, i_height, i_l_stride, p_mb->i_l_stride,
455                      i_select, b_average );
456 }
457
458 /*****************************************************************************
459  * vdec_MotionFieldField : motion compensation for field motion type (field)
460  *****************************************************************************/
461 #define FIELDFIELD( MOTION )                                            \
462     picture_t *     p_pred;                                             \
463                                                                         \
464     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
465     {                                                                   \
466         if( p_mb->b_P_second                                            \
467              && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
468             p_pred = p_mb->p_picture;                                   \
469         else                                                            \
470             p_pred = p_mb->p_forward;                                   \
471                                                                         \
472         MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0],             \
473                 p_mb->b_motion_field,                                   \
474                 p_mb->pppi_motion_vectors[0][0][0],                     \
475                 p_mb->pppi_motion_vectors[0][0][1],                     \
476                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
477                                                                         \
478         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
479         {                                                               \
480             MOTION( p_mb, p_mb->p_backward,                             \
481                     p_mb->ppi_field_select[0][1],                       \
482                     p_mb->b_motion_field,                               \
483                     p_mb->pppi_motion_vectors[0][1][0],                 \
484                     p_mb->pppi_motion_vectors[0][1][1],                 \
485                     p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );     \
486     }                                                                   \
487                                                                         \
488     else /* MB_MOTION_BACKWARD */                                       \
489     {                                                                   \
490         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1],   \
491                 p_mb->b_motion_field,                                   \
492                 p_mb->pppi_motion_vectors[0][1][0],                     \
493                 p_mb->pppi_motion_vectors[0][1][1],                     \
494                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
495     }                                                                   \
496 }
497
498 void vdec_MotionFieldField420( macroblock_t * p_mb )
499 {
500     FIELDFIELD( Motion420 )
501 }
502
503 void vdec_MotionFieldField422( macroblock_t * p_mb )
504 {
505     FIELDFIELD( Motion422 )
506 }
507
508 void vdec_MotionFieldField444( macroblock_t * p_mb )
509 {
510     FIELDFIELD( Motion444 )
511 }
512
513 /*****************************************************************************
514  * vdec_MotionField16x8XXX : motion compensation for 16x8 motion type (field)
515  *****************************************************************************/
516 #define FIELD16X8( MOTION )                                             \
517 {                                                                       \
518     picture_t *     p_pred;                                             \
519                                                                         \
520     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
521     {                                                                   \
522         if( p_mb->b_P_second                                            \
523              && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
524             p_pred = p_mb->p_picture;                                   \
525         else                                                            \
526             p_pred = p_mb->p_forward;                                   \
527                                                                         \
528         MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0],             \
529                 p_mb->b_motion_field,                                   \
530                 p_mb->pppi_motion_vectors[0][0][0],                     \
531                 p_mb->pppi_motion_vectors[0][0][1],                     \
532                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 );          \
533                                                                         \
534         if( p_mb->b_P_second                                            \
535              && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\
536             p_pred = p_mb->p_picture;                                   \
537         else                                                            \
538             p_pred = p_mb->p_forward;                                   \
539                                                                         \
540         MOTION( p_mb, p_pred, p_mb->ppi_field_select[1][0],             \
541                 p_mb->b_motion_field,                                   \
542                 p_mb->pppi_motion_vectors[1][0][0],                     \
543                 p_mb->pppi_motion_vectors[1][0][1],                     \
544                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 );          \
545                                                                         \
546         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
547         {                                                               \
548             MOTION( p_mb, p_mb->p_backward,                             \
549                     p_mb->ppi_field_select[0][1],                       \
550                     p_mb->b_motion_field,                               \
551                     p_mb->pppi_motion_vectors[0][1][0],                 \
552                     p_mb->pppi_motion_vectors[0][1][1],                 \
553                     p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 1 );      \
554                                                                         \
555             MOTION( p_mb, p_mb->p_backward,                             \
556                     p_mb->ppi_field_select[1][1],                       \
557                     p_mb->b_motion_field,                               \
558                     p_mb->pppi_motion_vectors[1][1][0],                 \
559                     p_mb->pppi_motion_vectors[1][1][1],                 \
560                     p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 1 );      \
561         }                                                               \
562     }                                                                   \
563                                                                         \
564     else /* MB_MOTION_BACKWARD */                                       \
565     {                                                                   \
566         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1],   \
567                 p_mb->b_motion_field,                                   \
568                 p_mb->pppi_motion_vectors[0][1][0],                     \
569                 p_mb->pppi_motion_vectors[0][1][1],                     \
570                 p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 );          \
571                                                                         \
572         MOTION( p_mb, p_mb->p_backward, 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, 0 );          \
577     }                                                                   \
578 }
579
580 void vdec_MotionField16x8420( macroblock_t * p_mb )
581 {
582     FIELD16X8( Motion420 )
583 }
584
585 void vdec_MotionField16x8422( macroblock_t * p_mb )
586 {
587     FIELD16X8( Motion422 )
588 }
589
590 void vdec_MotionField16x8444( macroblock_t * p_mb )
591 {
592     FIELD16X8( Motion444 )
593 }
594
595 /*****************************************************************************
596  * vdec_MotionFieldDMVXXX : motion compensation for dmv motion type (field)
597  *****************************************************************************/
598 #define FIELDDMV( MOTION )                                              \
599 {                                                                       \
600     /* This is necessarily a MOTION_FORWARD only macroblock, in a P     \
601      * picture. */                                                      \
602     picture_t *     p_pred;                                             \
603                                                                         \
604     /* predict from field of same parity */                             \
605     MOTION( p_mb, p_mb->p_forward,                                      \
606             p_mb->b_motion_field, p_mb->b_motion_field,                 \
607             p_mb->pppi_motion_vectors[0][0][0],                         \
608             p_mb->pppi_motion_vectors[0][0][1],                         \
609             p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );             \
610                                                                         \
611     if( p_mb->b_P_second )                                              \
612         p_pred = p_mb->p_picture;                                       \
613     else                                                                \
614         p_pred = p_mb->p_forward;                                       \
615                                                                         \
616     /* predict from field of opposite parity */                         \
617     MOTION( p_mb, p_pred, !p_mb->b_motion_field, p_mb->b_motion_field,  \
618             p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1],                   \
619             p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );             \
620 } /* FIELDDMV */
621
622 void vdec_MotionFieldDMV420( macroblock_t * p_mb )
623 {
624     FIELDDMV( Motion420 )
625 }
626
627 void vdec_MotionFieldDMV422( macroblock_t * p_mb )
628 {
629     FIELDDMV( Motion422 )
630 }
631
632 void vdec_MotionFieldDMV444( macroblock_t * p_mb )
633 {
634     FIELDDMV( Motion444 )
635 }
636
637 /*****************************************************************************
638  * vdec_MotionFrameFrameXXX : motion compensation for frame motion type (frame)
639  *****************************************************************************/
640 #define FRAMEFRAME( MOTION )                                            \
641 {                                                                       \
642     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
643     {                                                                   \
644         MOTION( p_mb, p_mb->p_forward, 0, 0,                            \
645                 p_mb->pppi_motion_vectors[0][0][0],                     \
646                 p_mb->pppi_motion_vectors[0][0][1],                     \
647                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
648                                                                         \
649         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
650         {                                                               \
651             MOTION( p_mb, p_mb->p_backward, 0, 0,                       \
652                     p_mb->pppi_motion_vectors[0][1][0],                 \
653                     p_mb->pppi_motion_vectors[0][1][1],                 \
654                     p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );     \
655         }                                                               \
656     }                                                                   \
657                                                                         \
658     else /* MB_MOTION_BACKWARD */                                       \
659     {                                                                   \
660         MOTION( p_mb, p_mb->p_backward, 0, 0,                           \
661                 p_mb->pppi_motion_vectors[0][1][0],                     \
662                 p_mb->pppi_motion_vectors[0][1][1],                     \
663                 p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
664     }                                                                   \
665 } /* FRAMEFRAME */
666
667 void vdec_MotionFrameFrame420( macroblock_t * p_mb )
668 {
669     FRAMEFRAME( Motion420 )
670 }
671
672 void vdec_MotionFrameFrame422( macroblock_t * p_mb )
673 {
674     FRAMEFRAME( Motion422 )
675 }
676
677 void vdec_MotionFrameFrame444( macroblock_t * p_mb )
678 {
679     FRAMEFRAME( Motion444 )
680 }
681
682 /*****************************************************************************
683  * vdec_MotionFrameFieldXXX : motion compensation for field motion type (frame)
684  *****************************************************************************/
685 #define FRAMEFIELD( MOTION )                                            \
686 {                                                                       \
687     int i_l_stride = p_mb->i_l_stride << 1;                             \
688     int i_c_stride = p_mb->i_c_stride << 1;                             \
689                                                                         \
690     if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
691     {                                                                   \
692         MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[0][0], 0, \
693                 p_mb->pppi_motion_vectors[0][0][0],                     \
694                 p_mb->pppi_motion_vectors[0][0][1],                     \
695                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
696                                                                         \
697         MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[1][0], 1, \
698                 p_mb->pppi_motion_vectors[1][0][0],                     \
699                 p_mb->pppi_motion_vectors[1][0][1],                     \
700                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
701                                                                         \
702         if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
703         {                                                               \
704             MOTION( p_mb, p_mb->p_backward,                             \
705                     p_mb->ppi_field_select[0][1], 0,                    \
706                     p_mb->pppi_motion_vectors[0][1][0],                 \
707                     p_mb->pppi_motion_vectors[0][1][1],                 \
708                     i_l_stride, i_c_stride, 8, 0, 1 );                  \
709                                                                         \
710             MOTION( p_mb, p_mb->p_backward,                             \
711                     p_mb->ppi_field_select[1][1], 1,                    \
712                     p_mb->pppi_motion_vectors[1][1][0],                 \
713                     p_mb->pppi_motion_vectors[1][1][1],                 \
714                     i_l_stride, i_c_stride, 8, 0, 1 );                  \
715         }                                                               \
716     }                                                                   \
717                                                                         \
718     else /* MB_MOTION_BACKWARD only */                                  \
719     {                                                                   \
720         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], 0,\
721                 p_mb->pppi_motion_vectors[0][1][0],                     \
722                 p_mb->pppi_motion_vectors[0][1][1],                     \
723                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
724                                                                         \
725         MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], 1,\
726                 p_mb->pppi_motion_vectors[1][1][0],                     \
727                 p_mb->pppi_motion_vectors[1][1][1],                     \
728                 i_l_stride, i_c_stride, 8, 0, 0 );                      \
729     }                                                                   \
730 } /* FRAMEFIELD */
731
732 void vdec_MotionFrameField420( macroblock_t * p_mb )
733 {
734     FRAMEFIELD( Motion420 )
735 }
736
737 void vdec_MotionFrameField422( macroblock_t * p_mb )
738 {
739     FRAMEFIELD( Motion422 )
740 }
741
742 void vdec_MotionFrameField444( macroblock_t * p_mb )
743 {
744     FRAMEFIELD( Motion444 )
745 }
746
747 /*****************************************************************************
748  * vdec_MotionFrameDMVXXX : motion compensation for dmv motion type (frame)
749  *****************************************************************************/
750 #define FRAMEDMV( MOTION )                                              \
751 {                                                                       \
752     /* This is necessarily a MOTION_FORWARD only macroblock, in a P     \
753      * picture. */                                                      \
754                                                                         \
755     /* predict top field from top field */                              \
756     MOTION( p_mb, p_mb->p_forward, 0, 0,                                \
757             p_mb->pppi_motion_vectors[0][0][0],                         \
758             p_mb->pppi_motion_vectors[0][0][1],                         \
759             /* ????? >> 1 ? */                                          \
760             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 );    \
761                                                                         \
762     /* predict and add to top field from bottom field */                \
763     MOTION( p_mb, p_mb->p_forward, 1, 0,                                \
764             p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1],                   \
765             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 );    \
766                                                                         \
767     /* predict bottom field from bottom field */                        \
768     MOTION( p_mb, p_mb->p_forward, 1, 1,                                \
769             p_mb->pppi_motion_vectors[0][0][0],                         \
770             p_mb->pppi_motion_vectors[0][0][1],                         \
771             /* ????? >> 1 ? */                                          \
772             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 );    \
773                                                                         \
774     /* predict and add to bottom field from top field */                \
775     MOTION( p_mb, p_mb->p_forward, 1, 0,                                \
776             p_mb->ppi_dmv[1][0], p_mb->ppi_dmv[1][1],                   \
777             p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 );    \
778 } /* FRAMEDMV */
779
780 void vdec_MotionFrameDMV420( macroblock_t * p_mb )
781 {
782     FRAMEDMV( Motion420 )
783 }
784
785 void vdec_MotionFrameDMV422( macroblock_t * p_mb )
786 {
787     FRAMEDMV( Motion422 )
788 }
789
790 void vdec_MotionFrameDMV444( macroblock_t * p_mb )
791 {
792     FRAMEDMV( Motion444 )
793 }