Commit a890c0ee authored by Sam Hocevar's avatar Sam Hocevar

Removed obsolete files which suddenly reappeared.. THE FILES THAT WOULD

 NEVER DIE ! MUUAHAHAHAHAHAAAA !!
parent e6198f86
/*****************************************************************************
* vdec_block_c.c: Macroblock copy functions in C
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: vdec_block_c.c,v 1.8 2001/12/09 17:01:36 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
/* MODULE_NAME defined in Makefile together with -DBUILTIN */
#ifdef BUILTIN
# include "modules_inner.h"
#else
# define _M( foo ) foo
#endif
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <string.h> /* memcpy(), memset() */
#include "common.h"
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "threads.h"
#include "mtime.h"
#include "vdec_idct.h"
#include "modules.h"
#include "modules_export.h"
/*****************************************************************************
* Static variables
*****************************************************************************
* We can keep them static since they will always contain the same values.
*****************************************************************************/
static u8 pi_crop_buf[VDEC_CROPRANGE];
static u8 *pi_crop;
/*****************************************************************************
* vdec_InitDecode: initialize video decoder thread
*****************************************************************************/
void _M( vdec_InitDecode ) ( )
{
int i_dummy;
/* Init crop table */
pi_crop = pi_crop_buf + (VDEC_CROPRANGE >> 1);
for( i_dummy = -(VDEC_CROPRANGE >> 1); i_dummy < 0; i_dummy++ )
{
pi_crop[i_dummy] = 0;
}
for( ; i_dummy < 255; i_dummy ++ )
{
pi_crop[i_dummy] = i_dummy;
}
for( ; i_dummy < (VDEC_CROPRANGE >> 1) -1; i_dummy++ )
{
pi_crop[i_dummy] = 255;
}
}
/*****************************************************************************
* vdec_AddBlock : add a block
*****************************************************************************/
void _M( vdec_AddBlock ) ( dctelem_t * p_block, yuv_data_t * p_data,
int i_incr )
{
int i = 8;
do {
p_data[0] = pi_crop[ p_data[0] + p_block[0] ];
p_data[1] = pi_crop[ p_data[1] + p_block[1] ];
p_data[2] = pi_crop[ p_data[2] + p_block[2] ];
p_data[3] = pi_crop[ p_data[3] + p_block[3] ];
p_data[4] = pi_crop[ p_data[4] + p_block[4] ];
p_data[5] = pi_crop[ p_data[5] + p_block[5] ];
p_data[6] = pi_crop[ p_data[6] + p_block[6] ];
p_data[7] = pi_crop[ p_data[7] + p_block[7] ];
p_data += i_incr;
p_block += 8;
} while( --i );
}
/*****************************************************************************
* vdec_CopyBlock : copy a block
*****************************************************************************/
void _M( vdec_CopyBlock )( dctelem_t * p_block, yuv_data_t * p_data,
int i_incr )
{
int i = 8;
do {
p_data[0] = pi_crop[ p_block[0] ];
p_data[1] = pi_crop[ p_block[1] ];
p_data[2] = pi_crop[ p_block[2] ];
p_data[3] = pi_crop[ p_block[3] ];
p_data[4] = pi_crop[ p_block[4] ];
p_data[5] = pi_crop[ p_block[5] ];
p_data[6] = pi_crop[ p_block[6] ];
p_data[7] = pi_crop[ p_block[7] ];
p_data += i_incr;
p_block += 8;
} while( --i );
}
/*****************************************************************************
* vdec_block_mmx.c: Macroblock copy functions in MMX assembly
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: vdec_block_mmx.c,v 1.8 2001/12/09 17:01:36 sam Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
* Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
/* MODULE_NAME defined in Makefile together with -DBUILTIN */
#ifdef BUILTIN
# include "modules_inner.h"
#else
# define _M( foo ) foo
#endif
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <string.h> /* memcpy(), memset() */
#include "common.h"
#include "intf_msg.h"
#include "threads.h"
#include "mtime.h"
#include "input_ext-dec.h"
#include "video.h"
#include "video_output.h"
#include "vdec_idct.h"
#include "modules.h"
#include "modules_export.h"
#include "mmx.h"
/*****************************************************************************
* vdec_InitDecode: initialize video decoder thread
*****************************************************************************/
void _M( vdec_InitDecode ) ( )
{
;
}
/*****************************************************************************
* vdec_AddBlock : add a block
*****************************************************************************/
#define ADD_MMX(offset,r1,r2,r3,r4) \
movq_m2r (*(p_data+2*i_incr), r1); \
packuswb_r2r (r4, r3); \
movq_r2r (r1, r2); \
p_data += i_incr; \
movq_r2m (r3, *p_data); \
punpcklbw_r2r (mm0, r1); \
paddsw_m2r (*(p_block+offset), r1); \
punpckhbw_r2r (mm0, r2); \
paddsw_m2r (*(p_block+offset+4), r2);
void _M( vdec_AddBlock ) ( dctelem_t * p_block, yuv_data_t * p_data,
int i_incr )
{
movq_m2r (*p_data, mm1);
pxor_r2r (mm0, mm0);
movq_m2r (*(p_data + i_incr), mm3);
movq_r2r (mm1, mm2);
punpcklbw_r2r (mm0, mm1);
movq_r2r (mm3, mm4);
paddsw_m2r (*(p_block+0*8), mm1);
punpckhbw_r2r (mm0, mm2);
paddsw_m2r (*(p_block+0*8+4), mm2);
punpcklbw_r2r (mm0, mm3);
paddsw_m2r (*(p_block+1*8), mm3);
packuswb_r2r (mm2, mm1);
punpckhbw_r2r (mm0, mm4);
movq_r2m (mm1, *p_data);
paddsw_m2r (*(p_block+1*8+4), mm4);
ADD_MMX (2*8, mm1, mm2, mm3, mm4);
ADD_MMX (3*8, mm3, mm4, mm1, mm2);
ADD_MMX (4*8, mm1, mm2, mm3, mm4);
ADD_MMX (5*8, mm3, mm4, mm1, mm2);
ADD_MMX (6*8, mm1, mm2, mm3, mm4);
ADD_MMX (7*8, mm3, mm4, mm1, mm2);
packuswb_r2r (mm4, mm3);
movq_r2m (mm3, *(p_data + i_incr));
}
/*****************************************************************************
* vdec_CopyBlock : copy a block
*****************************************************************************/
#define COPY_MMX(offset,r0,r1,r2) \
movq_m2r (*(p_block+offset), r0); \
p_data += i_incr; \
movq_m2r (*(p_block+offset+4), r1); \
movq_r2m (r2, *p_data); \
packuswb_r2r (r1, r0);
void _M( vdec_CopyBlock ) ( dctelem_t * p_block, yuv_data_t * p_data,
int i_incr )
{
movq_m2r (*(p_block+0*8), mm0);
movq_m2r (*(p_block+0*8+4), mm1);
movq_m2r (*(p_block+1*8), mm2);
packuswb_r2r (mm1, mm0);
movq_m2r (*(p_block+1*8+4), mm3);
movq_r2m (mm0, *p_data);
packuswb_r2r (mm3, mm2);
COPY_MMX (2*8, mm0, mm1, mm2);
COPY_MMX (3*8, mm2, mm3, mm0);
COPY_MMX (4*8, mm0, mm1, mm2);
COPY_MMX (5*8, mm2, mm3, mm0);
COPY_MMX (6*8, mm0, mm1, mm2);
COPY_MMX (7*8, mm2, mm3, mm0);
movq_r2m (mm2, *(p_data + i_incr));
}
/*****************************************************************************
* vout_mga.c: MGA video output display method
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: vout_mga.c,v 1.14 2002/01/19 19:54:01 gbazin Exp $
*
* Authors: Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
* Samuel Hocevar <sam@zoy.org>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <unistd.h> /* close() */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#include <fcntl.h> /* open() */
#include <sys/ioctl.h> /* ioctl() */
#include <sys/mman.h> /* PROT_WRITE */
#include <videolan/vlc.h>
#ifdef SYS_BSD
#include <sys/types.h> /* typedef ushort */
#endif
#include "video.h"
#include "video_output.h"
#include "vout_mga.h"
/*****************************************************************************
* vout_sys_t: video output MGA method descriptor
*****************************************************************************
* This structure is part of the video output thread descriptor.
* It describes the MGA specific properties of an output thread.
*****************************************************************************/
typedef struct vout_sys_s
{
int i_page_size;
byte_t *p_video;
/* MGA specific variables */
int i_fd;
int i_size;
mga_vid_config_t mga;
byte_t * p_mga_vid_base;
boolean_t b_g400;
} vout_sys_t;
#define DUMMY_WIDTH 720
#define DUMMY_HEIGHT 576
#define DUMMY_BITS_PER_PLANE 16
#define DUMMY_BYTES_PER_PIXEL 2
#define NUM_FRAMES 4
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int vout_Probe ( probedata_t *p_data );
static int vout_Create ( struct vout_thread_s * );
static int vout_Init ( struct vout_thread_s * );
static void vout_End ( struct vout_thread_s * );
static void vout_Destroy ( struct vout_thread_s * );
static int vout_Manage ( struct vout_thread_s * );
static void vout_Display ( struct vout_thread_s * );
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
void _M( vout_getfunctions )( function_list_t * p_function_list )
{
p_function_list->pf_probe = vout_Probe;
p_function_list->functions.vout.pf_create = vout_Create;
p_function_list->functions.vout.pf_init = vout_Init;
p_function_list->functions.vout.pf_end = vout_End;
p_function_list->functions.vout.pf_destroy = vout_Destroy;
p_function_list->functions.vout.pf_manage = vout_Manage;
p_function_list->functions.vout.pf_display = vout_Display;
p_function_list->functions.vout.pf_setpalette = NULL;
}
/*****************************************************************************
* intf_Probe: return a score
*****************************************************************************/
static int vout_Probe( probedata_t *p_data )
{
return( 10 );
}
/*****************************************************************************
* vout_Create: allocates dummy video thread output method
*****************************************************************************
* This function allocates and initializes a dummy vout method.
*****************************************************************************/
static int vout_Create( vout_thread_t *p_vout )
{
/* Allocate structure */
p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
if( p_vout->p_sys == NULL )
{
intf_ErrMsg("vout error: %s", strerror(ENOMEM) );
return( 1 );
}
if( (p_vout->p_sys->i_fd = open( "/dev/mga_vid", O_RDWR )) == -1 )
{
intf_ErrMsg( "vout error: can't open MGA driver /dev/mga_vid" );
free( p_vout->p_sys );
return( 1 );
}
p_vout->i_width = DUMMY_WIDTH;
p_vout->i_height = DUMMY_HEIGHT;
p_vout->i_screen_depth = DUMMY_BITS_PER_PLANE;
p_vout->i_bytes_per_pixel = DUMMY_BYTES_PER_PIXEL;
p_vout->i_bytes_per_line = DUMMY_WIDTH * DUMMY_BYTES_PER_PIXEL;
p_vout->p_sys->i_page_size = DUMMY_WIDTH * DUMMY_HEIGHT
* DUMMY_BYTES_PER_PIXEL;
/* Map two framebuffers a the very beginning of the fb */
p_vout->p_sys->p_video = malloc( 2 * p_vout->p_sys->i_page_size );
if( p_vout->p_sys->p_video == NULL )
{
intf_ErrMsg( "vout error: can't map video memory (%s)",
strerror(errno) );
free( p_vout->p_sys );
return( 1 );
}
/* Set and initialize buffers */
p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_video,
p_vout->p_sys->p_video + p_vout->p_sys->i_page_size );
return( 0 );
}
/*****************************************************************************
* vout_Init: initialize dummy video thread output method
*****************************************************************************/
static int vout_Init( vout_thread_t *p_vout )
{
/* create the MGA output */
p_vout->p_sys->mga.src_width = p_vout->i_width;
p_vout->p_sys->mga.src_height = p_vout->i_height;
/* FIXME: we should initialize these ones according to the streams */
p_vout->p_sys->mga.dest_width = p_vout->i_width;
p_vout->p_sys->mga.dest_height = p_vout->i_height;
//p_vout->p_sys->mga?dest_width = 400;
//p_vout->p_sys->mga.dest_height = 300;
p_vout->p_sys->mga.x_org = 0;
p_vout->p_sys->mga.y_org = 0;
p_vout->p_sys->mga.colkey_on = 0;
p_vout->p_sys->mga.num_frames = NUM_FRAMES;
p_vout->p_sys->mga.frame_size = ((p_vout->i_width + 31) & ~31) * p_vout->i_height + (((p_vout->i_width + 31) & ~31) * p_vout->i_height) / 2;
p_vout->p_sys->mga.format=MGA_VID_FORMAT_YV12;
p_vout->p_sys->mga.version=MGA_VID_VERSION;
if( ioctl(p_vout->p_sys->i_fd, MGA_VID_CONFIG, &p_vout->p_sys->mga) )
{
intf_ErrMsg( "vout error: mga_vid ioctl failed" );
}
if (p_vout->p_sys->mga.card_type == MGA_G200)
{
intf_Msg( "vout: detected MGA G200 (%d MB Ram)",
p_vout->p_sys->mga.ram_size );
p_vout->p_sys->b_g400 = 0;
}
else
{
intf_Msg( "vout: detected MGA G400 (%d MB Ram)",
p_vout->p_sys->mga.ram_size );
p_vout->p_sys->b_g400 = 1;
}
ioctl( p_vout->p_sys->i_fd, MGA_VID_ON, 0 );
p_vout->p_sys->i_size = ( (p_vout->p_sys->mga.src_width + 31) & ~31 )
* p_vout->p_sys->mga.src_height;
p_vout->p_sys->p_mga_vid_base = mmap( 0, p_vout->p_sys->i_size
+ p_vout->p_sys->i_size / 2,
PROT_WRITE, MAP_SHARED,
p_vout->p_sys->i_fd, 0 );
memset( p_vout->p_sys->p_mga_vid_base,
0x00, p_vout->p_sys->i_size );
memset( p_vout->p_sys->p_mga_vid_base + p_vout->p_sys->i_size,
0x00, p_vout->p_sys->i_size / 2 );
return( 0 );
}
/*****************************************************************************
* vout_End: terminate dummy video thread output method
*****************************************************************************/
static void vout_End( vout_thread_t *p_vout )
{
ioctl( p_vout->p_sys->i_fd, MGA_VID_OFF, 0 );
}
/*****************************************************************************
* vout_Destroy: destroy dummy video thread output method
*****************************************************************************
* Terminate an output method created by DummyCreateOutputMethod
*****************************************************************************/
static void vout_Destroy( vout_thread_t *p_vout )
{
close( p_vout->p_sys->i_fd );
free( p_vout->p_sys->p_video );
free( p_vout->p_sys );
}
/*****************************************************************************
* vout_Manage: handle dummy events
*****************************************************************************
* This function should be called regularly by video output thread. It manages
* console events. It returns a non null value on error.
*****************************************************************************/
static int vout_Manage( vout_thread_t *p_vout )
{
return( 0 );
}
/*****************************************************************************
* vout_Display: displays previously rendered output
*****************************************************************************
* This function send the currently rendered image to dummy image, waits until
* it is displayed and switch the two rendering buffers, preparing next frame.
*****************************************************************************/
static void vout_Display( vout_thread_t *p_vout )
{
;
}
/*****************************************************************************
* vout_mga.h: MGA video output display method headers
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: vout_mga.h,v 1.5 2002/01/05 15:17:12 sam Exp $
*
* Authors: Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
* Samuel Hocevar <sam@zoy.org>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Boston, MA 02111-1307, USA.
*****************************************************************************/
#ifndef __LINUX_MGAVID_H
#define __LINUX_MGAVID_H
typedef struct mga_vid_config_s
{
u16 version;
u16 card_type;
u32 ram_size;
u32 src_width;
u32 src_height;
u32 dest_width;
u32 dest_height;
u32 x_org;
u32 y_org;
u8 colkey_on;
u8 colkey_red;
u8 colkey_green;
u8 colkey_blue;
u32 format;
u32 frame_size;
u32 num_frames;
} mga_vid_config_t;
#define MGA_VID_FORMAT_YV12 0x32315659
#define MGA_VID_FORMAT_YUY2 (('Y'<<24)|('U'<<16)|('Y'<<8)|'2')
#define MGA_VID_CONFIG _IOR('J', 1, mga_vid_config_t)
#define MGA_VID_ON _IO ('J', 2)
#define MGA_VID_OFF _IO ('J', 3)
#define MGA_VID_FSEL _IOR('J', 4, int)
#define MGA_G200 0x1234
#define MGA_G400 0x5678
#define MGA_VID_VERSION 0x0201
#endif
/*****************************************************************************
* vdec_motion_common.c : common motion compensation routines common
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: vdec_motion_common.c,v 1.11 2001/12/09 17:01:36 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Jean-Marc Dressler <polux@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
/* MODULE_NAME defined in Makefile together with -DBUILTIN */
#ifdef BUILTIN
# include "modules_inner.h"
#else
# define _M( foo ) foo
#endif
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "intf_msg.h"
#include "video.h"
#include "vdec_ext-plugins.h"
#include "modules.h"
#include "modules_export.h"
extern int _M( 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 _M( motion_getfunctions )( function_list_t * p_function_list )
{
p_function_list->pf_probe = _M( 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;
}
#define __MotionComponents(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_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 )();
__MotionComponents (16,16) /* 444, 422, 420 */
__MotionComponents (16,8) /* 444, 422, 420 */
__MotionComponents (8,8) /* 422, 420 */
__MotionComponents (8,4) /* 420 */
#if 0
__MotionComponents (8,16) /* 422 */
#endif
#define ___callTheRightOne(width,height) \
if ((i_width == width) && (i_height == height)) \
{ \
if (!b_average) \
{ \
switch (i_select) \
{ \
case 0: \
_M( MotionComponent_x_y_copy_##width##_##height )(p_src, \
p_dest, i_stride); \
break; \
case 1: \
_M( MotionComponent_X_y_copy_##width##_##height )(p_src, \
p_dest, i_stride); \
break; \
case 2: \
_M( MotionComponent_x_Y_copy_##width##_##height )(p_src, \
p_dest, i_stride); \
break; \
case 3: \
_M( MotionComponent_X_Y_copy_##width##_##height )(p_src, \
p_dest, i_stride); \
break; \
} \
} \
else \
{ \
switch (i_select) \
{ \
case 0: \
_M( MotionComponent_x_y_avg_##width##_##height )(p_src, \
p_dest, i_stride); \
break; \
case 1: \
_M( MotionComponent_X_y_avg_##width##_##height )(p_src, \
p_dest, i_stride); \
break; \
case 2: \
_M( MotionComponent_x_Y_avg_##width##_##height )(p_src, \
p_dest, i_stride); \
break; \
case 3: \
_M( MotionComponent_X_Y_avg_##width##_##height )(p_src, \
p_dest, i_stride); \
break; \
} \
} \
}
/*****************************************************************************
* vdec_MotionComponent : last stage of motion compensation
*****************************************************************************/
static __inline__ void MotionComponent(
pixel_data_t * p_src, /* source block */
pixel_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 */ )
{
___callTheRightOne (16,16)
___callTheRightOne (16,8)
___callTheRightOne (8,8)
___callTheRightOne (8,4)
#if 0
___callTheRightOne (8,16)
#endif
}
/*****************************************************************************
* 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;
i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1))
+ (p_mb->i_motion_l_y + i_offset
+ b_source_field)
* p_mb->p_picture->i_width
+ (i_mv_y >> 1) * i_l_stride;
if( i_source_offset >= p_source->i_size )
{
intf_WarnMsg( 2, "Bad motion vector (lum)" );
return;
}
/* Luminance */
MotionComponent( /* source */
p_source->planes[ Y_PLANE ].p_data
+ i_source_offset,
/* destination */
p_mb->p_picture->planes[ Y_PLANE ].p_data
+ (p_mb->i_l_x)
+ (p_mb->i_motion_l_y + b_dest_field + i_offset)
* p_mb->p_picture->i_width,
/* prediction width and height */
16, i_height,
/* stride */
i_l_stride,
/* 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))
+ (p_mb->i_motion_c_y + (i_offset >> 1)
+ b_source_field)
* p_mb->p_picture->i_chroma_width
+ ((i_mv_y/2) >> 1) * i_c_stride;
if( i_source_offset >= p_source->i_chroma_size )
{
intf_WarnMsg( 2, "Bad motion vector (chroma)" );
return;
}
i_dest_offset = (p_mb->i_c_x)
+ (p_mb->i_motion_c_y + b_dest_field
+ (i_offset >> 1))
* 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->planes[ U_PLANE ].p_data
+ i_source_offset,
p_mb->p_picture->planes[ U_PLANE ].p_data
+ i_dest_offset,
8, i_c_height, i_c_stride,
i_c_select, b_average );
/* Chrominance Cb */
MotionComponent( p_source->planes[ V_PLANE ].p_data
+ i_source_offset,
p_mb->p_picture->planes[ V_PLANE ].p_data
+ i_dest_offset,
8, i_c_height, i_c_stride,
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 */ )
{
#if 0
int i_source_offset, i_dest_offset, i_c_select;
/* Luminance */
MotionComponent( /* source */
p_source->planes[ Y_PLANE ].p_data
+ (p_mb->i_l_x + (i_mv_x >> 1))
+ (p_mb->i_motion_l_y + i_offset
+ b_source_field)
* p_mb->p_picture->i_width
+ (i_mv_y >> 1) * p_mb->i_l_stride,
/* destination */
p_mb->p_picture->planes[ Y_PLANE ].p_data
+ (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 */
i_l_stride,
/* 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))
+ (p_mb->i_motion_c_y + i_offset
+ b_source_field)
* p_mb->p_picture->i_chroma_width
+ (i_mv_y) >> 1) * p_mb->i_c_stride;
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->planes[ U_PLANE ].p_data
+ i_source_offset,
p_mb->p_picture->planes[ U_PLANE ].p_data
+ i_dest_offset,
8, i_height, i_c_stride,
i_c_select, b_average );
/* Chrominance Cb */
MotionComponent( p_source->planes[ V_PLANE ].p_data
+ i_source_offset,
p_mb->p_picture->planes[ U_PLANE ].p_data
+ i_dest_offset,
8, i_height, i_c_stride,
i_c_select, b_average );
#endif
}
/*****************************************************************************
* 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 */ )
{
#if 0
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)
* p_mb->p_picture->i_width
+ (i_mv_y >> 1) * p_mb->i_l_stride;
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->planes[ Y_PLANE ].p_data
+ i_source_offset,
p_mb->p_picture->planes[ Y_PLANE ].p_data
+ i_dest_offset,
16, i_height, i_l_stride,
i_select, b_average );
/* Chrominance Cr */
MotionComponent( p_source->planes[ U_PLANE ].p_data
+ i_source_offset,
p_mb->p_picture->planes[ U_PLANE ].p_data
+ i_dest_offset,
16, i_height, i_l_stride,
i_select, b_average );
/* Chrominance Cb */
MotionComponent( p_source->planes[ V_PLANE ].p_data
+ i_source_offset,
p_mb->p_picture->planes[ V_PLANE ].p_data
+ i_dest_offset,
16, i_height, i_l_stride,
i_select, b_average );
#endif
}
/*****************************************************************************
* vdec_MotionFieldField : motion compensation for field motion type (field)
*****************************************************************************/
#define FIELDFIELD( MOTION ) \
{ \
picture_t * p_pred; \
\
if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
{ \
if( p_mb->b_P_second \
&& (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 ); \
} \
} \
\
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 ); \
} \
}
static void vdec_MotionFieldField420( macroblock_t * p_mb )
{
FIELDFIELD( Motion420 )
}
static void vdec_MotionFieldField422( macroblock_t * p_mb )
{
//FIELDFIELD( Motion422 )
}
static void vdec_MotionFieldField444( macroblock_t * p_mb )
{
//FIELDFIELD( Motion444 )
}
/*****************************************************************************
* vdec_MotionField16x8XXX: motion compensation for 16x8 motion type (field)
*****************************************************************************/
#define FIELD16X8( MOTION ) \
{ \
picture_t * p_pred; \
\
if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
{ \
if( p_mb->b_P_second \
&& (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 ); \
\
if( p_mb->b_P_second \
&& (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 ); \
} \
}
static void vdec_MotionField16x8420( macroblock_t * p_mb )
{
FIELD16X8( Motion420 )
}
static void vdec_MotionField16x8422( macroblock_t * p_mb )
{
//FIELD16X8( Motion422 )
}
static void vdec_MotionField16x8444( macroblock_t * p_mb )
{
//FIELD16X8( Motion444 )
}
/*****************************************************************************
* vdec_MotionFieldDMVXXX : motion compensation for dmv motion type (field)
*****************************************************************************/
#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 */
static void vdec_MotionFieldDMV420( macroblock_t * p_mb )
{
FIELDDMV( Motion420 )
}
static void vdec_MotionFieldDMV422( macroblock_t * p_mb )
{
//FIELDDMV( Motion422 )
}
static void vdec_MotionFieldDMV444( macroblock_t * p_mb )
{
//FIELDDMV( Motion444 )
}
/*****************************************************************************
* vdec_MotionFrameFrameXXX?? : motion compensation for frame motion type (frame)
*****************************************************************************/
#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 */
static void vdec_MotionFrameFrame420( macroblock_t * p_mb )
{
FRAMEFRAME( Motion420 )
}
static void vdec_MotionFrameFrame422( macroblock_t * p_mb )
{
//FRAMEFRAME( Motion422 )
}
static void vdec_MotionFrameFrame444( macroblock_t * p_mb )
{
//FRAMEFRAME( Motion444 )
}
/*****************************************************************************
* vdec_MotionFrameFieldXXX?? : motion compensation for field motion type (frame)
*****************************************************************************/
#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], \
p_mb->pppi_motion_vectors[0][0][1] >> 1, \
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], \
p_mb->pppi_motion_vectors[1][0][1] >> 1, \
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], \
p_mb->pppi_motion_vectors[0][1][1] >> 1, \
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], \
p_mb->pppi_motion_vectors[1][1][1] >> 1, \
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], \
p_mb->pppi_motion_vectors[0][1][1] >> 1, \
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], \
p_mb->pppi_motion_vectors[1][1][1] >> 1, \
i_l_stride, i_c_stride, 8, 0, 0 ); \
} \
} /* FRAMEFIELD */
static void vdec_MotionFrameField420( macroblock_t * p_mb )
{
FRAMEFIELD( Motion420 )
}
static void vdec_MotionFrameField422( macroblock_t * p_mb )
{
//FRAMEFIELD( Motion422 )
}
static void vdec_MotionFrameField444( macroblock_t * p_mb )
{
//FRAMEFIELD( Motion444 )
}
/*****************************************************************************
* vdec_MotionFrameDMVXXX?? : motion compensation for dmv motion type (frame)
*****************************************************************************/
#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], \
/* XXX?? XXX?? >> 1 ? */ \
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], \
/* XXX?? XXX?? >> 1 ? */ \
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 */
static void vdec_MotionFrameDMV420( macroblock_t * p_mb )
{
FRAMEDMV( Motion420 )
}
static void vdec_MotionFrameDMV422( macroblock_t * p_mb )
{
//FRAMEDMV( Motion422 )
}
static void vdec_MotionFrameDMV444( macroblock_t * p_mb )
{
//FRAMEDMV( Motion444 )
}
/*****************************************************************************
* vdec_motion_inner.c : motion compensation inner routines
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: vdec_motion_inner.c,v 1.5 2001/12/09 17:01:36 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Jean-Marc Dressler <polux@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
#define MODULE_NAME motion
#include "modules_inner.h"
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include "common.h"
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "threads.h"
#include "mtime.h"
#include "video.h"
#define __MotionComponent_x_y_copy(width,height) \
void _M(MotionComponent_x_y_copy_##width##_##height) \
( pixel_data_t *p_src, pixel_data_t *p_dest, int i_stride ) \
{ \
int i_x, i_y; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
for( i_x = 0; i_x < width; i_x++ ) \
{ \
p_dest[i_x] = p_src[i_x]; \
} \
p_dest += i_stride; \
p_src += i_stride; \
} \
}
#define __MotionComponent_X_y_copy(width,height) \
void _M(MotionComponent_X_y_copy_##width##_##height) \
( pixel_data_t *p_src, pixel_data_t *p_dest, int i_stride ) \
{ \
int i_x, i_y; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
for( i_x = 0; i_x < width; i_x++ ) \
{ \
p_dest[i_x] = (unsigned int)(p_src[i_x] \
+ p_src[i_x + 1] \
+ 1) >> 1; \
} \
p_dest += i_stride; \
p_src += i_stride; \
} \
}
#define __MotionComponent_x_Y_copy(width,height) \
void _M(MotionComponent_x_Y_copy_##width##_##height) \
( pixel_data_t *p_src, pixel_data_t *p_dest, int i_stride ) \
{ \
int i_x, i_y; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
for( i_x = 0; i_x < width; i_x++ ) \
{ \
p_dest[i_x] = (unsigned int)(p_src[i_x] \
+ p_src[i_x + i_stride] \
+ 1) >> 1; \
} \
p_dest += i_stride; \
p_src += i_stride; \
} \
}
#define __MotionComponent_X_Y_copy(width,height) \
void _M(MotionComponent_X_Y_copy_##width##_##height) \
( pixel_data_t *p_src, pixel_data_t *p_dest, int i_stride ) \
{ \
int i_x, i_y; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
for( i_x = 0; i_x < width; i_x++ ) \
{ \
p_dest[i_x] = (unsigned int)(p_src[i_x] \
+ p_src[i_x + 1] \
+ p_src[i_x + i_stride] \
+ p_src[i_x + i_stride + 1] \
+ 2) >> 2; \
} \
p_dest += i_stride; \
p_src += i_stride; \
} \
}
#define __MotionComponent_x_y_avg(width,height) \
void _M(MotionComponent_x_y_avg_##width##_##height) \
( pixel_data_t * p_src, pixel_data_t * p_dest, int i_stride ) \
{ \
int i_x, i_y; \
unsigned int i_dummy; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
for( i_x = 0; i_x < width; i_x++ ) \
{ \
i_dummy = p_dest[i_x] + p_src[i_x]; \
p_dest[i_x] = (i_dummy + 1) >> 1; \
} \
p_dest += i_stride; \
p_src += i_stride; \
} \
}
#define __MotionComponent_X_y_avg(width,height) \
void _M(MotionComponent_X_y_avg_##width##_##height) \
( pixel_data_t * p_src, pixel_data_t * p_dest, int i_stride ) \
{ \
int i_x, i_y; \
unsigned int i_dummy; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
for( i_x = 0; i_x < width; i_x++ ) \
{ \
i_dummy = p_dest[i_x] + ((unsigned int)(p_src[i_x] \
+ p_src[i_x + 1] \
+ 1) >> 1); \
p_dest[i_x] = (i_dummy + 1) >> 1; \
} \
p_dest += i_stride; \
p_src += i_stride; \
} \
}
#define __MotionComponent_x_Y_avg(width,height) \
void _M(MotionComponent_x_Y_avg_##width##_##height) \
( pixel_data_t * p_src, pixel_data_t * p_dest, int i_stride ) \
{ \
int i_x, i_y; \
unsigned int i_dummy; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
for( i_x = 0; i_x < width; i_x++ ) \
{ \
i_dummy = \
p_dest[i_x] + ((unsigned int)(p_src[i_x] \
+ p_src[i_x + i_stride] \
+ 1) >> 1); \
p_dest[i_x] = (i_dummy + 1) >> 1; \
} \
p_dest += i_stride; \
p_src += i_stride; \
} \
}
#define __MotionComponent_X_Y_avg(width,height) \
void _M(MotionComponent_X_Y_avg_##width##_##height) \
( pixel_data_t * p_src, pixel_data_t * p_dest, int i_stride ) \
{ \
int i_x, i_y; \
unsigned int i_dummy; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
for( i_x = 0; i_x < width; i_x++ ) \
{ \
i_dummy = \
p_dest[i_x] + ((unsigned int)(p_src[i_x] \
+ p_src[i_x + 1] \
+ p_src[i_x + i_stride] \
+ p_src[i_x + i_stride + 1] \
+ 2) >> 2); \
p_dest[i_x] = (i_dummy + 1) >> 1; \
} \
p_dest += i_stride; \
p_src += i_stride; \
} \
}
#define __MotionComponents(width,height) \
__MotionComponent_x_y_copy(width,height) \
__MotionComponent_X_y_copy(width,height) \
__MotionComponent_x_Y_copy(width,height) \
__MotionComponent_X_Y_copy(width,height) \
__MotionComponent_x_y_avg(width,height) \
__MotionComponent_X_y_avg(width,height) \
__MotionComponent_x_Y_avg(width,height) \
__MotionComponent_X_Y_avg(width,height)
__MotionComponents (16,16) /* 444, 422, 420 */
__MotionComponents (16,8) /* 444, 422, 420 */
__MotionComponents (8,8) /* 422, 420 */
__MotionComponents (8,4) /* 420 */
#if 0
__MotionComponents (8,16) /* 422 */
#endif
/*****************************************************************************
* vdec_motion_inner_mmx.c : motion compensation inner routines optimized in
* MMX
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: vdec_motion_inner_mmx.c,v 1.5 2001/12/09 17:01:36 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>, largerly inspired by the
* work done by the livid project <http://www.linuxvideo.org/>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
#define MODULE_NAME motionmmx
#include "modules_inner.h"
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include "common.h"
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "threads.h"
#include "mtime.h"
#include "video.h"
#include "attributes.h"
#include "mmx.h"
/* OK, I know, this code has been taken from livid's mpeg2dec --Meuuh */
/* Some rounding constants */
mmx_t round1 = {0x0001000100010001LL};
mmx_t round4 = {0x0002000200020002LL};
/*
* Useful functions
*/
static __inline__ void MMXZeroReg()
{
/* load 0 into mm0 */
pxor_r2r(mm0,mm0);
}
static __inline__ void MMXAverage2( u8 *dst, u8 *src1, u8 *src2 )
{
//
// *dst = clip_to_u8((*src1 + *src2 + 1)/2);
//
movq_m2r(*src1,mm1); // load 8 src1 bytes
movq_r2r(mm1,mm2); // copy 8 src1 bytes
movq_m2r(*src2,mm3); // load 8 src2 bytes
movq_r2r(mm3,mm4); // copy 8 src2 bytes
punpcklbw_r2r(mm0,mm1); // unpack low src1 bytes
punpckhbw_r2r(mm0,mm2); // unpack high src1 bytes
punpcklbw_r2r(mm0,mm3); // unpack low src2 bytes
punpckhbw_r2r(mm0,mm4); // unpack high src2 bytes
paddw_r2r(mm3,mm1); // add lows to mm1
paddw_m2r(round1,mm1);
psraw_i2r(1,mm1); // /2
paddw_r2r(mm4,mm2); // add highs to mm2
paddw_m2r(round1,mm2);
psraw_i2r(1,mm2); // /2
packuswb_r2r(mm2,mm1); // pack (w/ saturation)
movq_r2m(mm1,*dst); // store result in dst
}
static __inline__ void MMXInterpAverage2( u8 *dst, u8 *src1, u8 *src2 )
{
//
// *dst = clip_to_u8((*dst + (*src1 + *src2 + 1)/2 + 1)/2);
//
movq_m2r(*dst,mm1); // load 8 dst bytes
movq_r2r(mm1,mm2); // copy 8 dst bytes
movq_m2r(*src1,mm3); // load 8 src1 bytes
movq_r2r(mm3,mm4); // copy 8 src1 bytes
movq_m2r(*src2,mm5); // load 8 src2 bytes
movq_r2r(mm5,mm6); // copy 8 src2 bytes
punpcklbw_r2r(mm0,mm1); // unpack low dst bytes
punpckhbw_r2r(mm0,mm2); // unpack high dst bytes
punpcklbw_r2r(mm0,mm3); // unpack low src1 bytes
punpckhbw_r2r(mm0,mm4); // unpack high src1 bytes
punpcklbw_r2r(mm0,mm5); // unpack low src2 bytes
punpckhbw_r2r(mm0,mm6); // unpack high src2 bytes
paddw_r2r(mm5,mm3); // add lows
paddw_m2r(round1,mm3);
psraw_i2r(1,mm3); // /2
paddw_r2r(mm6,mm4); // add highs
paddw_m2r(round1,mm4);
psraw_i2r(1,mm4); // /2
paddw_r2r(mm3,mm1); // add lows
paddw_m2r(round1,mm1);
psraw_i2r(1,mm1); // /2
paddw_r2r(mm4,mm2); // add highs
paddw_m2r(round1,mm2);
psraw_i2r(1,mm2); // /2
packuswb_r2r(mm2,mm1); // pack (w/ saturation)
movq_r2m(mm1,*dst); // store result in dst
}
static __inline__ void MMXAverage4( u8 *dst, u8 *src1, u8 *src2, u8 *src3,
u8 *src4 )
{
//
// *dst = (*src1 + *src2 + *src3 + *src4 + 2) / 4;
//
movq_m2r(*src1,mm1); // load 8 src1 bytes
movq_r2r(mm1,mm2); // copy 8 src1 bytes
punpcklbw_r2r(mm0,mm1); // unpack low src1 bytes
punpckhbw_r2r(mm0,mm2); // unpack high src1 bytes
movq_m2r(*src2,mm3); // load 8 src2 bytes
movq_r2r(mm3,mm4); // copy 8 src2 bytes
punpcklbw_r2r(mm0,mm3); // unpack low src2 bytes
punpckhbw_r2r(mm0,mm4); // unpack high src2 bytes
paddw_r2r(mm3,mm1); // add lows
paddw_r2r(mm4,mm2); // add highs
// now have partials in mm1 and mm2
movq_m2r(*src3,mm3); // load 8 src3 bytes
movq_r2r(mm3,mm4); // copy 8 src3 bytes
punpcklbw_r2r(mm0,mm3); // unpack low src3 bytes
punpckhbw_r2r(mm0,mm4); // unpack high src3 bytes
paddw_r2r(mm3,mm1); // add lows
paddw_r2r(mm4,mm2); // add highs
movq_m2r(*src4,mm5); // load 8 src4 bytes
movq_r2r(mm5,mm6); // copy 8 src4 bytes
punpcklbw_r2r(mm0,mm5); // unpack low src4 bytes
punpckhbw_r2r(mm0,mm6); // unpack high src4 bytes
paddw_r2r(mm5,mm1); // add lows
paddw_r2r(mm6,mm2); // add highs
// now have subtotal in mm1 and mm2
paddw_m2r(round4,mm1);
psraw_i2r(2,mm1); // /4
paddw_m2r(round4,mm2);
psraw_i2r(2,mm2); // /4
packuswb_r2r(mm2,mm1); // pack (w/ saturation)
movq_r2m(mm1,*dst); // store result in dst
}
static __inline__ void MMXInterpAverage4( u8 *dst, u8 *src1, u8 *src2,
u8 *src3, u8 *src4 )
{
//
// *dst = clip_to_u8((*dst + (*src1 + *src2 + *src3 + *src4 + 2)/4 + 1)/2);
//
movq_m2r(*src1,mm1); // load 8 src1 bytes
movq_r2r(mm1,mm2); // copy 8 src1 bytes
punpcklbw_r2r(mm0,mm1); // unpack low src1 bytes
punpckhbw_r2r(mm0,mm2); // unpack high src1 bytes
movq_m2r(*src2,mm3); // load 8 src2 bytes
movq_r2r(mm3,mm4); // copy 8 src2 bytes
punpcklbw_r2r(mm0,mm3); // unpack low src2 bytes
punpckhbw_r2r(mm0,mm4); // unpack high src2 bytes
paddw_r2r(mm3,mm1); // add lows
paddw_r2r(mm4,mm2); // add highs
// now have partials in mm1 and mm2
movq_m2r(*src3,mm3); // load 8 src3 bytes
movq_r2r(mm3,mm4); // copy 8 src3 bytes
punpcklbw_r2r(mm0,mm3); // unpack low src3 bytes
punpckhbw_r2r(mm0,mm4); // unpack high src3 bytes
paddw_r2r(mm3,mm1); // add lows
paddw_r2r(mm4,mm2); // add highs
movq_m2r(*src4,mm5); // load 8 src4 bytes
movq_r2r(mm5,mm6); // copy 8 src4 bytes
punpcklbw_r2r(mm0,mm5); // unpack low src4 bytes
punpckhbw_r2r(mm0,mm6); // unpack high src4 bytes
paddw_r2r(mm5,mm1); // add lows
paddw_r2r(mm6,mm2); // add highs
paddw_m2r(round4,mm1);
psraw_i2r(2,mm1); // /4
paddw_m2r(round4,mm2);
psraw_i2r(2,mm2); // /4
// now have subtotal/4 in mm1 and mm2
movq_m2r(*dst,mm3); // load 8 dst bytes
movq_r2r(mm3,mm4); // copy 8 dst bytes
punpcklbw_r2r(mm0,mm3); // unpack low dst bytes
punpckhbw_r2r(mm0,mm4); // unpack high dst bytes
paddw_r2r(mm3,mm1); // add lows
paddw_r2r(mm4,mm2); // add highs
paddw_m2r(round1,mm1);
psraw_i2r(1,mm1); // /2
paddw_m2r(round1,mm2);
psraw_i2r(1,mm2); // /2
// now have end value in mm1 and mm2
packuswb_r2r(mm2,mm1); // pack (w/ saturation)
movq_r2m(mm1,*dst); // store result in dst
}
/*
* Actual Motion compensation
*/
#define pavg_r2r(src,dest) pavgusb_r2r (src, dest);
#define pavg_m2r(src,dest) pavgusb_m2r (src, dest);
#define __MotionComponent_x_y_copy(width,height) \
void _M(MotionComponent_x_y_copy_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
\
MMXZeroReg(); \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
movq_m2r( *p_src, mm0 ); /* load 8 ref bytes */ \
if( width == 16 ) \
movq_m2r( *(p_src + 8), mm1 ); \
p_src += i_stride; \
\
movq_r2m( mm0, *p_dest ); /* store 8 bytes at curr */ \
if( width == 16 ) \
movq_r2m( mm1, *(p_dest + 8) ); \
p_dest += i_stride; \
} \
}
#define __MotionComponent_X_y_copy(width,height) \
void _M(MotionComponent_X_y_copy_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
\
MMXZeroReg(); \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
MMXAverage2( p_dest, p_src, p_src + 1 ); \
\
if( width == 16 ) \
{ \
MMXAverage2( p_dest + 8, p_src + 8, p_src + 9 ); \
} \
\
p_dest += i_stride; \
p_src += i_stride; \
} \
}
#define __MotionComponent_x_Y_copy(width,height) \
void _M(MotionComponent_x_Y_copy_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
pixel_data_t * p_next_src = p_src + i_stride; \
\
MMXZeroReg(); \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
MMXAverage2( p_dest, p_src, p_next_src ); \
\
if( width == 16 ) \
{ \
MMXAverage2( p_dest + 8, p_src + 8, p_next_src + 8 ); \
} \
\
p_dest += i_stride; \
p_src += i_stride; \
p_next_src += i_stride; \
} \
}
#define __MotionComponent_X_Y_copy(width,height) \
void _M(MotionComponent_X_Y_copy_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
pixel_data_t * p_next_src = p_src + i_stride; \
\
MMXZeroReg(); \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
MMXAverage4( p_dest, p_src, p_src + 1, p_next_src, p_next_src + 1 );\
\
if( width == 16 ) \
{ \
MMXAverage4( p_dest + 8, p_src + 8, p_src + 9, \
p_next_src + 8, p_next_src + 9 ); \
} \
\
p_dest += i_stride; \
p_src += i_stride; \
p_next_src += i_stride; \
} \
}
#define __MotionComponent_x_y_avg(width,height) \
void _M(MotionComponent_x_y_avg_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
\
MMXZeroReg(); \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
MMXAverage2( p_dest, p_dest, p_src ); \
\
if( width == 16 ) \
{ \
MMXAverage2( p_dest + 8, p_dest + 8, p_src + 8 ); \
} \
\
p_dest += i_stride; \
p_src += i_stride; \
} \
}
#define __MotionComponent_X_y_avg(width,height) \
void _M(MotionComponent_X_y_avg_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
\
MMXZeroReg(); \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
MMXInterpAverage2( p_dest, p_src, p_src + 1 ); \
\
if( width == 16 ) \
{ \
MMXInterpAverage2( p_dest + 8, p_src + 8, p_src + 9 ); \
} \
\
p_dest += i_stride; \
p_src += i_stride; \
} \
}
#define __MotionComponent_x_Y_avg(width,height) \
void _M(MotionComponent_x_Y_avg_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
pixel_data_t * p_next_src = p_src + i_stride; \
\
MMXZeroReg(); \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
MMXInterpAverage2( p_dest, p_src, p_next_src ); \
\
if( width == 16 ) \
{ \
MMXInterpAverage2( p_dest + 8, p_src + 8, p_next_src + 8 ); \
} \
p_dest += i_stride; \
p_src += i_stride; \
p_next_src += i_stride; \
} \
}
#define __MotionComponent_X_Y_avg(width,height) \
void _M(MotionComponent_X_Y_avg_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
pixel_data_t * p_next_src = p_src + i_stride; \
\
MMXZeroReg(); \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
MMXInterpAverage4( p_dest, p_src, p_src + 1, p_next_src, \
p_next_src + 1 ); \
\
if( width == 16 ) \
{ \
MMXInterpAverage4( p_dest + 8, p_src + 8, p_src + 9, \
p_next_src + 8, p_next_src + 9 ); \
} \
\
p_dest += i_stride; \
p_src += i_stride; \
p_next_src += i_stride; \
} \
}
#define __MotionComponents(width,height) \
__MotionComponent_x_y_copy(width,height) \
__MotionComponent_X_y_copy(width,height) \
__MotionComponent_x_Y_copy(width,height) \
__MotionComponent_X_Y_copy(width,height) \
__MotionComponent_x_y_avg(width,height) \
__MotionComponent_X_y_avg(width,height) \
__MotionComponent_x_Y_avg(width,height) \
__MotionComponent_X_Y_avg(width,height)
__MotionComponents (16,16) /* 444, 422, 420 */
__MotionComponents (16,8) /* 444, 422, 420 */
__MotionComponents (8,8) /* 422, 420 */
__MotionComponents (8,4) /* 420 */
#if 0
__MotionComponents (8,16) /* 422 */
#endif
/*****************************************************************************
* vdec_motion_inner_mmxext.c : motion compensation inner routines optimized
* in MMX EXT
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: vdec_motion_inner_mmxext.c,v 1.5 2001/12/09 17:01:36 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>, largerly inspired by the
* work done by the livid project <http://www.linuxvideo.org/>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.
*****************************************************************************/
#define MODULE_NAME motionmmxext
#include "modules_inner.h"
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include "common.h"
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "threads.h"
#include "mtime.h"
#include "video.h"
#include "attributes.h"
#include "mmx.h"
/* OK, I know, this code has been taken from livid's mpeg2dec --Meuuh */
static mmx_t mask_one = {0x0101010101010101LL};
/*
* Useful functions
*/
#define pavg_r2r(src,dest) pavgb_r2r (src, dest);
#define pavg_m2r(src,dest) pavgb_m2r (src, dest);
#define __MotionComponent_x_y_copy(width,height) \
void _M(MotionComponent_x_y_copy_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
\
pxor_r2r (mm0, mm0); \
pxor_r2r (mm1, mm1); \
pxor_r2r (mm2, mm2); \
pxor_r2r (mm3, mm3); \
pxor_r2r (mm4, mm4); \
pxor_r2r (mm5, mm5); \
pxor_r2r (mm6, mm6); \
pxor_r2r (mm7, mm7); \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
movq_m2r( *p_src, mm0 ); /* load 8 ref bytes */ \
if( width == 16 ) \
movq_m2r( *(p_src + 8), mm1 ); \
p_src += i_stride; \
\
movq_r2m( mm0, *p_dest ); /* store 8 bytes at curr */ \
if( width == 16 ) \
movq_r2m( mm1, *(p_dest + 8) ); \
p_dest += i_stride; \
} \
}
#define __MotionComponent_X_y_copy(width,height) \
void _M(MotionComponent_X_y_copy_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
movq_m2r (*p_src, mm0); \
if( width == 16 ) \
movq_m2r (*(p_src + 8), mm1); \
pavg_m2r (*(p_src + 1), mm0); \
if( width == 16 ) \
pavg_m2r (*(p_src + 9), mm1); \
movq_r2m (mm0, *p_dest); \
p_src += i_stride; \
if( width == 16 ) \
movq_r2m (mm1, *(p_dest + 8)); \
p_dest += i_stride; \
} \
}
#define __MotionComponent_x_Y_copy(width,height) \
void _M(MotionComponent_x_Y_copy_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
pixel_data_t * p_next_src = p_src + i_stride; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
movq_m2r (*p_src, mm0); \
if( width == 16 ) \
movq_m2r (*(p_src + 8), mm1); \
pavg_m2r (*(p_next_src), mm0); \
if( width == 16 ) \
pavg_m2r (*(p_next_src + 8), mm1); \
movq_r2m (mm0, *p_dest); \
p_src += i_stride; \
p_next_src += i_stride; \
if( width == 16 ) \
movq_r2m (mm1, *(p_dest + 8)); \
p_dest += i_stride; \
} \
}
#define __MotionComponent_X_Y_copy(width,height) \
void _M(MotionComponent_X_Y_copy_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
\
if( width == 16 ) \
{ \
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
movq_m2r (*p_src, mm0); \
movq_m2r (*(p_src+i_stride+1), mm1); \
movq_r2r (mm0, mm7); \
movq_m2r (*(p_src+1), mm2); \
pxor_r2r (mm1, mm7); \
movq_m2r (*(p_src + i_stride), mm3); \
movq_r2r (mm2, mm6); \
pxor_r2r (mm3, mm6); \
pavg_r2r (mm1, mm0); \
pavg_r2r (mm3, mm2); \
por_r2r (mm6, mm7); \
movq_r2r (mm0, mm6); \
pxor_r2r (mm2, mm6); \
pand_r2r (mm6, mm7); \
pand_m2r (mask_one, mm7); \
pavg_r2r (mm2, mm0); \
psubusb_r2r (mm7, mm0); \
movq_r2m (mm0, *p_dest); \
\
movq_m2r (*(p_src+8), mm0); \
movq_m2r (*(p_src+i_stride+9), mm1); \
movq_r2r (mm0, mm7); \
movq_m2r (*(p_src+9), mm2); \
pxor_r2r (mm1, mm7); \
movq_m2r (*(p_src+i_stride+8), mm3); \
movq_r2r (mm2, mm6); \
pxor_r2r (mm3, mm6); \
pavg_r2r (mm1, mm0); \
pavg_r2r (mm3, mm2); \
por_r2r (mm6, mm7); \
movq_r2r (mm0, mm6); \
pxor_r2r (mm2, mm6); \
pand_r2r (mm6, mm7); \
pand_m2r (mask_one, mm7); \
pavg_r2r (mm2, mm0); \
psubusb_r2r (mm7, mm0); \
p_src += i_stride; \
movq_r2m (mm0, *(p_dest+8)); \
p_dest += i_stride; \
} \
} \
else \
{ \
movq_m2r (*p_src, mm0); \
movq_m2r (*(p_src+1), mm1); \
movq_r2r (mm0, mm7); \
pxor_r2r (mm1, mm7); \
pavg_r2r (mm1, mm0); \
p_src += i_stride; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
movq_m2r (*p_src, mm2); \
movq_r2r (mm0, mm5); \
movq_m2r (*(p_src+1), mm3); \
movq_r2r (mm2, mm6); \
pxor_r2r (mm3, mm6); \
pavg_r2r (mm3, mm2); \
por_r2r (mm6, mm7); \
pxor_r2r (mm2, mm5); \
pand_r2r (mm5, mm7); \
pavg_r2r (mm2, mm0); \
pand_m2r (mask_one, mm7); \
psubusb_r2r (mm7, mm0); \
p_src += i_stride; \
movq_r2m (mm0, *p_dest); \
p_dest += i_stride; \
movq_r2r (mm6, mm7); \
movq_r2r (mm2, mm0); \
} \
} \
}
#define __MotionComponent_x_y_avg(width,height) \
void _M(MotionComponent_x_y_avg_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
movq_m2r( *p_src, mm0 ); \
if( width == 16 ) \
movq_m2r( *(p_src + 8), mm1 ); \
pavg_m2r( *p_dest, mm0 ); \
if( width == 16 ) \
pavg_m2r( *(p_dest + 8), mm1 ); \
movq_r2m( mm0, *p_dest ); \
p_src += i_stride; \
if( width == 16 ) \
movq_r2m( mm1, *(p_dest + 8) ); \
p_dest += i_stride; \
} \
}
#define __MotionComponent_X_y_avg(width,height) \
void _M(MotionComponent_X_y_avg_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
movq_m2r (*p_src, mm0); \
if( width == 16 ) \
movq_m2r (*(p_src + 8), mm1); \
pavg_m2r (*(p_src + 1), mm0); \
if( width == 16 ) \
pavg_m2r (*(p_src + 9), mm1); \
pavg_m2r (*p_dest, mm0); \
if( width == 16 ) \
pavg_m2r (*(p_dest + 8), mm1); \
p_src += i_stride; \
movq_r2m (mm0, *p_dest); \
if( width == 16 ) \
movq_r2m (mm1, *(p_dest + 8)); \
p_dest += i_stride; \
} \
}
#define __MotionComponent_x_Y_avg(width,height) \
void _M(MotionComponent_x_Y_avg_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
pixel_data_t * p_next_src = p_src + i_stride; \
\
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
movq_m2r (*p_src, mm0); \
if( width == 16 ) \
movq_m2r (*(p_src + 8), mm1); \
pavg_m2r (*(p_next_src), mm0); \
if( width == 16 ) \
pavg_m2r (*(p_next_src + 8), mm1); \
pavg_m2r (*p_dest, mm0); \
if( width == 16 ) \
pavg_m2r (*(p_dest + 8), mm1); \
p_src += i_stride; \
p_next_src += i_stride; \
movq_r2m (mm0, *p_dest); \
if( width == 16 ) \
movq_r2m (mm1, *(p_dest + 8)); \
p_dest += i_stride; \
} \
}
#define __MotionComponent_X_Y_avg(width,height) \
void _M(MotionComponent_X_Y_avg_##width##_##height)(pixel_data_t * p_src, \
pixel_data_t * p_dest, \
int i_stride) \
{ \
int i_y; \
\
if( width == 16 ) \
{ \
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
movq_m2r (*p_src, mm0); \
movq_m2r (*(p_src+i_stride+1), mm1); \
movq_r2r (mm0, mm7); \
movq_m2r (*(p_src+1), mm2); \
pxor_r2r (mm1, mm7); \
movq_m2r (*(p_src+i_stride), mm3); \
movq_r2r (mm2, mm6); \
pxor_r2r (mm3, mm6); \
pavg_r2r (mm1, mm0); \
pavg_r2r (mm3, mm2); \
por_r2r (mm6, mm7); \
movq_r2r (mm0, mm6); \
pxor_r2r (mm2, mm6); \
pand_r2r (mm6, mm7); \
pand_m2r (mask_one, mm7); \
pavg_r2r (mm2, mm0); \
psubusb_r2r (mm7, mm0); \
movq_m2r (*p_dest, mm1); \
pavg_r2r (mm1, mm0); \
movq_r2m (mm0, *p_dest); \
\
movq_m2r (*(p_src+8), mm0); \
movq_m2r (*(p_src+i_stride+9), mm1); \
movq_r2r (mm0, mm7); \
movq_m2r (*(p_src+9), mm2); \
pxor_r2r (mm1, mm7); \
movq_m2r (*(p_src+i_stride+8), mm3); \
movq_r2r (mm2, mm6); \
pxor_r2r (mm3, mm6); \
pavg_r2r (mm1, mm0); \
pavg_r2r (mm3, mm2); \
por_r2r (mm6, mm7); \
movq_r2r (mm0, mm6); \
pxor_r2r (mm2, mm6); \
pand_r2r (mm6, mm7); \
pand_m2r (mask_one, mm7); \
pavg_r2r (mm2, mm0); \
psubusb_r2r (mm7, mm0); \
movq_m2r (*(p_dest+8), mm1); \
pavg_r2r (mm1, mm0); \
p_src += i_stride; \
movq_r2m (mm0, *(p_dest+8)); \
p_dest += i_stride; \
} \
} \
else \
{ \
for( i_y = 0; i_y < height; i_y ++ ) \
{ \
movq_m2r (*p_src, mm0); \
movq_m2r (*(p_src+i_stride+1), mm1); \
movq_r2r (mm0, mm7); \
movq_m2r (*(p_src+1), mm2); \
pxor_r2r (mm1, mm7); \
movq_m2r (*(p_src+i_stride), mm3); \
movq_r2r (mm2, mm6); \
pxor_r2r (mm3, mm6); \
pavg_r2r (mm1, mm0); \
pavg_r2r (mm3, mm2); \
por_r2r (mm6, mm7); \
movq_r2r (mm0, mm6); \
pxor_r2r (mm2, mm6); \
pand_r2r (mm6, mm7); \
pand_m2r (mask_one, mm7); \
pavg_r2r (mm2, mm0); \
psubusb_r2r (mm7, mm0); \
movq_m2r (*p_dest, mm1); \
pavg_r2r (mm1, mm0); \
p_src += i_stride; \
movq_r2m (mm0, *p_dest); \
p_dest += i_stride; \
} \
} \
}
#define __MotionComponents(width,height) \
__MotionComponent_x_y_copy(width,height) \
__MotionComponent_X_y_copy(width,height) \
__MotionComponent_x_Y_copy(width,height) \
__MotionComponent_X_Y_copy(width,height) \
__MotionComponent_x_y_avg(width,height) \
__MotionComponent_X_y_avg(width,height) \
__MotionComponent_x_Y_avg(width,height) \
__MotionComponent_X_Y_avg(width,height)
__MotionComponents (16,16) /* 444, 422, 420 */
__MotionComponents (16,8) /* 444, 422, 420 */
__MotionComponents (8,8) /* 422, 420 */
__MotionComponents (8,4) /* 420 */
#if 0
__MotionComponents (8,16) /* 422 */
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment