vdec_motion_common.c 38.2 KB
Newer Older
1
/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
2
 * vdec_motion_common.c : common motion compensation routines common
3 4
 *****************************************************************************
 * Copyright (C) 1999, 2000 VideoLAN
Sam Hocevar's avatar
 
Sam Hocevar committed
5
 * $Id: vdec_motion_common.c,v 1.8 2001/06/07 15:27:44 sam Exp $
6
 *
7 8 9
 * Authors: Christophe Massiot <massiot@via.ecp.fr>
 *          Jean-Marc Dressler <polux@via.ecp.fr>
 *          Michel Lespinasse <walken@via.ecp.fr>
10 11 12 13 14
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
15
 * 
16 17
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
20
 *
21 22 23
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24 25
 *****************************************************************************/

Sam Hocevar's avatar
 
Sam Hocevar committed
26 27 28 29 30 31 32
/* MODULE_NAME defined in Makefile together with -DBUILTIN */
#ifdef BUILTIN
#   include "modules_inner.h"
#else
#   define _M( foo ) foo
#endif

33 34 35
/*****************************************************************************
 * Preamble
 *****************************************************************************/
36 37
#include "defs.h"

38 39
#include "config.h"
#include "common.h"
40
#include "threads.h"
41 42 43 44 45 46
#include "mtime.h"

#include "intf_msg.h"

#include "video.h"

47 48
#include "vdec_motion.h"
#include "vpar_blocks.h"
Sam Hocevar's avatar
 
Sam Hocevar committed
49

Sam Hocevar's avatar
 
Sam Hocevar committed
50 51 52
#include "modules.h"
#include "modules_export.h"

Sam Hocevar's avatar
 
Sam Hocevar committed
53
extern int _M( motion_Probe )( probedata_t *p_data );
Sam Hocevar's avatar
 
Sam Hocevar committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

static void vdec_MotionFieldField420  ( macroblock_t * p_mb );
static void vdec_MotionFieldField422  ( macroblock_t * p_mb );
static void vdec_MotionFieldField444  ( macroblock_t * p_mb );
static void vdec_MotionField16x8420   ( macroblock_t * p_mb );
static void vdec_MotionField16x8422   ( macroblock_t * p_mb );
static void vdec_MotionField16x8444   ( macroblock_t * p_mb );
static void vdec_MotionFieldDMV420    ( macroblock_t * p_mb );
static void vdec_MotionFieldDMV422    ( macroblock_t * p_mb );
static void vdec_MotionFieldDMV444    ( macroblock_t * p_mb );
static void vdec_MotionFrameFrame420  ( macroblock_t * p_mb );
static void vdec_MotionFrameFrame422  ( macroblock_t * p_mb );
static void vdec_MotionFrameFrame444  ( macroblock_t * p_mb );
static void vdec_MotionFrameField420  ( macroblock_t * p_mb );
static void vdec_MotionFrameField422  ( macroblock_t * p_mb );
static void vdec_MotionFrameField444  ( macroblock_t * p_mb );
static void vdec_MotionFrameDMV420    ( macroblock_t * p_mb );
static void vdec_MotionFrameDMV422    ( macroblock_t * p_mb );
static void vdec_MotionFrameDMV444    ( macroblock_t * p_mb );

/*****************************************************************************
 * Functions exported as capabilities. They are declared as static so that
 * we don't pollute the namespace too much.
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
78
void _M( motion_getfunctions )( function_list_t * p_function_list )
Sam Hocevar's avatar
 
Sam Hocevar committed
79
{
Sam Hocevar's avatar
 
Sam Hocevar committed
80
    p_function_list->pf_probe = _M( motion_Probe );
Sam Hocevar's avatar
 
Sam Hocevar committed
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97

#define list p_function_list->functions.motion
#define motion_functions( yuv ) \
    list.pf_field_field_##yuv = vdec_MotionFieldField##yuv; \
    list.pf_field_16x8_##yuv  = vdec_MotionField16x8##yuv;  \
    list.pf_field_dmv_##yuv   = vdec_MotionFieldDMV##yuv;   \
    list.pf_frame_field_##yuv = vdec_MotionFrameField##yuv; \
    list.pf_frame_frame_##yuv = vdec_MotionFrameFrame##yuv; \
    list.pf_frame_dmv_##yuv   = vdec_MotionFrameDMV##yuv;
    motion_functions( 420 )
    motion_functions( 422 )
    motion_functions( 444 )
#undef motion_functions
#undef list

    return;
}
98

Sam Hocevar's avatar
 
Sam Hocevar committed
99
#define __MotionComponents(width,height)                \
Sam Hocevar's avatar
 
Sam Hocevar committed
100 101 102 103 104 105 106 107
void _M( MotionComponent_x_y_copy_##width##_##height )();    \
void _M( MotionComponent_X_y_copy_##width##_##height )();    \
void _M( MotionComponent_x_Y_copy_##width##_##height )();    \
void _M( MotionComponent_X_Y_copy_##width##_##height )();    \
void _M( MotionComponent_x_y_avg_##width##_##height )();     \
void _M( MotionComponent_X_y_avg_##width##_##height )();     \
void _M( MotionComponent_x_Y_avg_##width##_##height )();     \
void _M( MotionComponent_X_Y_avg_##width##_##height )();
Michel Lespinasse's avatar
 
Michel Lespinasse committed
108

Sam Hocevar's avatar
 
Sam Hocevar committed
109
__MotionComponents (16,16)       /* 444, 422, 420 */
Sam Hocevar's avatar
 
Sam Hocevar committed
110
__MotionComponents (16,8)        /* 444, 422, 420 */
Sam Hocevar's avatar
 
Sam Hocevar committed
111 112
__MotionComponents (8,8)         /* 422, 420 */
__MotionComponents (8,4)         /* 420 */
Michel Lespinasse's avatar
 
Michel Lespinasse committed
113
#if 0
Sam Hocevar's avatar
 
Sam Hocevar committed
114
__MotionComponents (8,16)        /* 422 */
Michel Lespinasse's avatar
 
Michel Lespinasse committed
115 116
#endif

Sam Hocevar's avatar
 
Sam Hocevar committed
117 118 119 120 121 122 123 124
#define ___callTheRightOne(width,height)                                     \
    if ((i_width == width) && (i_height == height))                          \
    {                                                                        \
        if (!b_average)                                                      \
        {                                                                    \
            switch (i_select)                                                \
            {                                                                \
            case 0:                                                          \
Sam Hocevar's avatar
 
Sam Hocevar committed
125 126
                _M( MotionComponent_x_y_copy_##width##_##height )(p_src,     \
                                                          p_dest, i_stride); \
Sam Hocevar's avatar
 
Sam Hocevar committed
127 128
                break;                                                       \
            case 1:                                                          \
Sam Hocevar's avatar
 
Sam Hocevar committed
129 130
                _M( MotionComponent_X_y_copy_##width##_##height )(p_src,     \
                                                          p_dest, i_stride); \
Sam Hocevar's avatar
 
Sam Hocevar committed
131 132
                break;                                                       \
            case 2:                                                          \
Sam Hocevar's avatar
 
Sam Hocevar committed
133 134
                _M( MotionComponent_x_Y_copy_##width##_##height )(p_src,     \
                                                          p_dest, i_stride); \
Sam Hocevar's avatar
 
Sam Hocevar committed
135 136
                break;                                                       \
            case 3:                                                          \
Sam Hocevar's avatar
 
Sam Hocevar committed
137 138
                _M( MotionComponent_X_Y_copy_##width##_##height )(p_src,     \
                                                          p_dest, i_stride); \
Sam Hocevar's avatar
 
Sam Hocevar committed
139 140 141 142 143 144 145 146
                break;                                                       \
            }                                                                \
        }                                                                    \
        else                                                                 \
        {                                                                    \
            switch (i_select)                                                \
            {                                                                \
            case 0:                                                          \
Sam Hocevar's avatar
 
Sam Hocevar committed
147 148
                _M( MotionComponent_x_y_avg_##width##_##height )(p_src,      \
                                                          p_dest, i_stride); \
Sam Hocevar's avatar
 
Sam Hocevar committed
149 150
                break;                                                       \
            case 1:                                                          \
Sam Hocevar's avatar
 
Sam Hocevar committed
151 152
                _M( MotionComponent_X_y_avg_##width##_##height )(p_src,      \
                                                          p_dest, i_stride); \
Sam Hocevar's avatar
 
Sam Hocevar committed
153 154
                break;                                                       \
            case 2:                                                          \
Sam Hocevar's avatar
 
Sam Hocevar committed
155 156
                _M( MotionComponent_x_Y_avg_##width##_##height )(p_src,      \
                                                          p_dest, i_stride); \
Sam Hocevar's avatar
 
Sam Hocevar committed
157 158
                break;                                                       \
            case 3:                                                          \
Sam Hocevar's avatar
 
Sam Hocevar committed
159 160
                _M( MotionComponent_X_Y_avg_##width##_##height )(p_src,      \
                                                          p_dest, i_stride); \
Sam Hocevar's avatar
 
Sam Hocevar committed
161 162 163
                break;                                                       \
            }                                                                \
        }                                                                    \
Michel Lespinasse's avatar
 
Michel Lespinasse committed
164
    }
