vdec_motion_common.c 38.1 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.2 2001/02/13 06:31:05 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 26 27 28
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
29 30
#include "defs.h"

31 32
#include "config.h"
#include "common.h"
33
#include "threads.h"
34
#include "mtime.h"
Sam Hocevar's avatar
 
Sam Hocevar committed
35
#include "modules.h"
36 37 38 39 40

#include "intf_msg.h"

#include "video.h"

41 42
#include "vdec_motion.h"
#include "vpar_blocks.h"
Sam Hocevar's avatar
 
Sam Hocevar committed
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

extern int motion_Probe( probedata_t *p_data );

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.
 *****************************************************************************/
void motion_getfunctions( function_list_t * p_function_list )
{
    p_function_list->pf_probe = motion_Probe;

#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;
}
89

Sam Hocevar's avatar
 
Sam Hocevar committed
90 91 92 93 94 95 96 97
#define __MotionComponents(width,height)                \
void MotionComponent_x_y_copy_##width##_##height ();    \
void MotionComponent_X_y_copy_##width##_##height ();    \
void MotionComponent_x_Y_copy_##width##_##height ();    \
void MotionComponent_X_Y_copy_##width##_##height ();    \
void MotionComponent_x_y_avg_##width##_##height ();     \
void MotionComponent_X_y_avg_##width##_##height ();     \
void MotionComponent_x_Y_avg_##width##_##height ();     \
Michel Lespinasse's avatar
 
Michel Lespinasse committed
98 99
void MotionComponent_X_Y_avg_##width##_##height ();

Sam Hocevar's avatar
 
Sam Hocevar committed
100
__MotionComponents (16,16)       /* 444, 422, 420 */
Sam Hocevar's avatar
 
Sam Hocevar committed
101
__MotionComponents (16,8)        /* 444, 422, 420 */
Sam Hocevar's avatar
 
Sam Hocevar committed
102 103
__MotionComponents (8,8)         /* 422, 420 */
__MotionComponents (8,4)         /* 420 */
Michel Lespinasse's avatar
 
Michel Lespinasse committed
104
#if 0
Sam Hocevar's avatar
 
Sam Hocevar committed
105
__MotionComponents (8,16)        /* 422 */
Michel Lespinasse's avatar
 
Michel Lespinasse committed
106 107
#endif

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

157 158 159
/*****************************************************************************
 * vdec_MotionComponent : last stage of motion compensation
 *****************************************************************************/
160 161 162 163 164 165 166 167 168 169
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 */ )
170
{
Sam Hocevar's avatar
 
Sam Hocevar committed
171 172 173 174
    ___callTheRightOne (16,16)
    ___callTheRightOne (16,8)
    ___callTheRightOne (8,8)
    ___callTheRightOne (8,4)
Michel Lespinasse's avatar
 
Michel Lespinasse committed
175
#if 0
Sam Hocevar's avatar
 
Sam Hocevar committed
176
    ___callTheRightOne (8,16)
Michel Lespinasse's avatar
 
Michel Lespinasse committed
177
#endif
178 179
}

180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
/*****************************************************************************
 * 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;

Sam Hocevar's avatar
 
Sam Hocevar committed
205 206 207 208 209
    if( p_source == NULL )
    {
        return;
    }

210 211 212
    i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
                       + (p_mb->i_motion_l_y + i_offset
                         + b_source_field)
213
                       * p_mb->p_picture->i_width
214
                       + (i_mv_y >> 1) * i_l_stride;
215 216
    if( i_source_offset >= p_source->i_width * p_source->i_height )
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
217
        intf_ErrMsg( "vdec error: bad motion vector (lum)" );
218 219 220
        return;
    }

221 222
    /* Luminance */
    MotionComponent( /* source */
223
                     p_source->p_y + i_source_offset,
224 225 226
                     /* destination */
                     p_mb->p_picture->p_y
                       + (p_mb->i_l_x)
227
                       + (p_mb->i_motion_l_y + b_dest_field + i_offset)
228 229 230 231
                         * p_mb->p_picture->i_width,
                     /* prediction width and height */
                     16, i_height,
                     /* stride */
232
                     i_l_stride,
233 234 235 236 237
                     /* 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))
238
                        + (p_mb->i_motion_c_y + (i_offset >> 1)
239
                           + b_source_field)
240
                          * p_mb->p_picture->i_chroma_width
241
                        + ((i_mv_y/2) >> 1) * i_c_stride;
242 243
    if( i_source_offset >= (p_source->i_width * p_source->i_height) / 4 )
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
244
        intf_ErrMsg( "vdec error: bad motion vector (chroma)" );
245 246 247
        return;
    }

248
    i_dest_offset = (p_mb->i_c_x)
249 250
                      + (p_mb->i_motion_c_y + b_dest_field
                          + (i_offset >> 1))
251 252 253 254 255 256 257 258 259
                        * 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,
260
                     8, i_c_height, i_c_stride,
261 262 263 264 265 266 267
                     i_c_select, b_average );

    /* Chrominance Cb */
    MotionComponent( p_source->p_v
                       + i_source_offset,
                     p_mb->p_picture->p_v
                       + i_dest_offset,
268
                     8, i_c_height, i_c_stride,
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
                     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 */ )
{
294
#if 0
295 296 297 298 299 300 301 302
    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
303
                       * p_mb->p_picture->i_width
304
                       + (i_mv_y >> 1) * p_mb->i_l_stride,
305 306 307 308 309 310 311 312
                     /* 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 */
313
                     i_l_stride,
314 315 316 317 318
                     /* 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))
319
                        + (p_mb->i_motion_c_y + i_offset
320
                           + b_source_field)
321 322
                        * p_mb->p_picture->i_chroma_width
                        + (i_mv_y) >> 1) * p_mb->i_c_stride;
323 324 325 326 327 328 329 330 331 332
    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,
333
                     8, i_height, i_c_stride,
334 335 336 337 338 339 340
                     i_c_select, b_average );

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

/*****************************************************************************
 * 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 */ )
{
368
#if 0
369 370 371 372 373
    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)
374 375
                        * p_mb->p_picture->i_width
                        + (i_mv_y >> 1) * p_mb->i_l_stride;
376 377 378 379 380 381 382 383 384 385 386
    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,
387
                     16, i_height, i_l_stride,
388 389 390 391 392 393 394
                     i_select, b_average );

    /* Chrominance Cr */
    MotionComponent( p_source->p_u
                       + i_source_offset,
                     p_mb->p_picture->p_u
                       + i_dest_offset,
395
                     16, i_height, i_l_stride,
396 397 398 399 400 401 402
                     i_select, b_average );

    /* Chrominance Cb */
    MotionComponent( p_source->p_v
                       + i_source_offset,
                     p_mb->p_picture->p_v
                       + i_dest_offset,
403
                     16, i_height, i_l_stride,
404
                     i_select, b_average );
405
#endif
406 407
}

408
/*****************************************************************************
409
 * vdec_MotionFieldField : motion compensation for field motion type (field)
410
 *****************************************************************************/
411
#define FIELDFIELD( MOTION )                                            \
412
{                                                                       \
413 414 415 416
    picture_t *     p_pred;                                             \
                                                                        \
    if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
    {                                                                   \
417
        if( p_mb->b_P_second                                            \
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
             && (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 );     \
437
        }                                                               \
438 439 440 441 442 443 444 445 446 447 448
    }                                                                   \
                                                                        \
    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 );         \
    }                                                                   \
}
449

Sam Hocevar's avatar
 
Sam Hocevar committed
450
static void vdec_MotionFieldField420( macroblock_t * p_mb )
451 452 453
{
    FIELDFIELD( Motion420 )
}
454

Sam Hocevar's avatar
 
Sam Hocevar committed
455
static void vdec_MotionFieldField422( macroblock_t * p_mb )
456
{
457
    //FIELDFIELD( Motion422 )
458
}
459

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

/*****************************************************************************
466
 * vdec_MotionField16x8XXX: motion compensation for 16x8 motion type (field)
467
 *****************************************************************************/