165

166 167 168
/*****************************************************************************
 * vdec_MotionComponent : last stage of motion compensation
 *****************************************************************************/
169 170 171 172 173 174 175 176 177 178
static __inline__ void MotionComponent(
                    yuv_data_t * p_src,     /* source block */
                    yuv_data_t * p_dest,    /* dest block */
                    int i_width,            /* (explicit) width of block */
                    int i_height,           /* (explicit) height of block */
                    int i_stride,           /* number of coeffs to jump
                                             * between each predicted line */
                    int i_select,           /* half-pel vectors */
                    boolean_t b_average     /* (explicit) averaging of several
                                             * predictions */ )
179
{
Sam Hocevar's avatar
 
Sam Hocevar committed
180 181 182 183
    ___callTheRightOne (16,16)
    ___callTheRightOne (16,8)
    ___callTheRightOne (8,8)
    ___callTheRightOne (8,4)
Michel Lespinasse's avatar
 
Michel Lespinasse committed
184
#if 0
Sam Hocevar's avatar
 
Sam Hocevar committed
185
    ___callTheRightOne (8,16)
Michel Lespinasse's avatar
 
Michel Lespinasse committed
186
#endif
187 188
}

189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
/*****************************************************************************
 * Motion420 : motion compensation for a 4:2:0 macroblock
 *****************************************************************************/
static __inline__ void Motion420(
                    macroblock_t * p_mb,        /* destination macroblock */
                    picture_t * p_source,       /* source picture */
                    boolean_t b_source_field,   /* source field */
                    boolean_t b_dest_field,     /* destination field */
                    int i_mv_x, int i_mv_y,     /* motion vector coordinates,
                                                 * in half pels */
                    int i_l_stride,             /* number of coeffs to jump to
                                                 * go to the next predicted
                                                 * line */
                    int i_c_stride,
                    int i_height,               /* height of the block to
                                                 * predict, in luminance
                                                 * (explicit) */
                    int i_offset,               /* position of the first
                                                 * predicted line (explicit) */
                    boolean_t b_average         /* (explicit) averaging of
                                                 * several predictions */ )
{
    /* Temporary variables to avoid recalculating things twice */
    int     i_source_offset, i_dest_offset, i_c_height, i_c_select;

214 215 216
    i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
                       + (p_mb->i_motion_l_y + i_offset
                         + b_source_field)
217
                       * p_mb->p_picture->i_width
218
                       + (i_mv_y >> 1) * i_l_stride;
219 220

    if( i_source_offset >= p_source->i_size )
221
    {
Christophe Massiot's avatar
Christophe Massiot committed
222
        intf_WarnMsg( 2, "Bad motion vector (lum)" );
223 224 225
        return;
    }

226 227
    /* Luminance */
    MotionComponent( /* source */
228
                     p_source->p_y + i_source_offset,
229 230 231
                     /* destination */
                     p_mb->p_picture->p_y
                       + (p_mb->i_l_x)
232
                       + (p_mb->i_motion_l_y + b_dest_field + i_offset)
233 234 235 236
                         * p_mb->p_picture->i_width,
                     /* prediction width and height */
                     16, i_height,
                     /* stride */
237
                     i_l_stride,
238 239 240 241 242
                     /* select */
                     ((i_mv_y & 1) << 1) | (i_mv_x & 1),
                     b_average );

    i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
243
                        + (p_mb->i_motion_c_y + (i_offset >> 1)
244
                           + b_source_field)
245
                          * p_mb->p_picture->i_chroma_width
246
                        + ((i_mv_y/2) >> 1) * i_c_stride;
247 248

    if( i_source_offset >= p_source->i_chroma_size )
249
    {
Christophe Massiot's avatar
Christophe Massiot committed
250
        intf_WarnMsg( 2, "Bad motion vector (chroma)" );
251 252 253
        return;
    }

254
    i_dest_offset = (p_mb->i_c_x)
255 256
                      + (p_mb->i_motion_c_y + b_dest_field
                          + (i_offset >> 1))
257 258 259 260 261 262 263 264 265
                        * p_mb->p_picture->i_chroma_width;
    i_c_height = i_height >> 1;
    i_c_select = (((i_mv_y/2) & 1) << 1) | ((i_mv_x/2) & 1);

    /* Chrominance Cr */
    MotionComponent( p_source->p_u
                       + i_source_offset,
                     p_mb->p_picture->p_u
                       + i_dest_offset,
266
                     8, i_c_height, i_c_stride,
267 268 269 270 271 272 273
                     i_c_select, b_average );

    /* Chrominance Cb */
    MotionComponent( p_source->p_v
                       + i_source_offset,
                     p_mb->p_picture->p_v
                       + i_dest_offset,
274
                     8, i_c_height, i_c_stride,
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
                     i_c_select, b_average );
}

/*****************************************************************************
 * Motion422 : motion compensation for a 4:2:2 macroblock
 *****************************************************************************/
static __inline__ void Motion422(
                    macroblock_t * p_mb,        /* destination macroblock */
                    picture_t * p_source,       /* source picture */
                    boolean_t b_source_field,   /* source field */
                    boolean_t b_dest_field,     /* destination field */
                    int i_mv_x, int i_mv_y,     /* motion vector coordinates,
                                                 * in half pels */
                    int i_l_stride,             /* number of coeffs to jump to
                                                 * go to the next predicted
                                                 * line */
                    int i_c_stride,
                    int i_height,               /* height of the block to
                                                 * predict, in luminance
                                                 * (explicit) */
                    int i_offset,               /* position of the first
                                                 * predicted line (explicit) */
                    boolean_t b_average         /* (explicit) averaging of
                                                 * several predictions */ )
{
300
#if 0
301 302 303 304 305 306 307 308
    int     i_source_offset, i_dest_offset, i_c_select;

    /* Luminance */
    MotionComponent( /* source */
                     p_source->p_y
                       + (p_mb->i_l_x + (i_mv_x >> 1))
                       + (p_mb->i_motion_l_y + i_offset
                          + b_source_field)
Sam Hocevar's avatar
 
Sam Hocevar committed
309
                       * p_mb->p_picture->i_width
310
                       + (i_mv_y >> 1) * p_mb->i_l_stride,
311 312 313 314 315 316 317 318
                     /* destination */
                     p_mb->p_picture->p_y
                       + (p_mb->i_l_x)
                       + (p_mb->i_motion_l_y + b_dest_field)
                         * p_mb->p_picture->i_width,
                     /* prediction width and height */
                     16, i_height,
                     /* stride */
319
                     i_l_stride,
320 321 322 323 324
                     /* select */
                     ((i_mv_y & 1) << 1) | (i_mv_x & 1),
                     b_average );

    i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1))
325
                        + (p_mb->i_motion_c_y + i_offset
326
                           + b_source_field)
327 328
                        * p_mb->p_picture->i_chroma_width
                        + (i_mv_y) >> 1) * p_mb->i_c_stride;
329 330 331 332 333 334 335 336 337 338
    i_dest_offset = (p_mb->i_c_x)
                      + (p_mb->i_motion_c_y + b_dest_field)
                        * p_mb->p_picture->i_chroma_width;
    i_c_select = ((i_mv_y & 1) << 1) | ((i_mv_x/2) & 1);

    /* Chrominance Cr */
    MotionComponent( p_source->p_u
                       + i_source_offset,
                     p_mb->p_picture->p_u
                       + i_dest_offset,
339
                     8, i_height, i_c_stride,
340 341 342 343 344 345 346
                     i_c_select, b_average );

    /* Chrominance Cb */
    MotionComponent( p_source->p_v
                       + i_source_offset,
                     p_mb->p_picture->p_u
                       + i_dest_offset,
347
                     8, i_height, i_c_stride,
348
                     i_c_select, b_average );
349
#endif
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
}

/*****************************************************************************
 * Motion444 : motion compensation for a 4:4:4 macroblock
 *****************************************************************************/