468 469 470 471 472 473
#define FIELD16X8( MOTION )                                             \
{                                                                       \
    picture_t *     p_pred;                                             \
                                                                        \
    if( p_mb->i_mb_type & MB_MOTION_FORWARD )                           \
    {                                                                   \
474
        if( p_mb->b_P_second                                            \
475 476 477 478 479 480 481 482 483 484 485
             && (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 );          \
                                                                        \
486
        if( p_mb->b_P_second                                            \
487 488 489 490 491 492 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
             && (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 );          \
    }                                                                   \
}
531

Sam Hocevar's avatar
 
Sam Hocevar committed
532
static void vdec_MotionField16x8420( macroblock_t * p_mb )
533 534 535
{
    FIELD16X8( Motion420 )
}
536

Sam Hocevar's avatar
 
Sam Hocevar committed
537
static void vdec_MotionField16x8422( macroblock_t * p_mb )
538
{
539
    //FIELD16X8( Motion422 )
540
}
541

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

/*****************************************************************************
548
 * vdec_MotionFieldDMVXXX : motion compensation for dmv motion type (field)
549
 *****************************************************************************/
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
#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
574
static void vdec_MotionFieldDMV420( macroblock_t * p_mb )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
575
{
576 577 578
    FIELDDMV( Motion420 )
}

Sam Hocevar's avatar
 
Sam Hocevar committed
579
static void vdec_MotionFieldDMV422( macroblock_t * p_mb )
580
{
581
    //FIELDDMV( Motion422 )
582 583
}

Sam Hocevar's avatar
 
Sam Hocevar committed
584
static void vdec_MotionFieldDMV444( macroblock_t * p_mb )
585
{
586
    //FIELDDMV( Motion444 )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
587 588 589
}

/*****************************************************************************
590
 * vdec_MotionFrameFrameXXX?? : motion compensation for frame motion type (frame)
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
591
 *****************************************************************************/
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618
#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
619
static void vdec_MotionFrameFrame420( macroblock_t * p_mb )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
620
{
621 622
    FRAMEFRAME( Motion420 )
}
623

Sam Hocevar's avatar
 
Sam Hocevar committed
624
static void vdec_MotionFrameFrame422( macroblock_t * p_mb )
625
{
626
    //FRAMEFRAME( Motion422 )
627
}
628

Sam Hocevar's avatar
 
Sam Hocevar committed
629
static void vdec_MotionFrameFrame444( macroblock_t * p_mb )
630
{
631
    //FRAMEFRAME( Motion444 )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
632 633 634
}

/*****************************************************************************
635
 * vdec_MotionFrameFieldXXX?? : motion compensation for field motion type (frame)
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
636
 *****************************************************************************/
637 638 639 640 641 642 643 644 645
#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],                     \
646
                p_mb->pppi_motion_vectors[0][0][1] >> 1,                \
647 648 649 650
                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],                     \
651
                p_mb->pppi_motion_vectors[1][0][1] >> 1,                \
652 653 654 655 656 657 658
                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],                 \
659
                    p_mb->pppi_motion_vectors[0][1][1] >> 1,            \
660 661 662 663 664
                    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],                 \
665
                    p_mb->pppi_motion_vectors[1][1][1] >> 1,            \
666 667 668 669 670 671 672 673
                    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],                     \
674
                p_mb->pppi_motion_vectors[0][1][1] >> 1,                \
675 676 677 678
                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],                     \
679
                p_mb->pppi_motion_vectors[1][1][1] >> 1,                \
680 681 682 683
                i_l_stride, i_c_stride, 8, 0, 0 );                      \
    }                                                                   \
} /* FRAMEFIELD */

Sam Hocevar's avatar
 
Sam Hocevar committed
684
static void vdec_MotionFrameField420( macroblock_t * p_mb )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
685
{
686 687
    FRAMEFIELD( Motion420 )
}
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
688

Sam Hocevar's avatar
 
Sam Hocevar committed
689
static void vdec_MotionFrameField422( macroblock_t * p_mb )
690
{
691
    //FRAMEFIELD( Motion422 )
692
}
693

Sam Hocevar's avatar
 
Sam Hocevar committed
694
static void vdec_MotionFrameField444( macroblock_t * p_mb )
695
{
696
    //FRAMEFIELD( Motion444 )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
697 698 699
}

/*****************************************************************************
700
 * vdec_MotionFrameDMVXXX?? : motion compensation for dmv motion type (frame)
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
701
 *****************************************************************************/
702 703 704 705 706 707 708 709 710
#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
711
            /* XXX?? XXX?? >> 1 ? */                                    \
712 713 714 715 716 717 718 719 720 721 722
            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
723
            /* XXX?? XXX?? >> 1 ? */                                    \
724 725 726 727 728 729 730 731
            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
732
static void vdec_MotionFrameDMV420( macroblock_t * p_mb )
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
733
{
734
    FRAMEDMV( Motion420 )
735 736
}

Sam Hocevar's avatar
 
Sam Hocevar committed
737
static void vdec_MotionFrameDMV422( macroblock_t * p_mb )
738
{
739
    //FRAMEDMV( Motion422 )
740 741
}

Sam Hocevar's avatar
 
Sam Hocevar committed
742
static void vdec_MotionFrameDMV444( macroblock_t * p_mb )
743
{
744
    //FRAMEDMV( Motion444 )
745
}
Sam Hocevar's avatar
 
Sam Hocevar committed
746