static __inline__ void Motion444(
                    macroblock_t * p_mb,        /* destination macroblock */
                    picture_t * p_source,       /* source picture */
                    boolean_t b_source_field,   /* source field */
                    boolean_t b_dest_field,     /* destination field */
                    int i_mv_x, int i_mv_y,     /* motion vector coordinates,
                                                 * in half pels */
                    int i_l_stride,             /* number of coeffs to jump to
                                                 * go to the next predicted
                                                 * line */
                    int i_c_stride,
                    int i_height,               /* height of the block to
                                                 * predict, in luminance
                                                 * (explicit) */
                    int i_offset,               /* position of the first
                                                 * predicted line (explicit) */
                    boolean_t b_average         /* (explicit) averaging of
                                                 * several predictions */ )
{
374
#if 0
375 376 377 378 379
    int     i_source_offset, i_dest_offset, i_select;

    i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
                        + (p_mb->i_motion_l_y + i_offset
                           + b_source_field)
380 381
                        * p_mb->p_picture->i_width
                        + (i_mv_y >> 1) * p_mb->i_l_stride;
382 383 384 385 386 387 388 389 390 391 392
    i_dest_offset = (p_mb->i_l_x)
                      + (p_mb->i_motion_l_y + b_dest_field)
                        * p_mb->p_picture->i_width;
    i_select = ((i_mv_y & 1) << 1) | (i_mv_x & 1);


    /* Luminance */
    MotionComponent( p_source->p_y
                       + i_source_offset,
                     p_mb->p_picture->p_y
                       + i_dest_offset,
393
                     16, i_height, i_l_stride,
394 395 396 397 398 399 400
                     i_select, b_average );

    /* Chrominance Cr */
    MotionComponent( p_source->p_u
                       + i_source_offset,
                     p_mb->p_picture->p_u
                       + i_dest_offset,
401
                     16, i_height, i_l_stride,
402 403 404 405 406 407 408
                     i_select, b_average );

    /* Chrominance Cb */
    MotionComponent( p_source->p_v
                       + i_source_offset,
                     p_mb->p_picture->p_v
                       + i_dest_offset,
409
                     16, i_height, i_l_stride,
410
                     i_select, b_average );
411
#endif
412 413
}

414
/*****************************************************************************
415
 * vdec_MotionFieldField : motion compensation for field motion type (field)
416
 *****************************************************************************/
417
#define FIELDFIELD( MOTION )                                            \
418
{                                                                       \
419 420 421 422
    picture_t *     p_pred;                                             \
                                                                        \
    if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
    {                                                                   \
423
        if( p_mb->b_P_second                                            \
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
             && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
            p_pred = p_mb->p_picture;                                   \
        else                                                            \
            p_pred = p_mb->p_forward;                                   \
                                                                        \
        MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0],             \
                p_mb->b_motion_field,                                   \
                p_mb->pppi_motion_vectors[0][0][0],                     \
                p_mb->pppi_motion_vectors[0][0][1],                     \
                p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
                                                                        \
        if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
        {                                                               \
            MOTION( p_mb, p_mb->p_backward,                             \
                    p_mb->ppi_field_select[0][1],                       \
                    p_mb->b_motion_field,                               \
                    p_mb->pppi_motion_vectors[0][1][0],                 \
                    p_mb->pppi_motion_vectors[0][1][1],                 \
                    p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );     \
443
        }                                                               \
444 445 446 447 448 449 450 451 452 453 454
    }                                                                   \
                                                                        \
    else /* MB_MOTION_BACKWARD */                                       \
    {                                                                   \
        MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1],   \
                p_mb->b_motion_field,                                   \
                p_mb->pppi_motion_vectors[0][1][0],                     \
                p_mb->pppi_motion_vectors[0][1][1],                     \
                p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
    }                                                                   \
}
455

Sam Hocevar's avatar
 
Sam Hocevar committed
456
static void vdec_MotionFieldField420( macroblock_t * p_mb )
457 458 459
{
    FIELDFIELD( Motion420 )
}
460

Sam Hocevar's avatar
 
Sam Hocevar committed
461
static void vdec_MotionFieldField422( macroblock_t * p_mb )
462
{
463
    //FIELDFIELD( Motion422 )
464
}
465

Sam Hocevar's avatar
 
Sam Hocevar committed
466
static void vdec_MotionFieldField444( macroblock_t * p_mb )
467
{
468
    //FIELDFIELD( Motion444 )
469 470 471
}

/*****************************************************************************
472
 * vdec_MotionField16x8XXX: motion compensation for 16x8 motion type (field)
473
 *****************************************************************************/
474 475 476 477 478 479
#define FIELD16X8( MOTION )                                             \
{                                                                       \
    picture_t *     p_pred;                                             \
                                                                        \
    if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
    {                                                                   \
480
        if( p_mb->b_P_second                                            \
481 482 483 484 485 486 487 488 489 490 491
             && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
            p_pred = p_mb->p_picture;                                   \
        else                                                            \
            p_pred = p_mb->p_forward;                                   \
                                                                        \
        MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0],             \
                p_mb->b_motion_field,                                   \
                p_mb->pppi_motion_vectors[0][0][0],                     \
                p_mb->pppi_motion_vectors[0][0][1],                     \
                p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 );          \
                                                                        \
492
        if( p_mb->b_P_second                                            \
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
             && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\
            p_pred = p_mb->p_picture;                                   \
        else                                                            \
            p_pred = p_mb->p_forward;                                   \
                                                                        \
        MOTION( p_mb, p_pred, p_mb->ppi_field_select[1][0],             \
                p_mb->b_motion_field,                                   \
                p_mb->pppi_motion_vectors[1][0][0],                     \
                p_mb->pppi_motion_vectors[1][0][1],                     \
                p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 );          \
                                                                        \
        if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
        {                                                               \
            MOTION( p_mb, p_mb->p_backward,                             \
                    p_mb->ppi_field_select[0][1],                       \
                    p_mb->b_motion_field,                               \
                    p_mb->pppi_motion_vectors[0][1][0],                 \
                    p_mb->pppi_motion_vectors[0][1][1],                 \
                    p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 1 );      \
                                                                        \
            MOTION( p_mb, p_mb->p_backward,                             \
                    p_mb->ppi_field_select[1][1],                       \
                    p_mb->b_motion_field,                               \
                    p_mb->pppi_motion_vectors[1][1][0],                 \
                    p_mb->pppi_motion_vectors[1][1][1],                 \
                    p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 1 );      \
        }                                                               \
    }                                                                   \
                                                                        \
    else /* MB_MOTION_BACKWARD */                                       \
    {                                                                   \
        MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1],   \
                p_mb->b_motion_field,                                   \
                p_mb->pppi_motion_vectors[0][1][0],                     \
                p_mb->pppi_motion_vectors[0][1][1],                     \
                p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 );          \
                                                                        \
        MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1],   \
                p_mb->b_motion_field,                                   \
                p_mb->pppi_motion_vectors[1][1][0],                     \
                p_mb->pppi_motion_vectors[1][1][1],                     \
                p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 );          \
    }                                                                   \
}
537

Sam Hocevar's avatar
 
Sam Hocevar committed
538
static void vdec_MotionField16x8420( macroblock_t * p_mb )
539 540 541
{
    FIELD16X8( Motion420 )
}
542

Sam Hocevar's avatar
 
Sam Hocevar committed
543
static void vdec_MotionField16x8422( macroblock_t * p_mb )
544
{
545
    //FIELD16X8( Motion422 )
546
}
547

Sam Hocevar's avatar
 
Sam Hocevar committed
548
static void vdec_MotionField16x8444( macroblock_t * p_mb )
549
{
550
    //FIELD16X8( Motion444 )
551 552 553
}

/*****************************************************************************
554
 * vdec_MotionFieldDMVXXX : motion compensation for dmv motion type (field)
555
 *****************************************************************************/
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
#define FIELDDMV( MOTION )                                              \
{                                                                       \
    /* This is necessarily a MOTION_FORWARD only macroblock, in a P     \
     * picture. */                                                      \
    picture_t *     p_pred;                                             \
                                                                        \
    /* predict from field of same parity */                             \
    MOTION( p_mb, p_mb->p_forward,                                      \
            p_mb->b_motion_field, p_mb->b_motion_field,                 \
            p_mb->pppi_motion_vectors[0][0][0],                         \
            p_mb->pppi_motion_vectors[0][0][1],                         \
            p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );             \
                                                                        \
    if( p_mb->b_P_second )                                              \
        p_pred = p_mb->p_picture;                                       \
    else                                                                \
        p_pred = p_mb->p_forward;                                       \
                                                                        \
    /* predict from field of opposite parity */                         \
    MOTION( p_mb, p_pred, !p_mb->b_motion_field, p_mb->b_motion_field,  \
            p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1],                   \
            p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );             \
} /* FIELDDMV */

Sam Hocevar's avatar
 
Sam Hocevar committed
580
static void vdec_MotionFieldDMV420( macroblock_t * p_mb )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
581
{
582 583 584
    FIELDDMV( Motion420 )
}

Sam Hocevar's avatar
 
Sam Hocevar committed
585
static void vdec_MotionFieldDMV422( macroblock_t * p_mb )
586
{
587
    //FIELDDMV( Motion422 )
588 589
}

Sam Hocevar's avatar
 
Sam Hocevar committed
590
static void vdec_MotionFieldDMV444( macroblock_t * p_mb )
591
{
592
    //FIELDDMV( Motion444 )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
593 594 595
}

/*****************************************************************************
596
 * vdec_MotionFrameFrameXXX?? : motion compensation for frame motion type (frame)
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
597
 *****************************************************************************/
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624
#define FRAMEFRAME( MOTION )                                            \
{                                                                       \
    if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
    {                                                                   \
        MOTION( p_mb, p_mb->p_forward, 0, 0,                            \
                p_mb->pppi_motion_vectors[0][0][0],                     \
                p_mb->pppi_motion_vectors[0][0][1],                     \
                p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
                                                                        \
        if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
        {                                                               \
            MOTION( p_mb, p_mb->p_backward, 0, 0,                       \
                    p_mb->pppi_motion_vectors[0][1][0],                 \
                    p_mb->pppi_motion_vectors[0][1][1],                 \
                    p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 );     \
        }                                                               \
    }                                                                   \
                                                                        \
    else /* MB_MOTION_BACKWARD */                                       \
    {                                                                   \
        MOTION( p_mb, p_mb->p_backward, 0, 0,                           \
                p_mb->pppi_motion_vectors[0][1][0],                     \
                p_mb->pppi_motion_vectors[0][1][1],                     \
                p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 );         \
    }                                                                   \
} /* FRAMEFRAME */

Sam Hocevar's avatar
 
Sam Hocevar committed
625
static void vdec_MotionFrameFrame420( macroblock_t * p_mb )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
626
{
627 628
    FRAMEFRAME( Motion420 )
}
629

Sam Hocevar's avatar
 
Sam Hocevar committed
630
static void vdec_MotionFrameFrame422( macroblock_t * p_mb )
631
{
632
    //FRAMEFRAME( Motion422 )
633
}
634

Sam Hocevar's avatar
 
Sam Hocevar committed
635
static void vdec_MotionFrameFrame444( macroblock_t * p_mb )
636
{
637
    //FRAMEFRAME( Motion444 )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
638 639 640
}

/*****************************************************************************
641
 * vdec_MotionFrameFieldXXX?? : motion compensation for field motion type (frame)
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
642
 *****************************************************************************/
643 644 645 646 647 648 649 650 651
#define FRAMEFIELD( MOTION )                                            \
{                                                                       \
    int i_l_stride = p_mb->i_l_stride << 1;                             \
    int i_c_stride = p_mb->i_c_stride << 1;                             \
                                                                        \
    if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
    {                                                                   \
        MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[0][0], 0, \
                p_mb->pppi_motion_vectors[0][0][0],                     \
652
                p_mb->pppi_motion_vectors[0][0][1] >> 1,                \
653 654 655 656
                i_l_stride, i_c_stride, 8, 0, 0 );                      \
                                                                        \
        MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[1][0], 1, \
                p_mb->pppi_motion_vectors[1][0][0],                     \
657
                p_mb->pppi_motion_vectors[1][0][1] >> 1,                \
658 659 660 661 662 663 664
                i_l_stride, i_c_stride, 8, 0, 0 );                      \
                                                                        \
        if( p_mb->i_mb_type & MB_MOTION_BACKWARD )                      \
        {                                                               \
            MOTION( p_mb, p_mb->p_backward,                             \
                    p_mb->ppi_field_select[0][1], 0,                    \
                    p_mb->pppi_motion_vectors[0][1][0],                 \
665
                    p_mb->pppi_motion_vectors[0][1][1] >> 1,            \
666 667 668 669 670
                    i_l_stride, i_c_stride, 8, 0, 1 );                  \
                                                                        \
            MOTION( p_mb, p_mb->p_backward,                             \
                    p_mb->ppi_field_select[1][1], 1,                    \
                    p_mb->pppi_motion_vectors[1][1][0],                 \
671
                    p_mb->pppi_motion_vectors[1][1][1] >> 1,            \
672 673 674 675 676 677 678 679
                    i_l_stride, i_c_stride, 8, 0, 1 );                  \
        }                                                               \
    }                                                                   \
                                                                        \
    else /* MB_MOTION_BACKWARD only */                                  \
    {                                                                   \
        MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], 0,\
                p_mb->pppi_motion_vectors[0][1][0],                     \
680
                p_mb->pppi_motion_vectors[0][1][1] >> 1,                \
681 682 683 684
                i_l_stride, i_c_stride, 8, 0, 0 );                      \
                                                                        \
        MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], 1,\
                p_mb->pppi_motion_vectors[1][1][0],                     \
685
                p_mb->pppi_motion_vectors[1][1][1] >> 1,                \
686 687 688 689
                i_l_stride, i_c_stride, 8, 0, 0 );                      \
    }                                                                   \
} /* FRAMEFIELD */

Sam Hocevar's avatar
 
Sam Hocevar committed
690
static void vdec_MotionFrameField420( macroblock_t * p_mb )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
691
{
692 693
    FRAMEFIELD( Motion420 )
}
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
694

Sam Hocevar's avatar
 
Sam Hocevar committed
695
static void vdec_MotionFrameField422( macroblock_t * p_mb )
696
{
697
    //FRAMEFIELD( Motion422 )
698
}
699

Sam Hocevar's avatar
 
Sam Hocevar committed
700
static void vdec_MotionFrameField444( macroblock_t * p_mb )
701
{
702
    //FRAMEFIELD( Motion444 )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
703 704 705
}

/*****************************************************************************
706
 * vdec_MotionFrameDMVXXX?? : motion compensation for dmv motion type (frame)
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
707
 *****************************************************************************/
708 709 710 711 712 713 714 715 716
#define FRAMEDMV( MOTION )                                              \
{                                                                       \
    /* This is necessarily a MOTION_FORWARD only macroblock, in a P     \
     * picture. */                                                      \
                                                                        \
    /* predict top field from top field */                              \
    MOTION( p_mb, p_mb->p_forward, 0, 0,                                \
            p_mb->pppi_motion_vectors[0][0][0],                         \
            p_mb->pppi_motion_vectors[0][0][1],                         \
Sam Hocevar's avatar
 
Sam Hocevar committed
717
            /* XXX?? XXX?? >> 1 ? */                                    \
718 719 720 721 722 723 724 725 726 727 728
            p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 );    \
                                                                        \
    /* predict and add to top field from bottom field */                \
    MOTION( p_mb, p_mb->p_forward, 1, 0,                                \
            p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1],                   \
            p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 );    \
                                                                        \
    /* predict bottom field from bottom field */                        \
    MOTION( p_mb, p_mb->p_forward, 1, 1,                                \
            p_mb->pppi_motion_vectors[0][0][0],                         \
            p_mb->pppi_motion_vectors[0][0][1],                         \
Sam Hocevar's avatar
 
Sam Hocevar committed
729
            /* XXX?? XXX?? >> 1 ? */                                    \
730 731 732 733 734 735 736 737
            p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 );    \
                                                                        \
    /* predict and add to bottom field from top field */                \
    MOTION( p_mb, p_mb->p_forward, 1, 0,                                \
            p_mb->ppi_dmv[1][0], p_mb->ppi_dmv[1][1],                   \
            p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 );    \
} /* FRAMEDMV */

Sam Hocevar's avatar
 
Sam Hocevar committed
738
static void vdec_MotionFrameDMV420( macroblock_t * p_mb )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
739
{
740
    FRAMEDMV( Motion420 )
741 742
}

Sam Hocevar's avatar
 
Sam Hocevar committed
743
static void vdec_MotionFrameDMV422( macroblock_t * p_mb )
744
{
745
    //FRAMEDMV( Motion422 )
746 747
}

Sam Hocevar's avatar
 
Sam Hocevar committed
748
static void vdec_MotionFrameDMV444( macroblock_t * p_mb )
749
{
750
    //FRAMEDMV( Motion444 )
751
}
Sam Hocevar's avatar
 
Sam Hocevar committed
752