our optimized IDCT, and MMX IDCT.
. cosmetic changes for modules (pf_* instead of p_*)
. fixes to the BeOS and dummy modules
WARNING: a new directory has been added, which means you have to
use `cvs update -dP' to update ; files have been removed , which means
you either have to run `make distclean' or remove the .deps directory,
and the configure script has changed, which means you have to run it
again. Don't complain before having checked this :)
Note about the IDCT modules: there is no way to choose the one we
use, but you may remove the module in lib/ to prevent it from being
loaded. The preference order is : MMX, Optimized, Classic.
VIDEO_DECODER = src/video_decoder/video_decoder.o \
src/video_decoder/vdec_motion.o \
- src/video_decoder/vdec_idct.o \
$(vdec_motion_inner)
MISC = src/misc/mtime.o \
#
ifneq (,$(findstring 86,$(ARCH)))
ifneq (,$(findstring mmx,$(ARCH)))
-ASM_OBJ = src/video_decoder/vdec_idctmmx.o \
- src/video_output/video_yuv_mmx.o
+ASM_OBJ = src/video_output/video_yuv_mmx.o
+PLUGIN_IDCTMMX_ASM = plugins/idct/idctmmx_asm.o
endif
endif
plugins/yuvmmx/video_yuv24.o \
plugins/yuvmmx/video_yuv32.o
+PLUGIN_IDCT = plugins/idct/idct.o \
+ plugins/idct/idct_common.o
+
+PLUGIN_IDCTCLASSIC = plugins/idct/idctclassic.o \
+ plugins/idct/idct_common.o
+
+PLUGIN_IDCTMMX = plugins/idct/idctmmx.o \
+ plugins/idct/idct_common.o
+
PLUGIN_ALSA = plugins/alsa/alsa.o \
plugins/alsa/aout_alsa.o
$(PLUGIN_X11) \
$(PLUGIN_YUV) \
$(PLUGIN_YUVMMX) \
+ $(PLUGIN_IDCT) \
+ $(PLUGIN_IDCTMMX) \
$(PLUGIN_SDL) \
$(PLUGIN_ALSA) \
$(PLUGIN_NULL)
+STD_PLUGIN_ASM =$(PLUGIN_IDCTMMX_ASM)
+
+STD_PLUGIN_COMMON = plugins/idct/idct_common.o
+# filter out duplicates from the plugin object lists
+STD_PLUGIN_OBJ := $(filter-out $(STD_PLUGIN_COMMON), $(STD_PLUGIN_OBJ)) \
+ $(STD_PLUGIN_COMMON)
+
#
# Other lists of files
#
-objects := $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ) $(STD_PLUGIN_OBJ)
+objects := $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ) $(STD_PLUGIN_OBJ) $(STD_PLUGIN_ASM)
dependancies := $(objects:%.o=.dep/%.d)
# All symbols must be exported
$(STD_PLUGIN_OBJ): %.o: %.c
$(CC) $(CFLAGS) $(PCFLAGS) -c -o $@ $<
+$(STD_PLUGIN_ASM): %.o: Makefile.dep
+$(STD_PLUGIN_ASM): %.o: %.S
+ $(CC) $(CFLAGS) $(PCFLAGS) -c -o $@ $<
+
$(PLUGIN_GNOME): %.o: Makefile.dep
$(PLUGIN_GNOME): %.o: %.c
$(CC) $(CFLAGS) $(PCFLAGS) `gnome-config --cflags gnomeui` -c -o $@ $<
lib/sdl.so: $(PLUGIN_SDL)
$(CC) $(PCFLAGS) -shared -o $@ $^ $(LIB_SDL)
-lib/yuv.so: $(PLUGIN_YUV)
ifeq ($(SYS),beos)
+lib/idct.so: $(PLUGIN_IDCT)
+ $(CC) -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
+
+lib/yuv.so: $(PLUGIN_YUV)
$(CC) -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
-else
- $(CC) $(PCFLAGS) -shared -o $@ $^
-endif
lib/yuvmmx.so: $(PLUGIN_YUVMMX)
-ifeq ($(SYS),beos)
+ $(CC) -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
+
+lib/idctclassic.so: $(PLUGIN_IDCTCLASSIC)
+ $(CC) -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
+
+lib/idctmmx.so: $(PLUGIN_IDCTMMX) $(PLUGIN_IDCTMMX_ASM)
$(CC) -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
else
+lib/yuv.so: $(PLUGIN_YUV)
+ $(CC) $(PCFLAGS) -shared -o $@ $^
+
+lib/yuvmmx.so: $(PLUGIN_YUVMMX)
+ $(CC) $(PCFLAGS) -shared -o $@ $^
+
+lib/idct.so: $(PLUGIN_IDCT)
+ $(CC) $(PCFLAGS) -shared -o $@ $^
+
+lib/idctclassic.so: $(PLUGIN_IDCTCLASSIC)
+ $(CC) $(PCFLAGS) -shared -o $@ $^
+
+lib/idctmmx.so: $(PLUGIN_IDCTMMX) $(PLUGIN_IDCTMMX_ASM)
$(CC) $(PCFLAGS) -shared -o $@ $^
endif
fi
-PLUGINS=${PLUGINS}"yuv ";
+PLUGINS=${PLUGINS}"yuv idct idctclassic ";
ARCH=${host_cpu}
# Check whether --enable-ppro or --disable-ppro was given.
# Check whether --enable-mmx or --disable-mmx was given.
if test "${enable_mmx+set}" = set; then
enableval="$enable_mmx"
- if test x$enableval = xyes; then ARCH=${ARCH}" mmx"; PLUGINS=${PLUGINS}"yuvmmx "; fi
+ if test x$enableval = xyes; then ARCH=${ARCH}" mmx"; PLUGINS=${PLUGINS}"yuvmmx idctmmx "; fi
else
- if test x${host_cpu} = xi686 -o x${host_cpu} = xi586; then ARCH=${ARCH}" mmx"; PLUGINS=${PLUGINS}"yuvmmx "; fi
+ if test x${host_cpu} = xi686 -o x${host_cpu} = xi586; then ARCH=${ARCH}" mmx"; PLUGINS=${PLUGINS}"yuvmmx idctmmx "; fi
fi
# Check whether --enable-debug or --disable-debug was given.
AC_HEADER_TIME
dnl default plugins
-PLUGINS=${PLUGINS}"yuv ";
+PLUGINS=${PLUGINS}"yuv idct idctclassic ";
ARCH=${host_cpu}
AC_ARG_ENABLE(ppro,
[ if test x${host_cpu} = xi686; then ARCH=${ARCH}" ppro"; fi ])
AC_ARG_ENABLE(mmx,
[ --disable-mmx Disable MMX optimizations (default enabled for x86)],
-[ if test x$enableval = xyes; then ARCH=${ARCH}" mmx"; PLUGINS=${PLUGINS}"yuvmmx "; fi ],
-[ if test x${host_cpu} = xi686 -o x${host_cpu} = xi586; then ARCH=${ARCH}" mmx"; PLUGINS=${PLUGINS}"yuvmmx "; fi ])
+[ if test x$enableval = xyes; then ARCH=${ARCH}" mmx"; PLUGINS=${PLUGINS}"yuvmmx idctmmx "; fi ],
+[ if test x${host_cpu} = xi686 -o x${host_cpu} = xi586; then ARCH=${ARCH}" mmx"; PLUGINS=${PLUGINS}"yuvmmx idctmmx "; fi ])
AC_ARG_ENABLE(debug,
[ --enable-debug Enable debug mode (default disabled)],
[ if test x$enableval = xyes; then DEBUG=1; fi ])
/* Plugin used and shortcuts to access its capabilities */
struct module_s * p_module;
- aout_open_t * p_open;
- aout_setformat_t * p_setformat;
- aout_getbufinfo_t * p_getbufinfo;
- aout_play_t * p_play;
- aout_close_t * p_close;
+ aout_open_t * pf_open;
+ aout_setformat_t * pf_setformat;
+ aout_getbufinfo_t * pf_getbufinfo;
+ aout_play_t * pf_play;
+ aout_close_t * pf_close;
void * buffer;
/* The s32 buffer is used to mix all the audio fifos together before
* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: common.h,v 1.23 2001/01/11 15:35:35 sam Exp $
+ * $Id: common.h,v 1.24 2001/01/13 12:57:19 sam Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
/* Counter for statistics and profiling */
typedef unsigned long count_t;
+/* DCT elements types */
+#ifndef VDEC_DFT
+typedef short dctelem_t;
+#else
+typedef int dctelem_t;
+#endif
+
/*****************************************************************************
* Classes declaration
*****************************************************************************/
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-dec.h,v 1.13 2001/01/12 17:33:18 massiot Exp $
+ * $Id: input_ext-dec.h,v 1.14 2001/01/13 12:57:19 sam Exp $
*
* Authors:
*
/* Pointers to packets (packets are then linked by the p_prev and
p_next fields of the data_packet_t struct) */
- data_packet_t * p_first; /* The first packet containing this
+ data_packet_t * p_first; /* The first packet contained by this
* PES (used by decoders). */
} pes_packet_t;
* Module capabilities.
*****************************************************************************/
-#define MODULE_CAPABILITY_NULL 0 /* The Module can't do anything */
-#define MODULE_CAPABILITY_INTF 1<<0 /* Interface */
-#define MODULE_CAPABILITY_INPUT 1<<1 /* Input */
-#define MODULE_CAPABILITY_DECAPS 1<<2 /* Decaps */
-#define MODULE_CAPABILITY_ADEC 1<<3 /* Audio decoder */
-#define MODULE_CAPABILITY_VDEC 1<<4 /* Video decoder */
-#define MODULE_CAPABILITY_AOUT 1<<5 /* Audio output */
-#define MODULE_CAPABILITY_VOUT 1<<6 /* Video output */
-#define MODULE_CAPABILITY_YUV 1<<7 /* YUV colorspace conversion */
-#define MODULE_CAPABILITY_AFX 1<<8 /* Audio effects */
-#define MODULE_CAPABILITY_VFX 1<<9 /* Video effects */
+#define MODULE_CAPABILITY_NULL 0 /* The Module can't do anything */
+#define MODULE_CAPABILITY_INTF 1 << 0 /* Interface */
+#define MODULE_CAPABILITY_INPUT 1 << 1 /* Input */
+#define MODULE_CAPABILITY_DECAPS 1 << 2 /* Decaps */
+#define MODULE_CAPABILITY_ADEC 1 << 3 /* Audio decoder */
+#define MODULE_CAPABILITY_VDEC 1 << 4 /* Video decoder */
+#define MODULE_CAPABILITY_IDCT 1 << 5 /* IDCT transformation */
+#define MODULE_CAPABILITY_AOUT 1 << 6 /* Audio output */
+#define MODULE_CAPABILITY_VOUT 1 << 7 /* Video output */
+#define MODULE_CAPABILITY_YUV 1 << 8 /* YUV colorspace conversion */
+#define MODULE_CAPABILITY_AFX 1 << 9 /* Audio effects */
+#define MODULE_CAPABILITY_VFX 1 << 10 /* Video effects */
/* FIXME: not yet used */
typedef struct probedata_s
/* FIXME: find a nicer way to do this. */
typedef struct function_list_s
{
- int ( * p_probe ) ( probedata_t * p_data );
+ int ( * pf_probe ) ( probedata_t * p_data );
union
{
struct
{
- int ( * p_open ) ( struct aout_thread_s * p_aout );
- int ( * p_setformat ) ( struct aout_thread_s * p_aout );
- long ( * p_getbufinfo ) ( struct aout_thread_s * p_aout,
- long l_buffer_info );
- void ( * p_play ) ( struct aout_thread_s * p_aout,
- byte_t *buffer, int i_size );
- void ( * p_close ) ( struct aout_thread_s * p_aout );
- } aout;
+ int ( * pf_open ) ( struct aout_thread_s * p_aout );
+ int ( * pf_setformat ) ( struct aout_thread_s * p_aout );
+ long ( * pf_getbufinfo ) ( struct aout_thread_s * p_aout,
+ long l_buffer_info );
+ void ( * pf_play ) ( struct aout_thread_s * p_aout,
+ byte_t *buffer, int i_size );
+ void ( * pf_close ) ( struct aout_thread_s * p_aout );
+ } aout;
+
+ struct
+ {
+ void ( * pf_init ) ( struct vdec_thread_s * p_vdec );
+ void ( * pf_sparse_idct ) ( struct vdec_thread_s * p_vdec,
+ dctelem_t * p_block,
+ int i_sparse_pos );
+ void ( * pf_idct ) ( struct vdec_thread_s * p_vdec,
+ dctelem_t * p_block,
+ int i_idontcare );
+ } idct;
} functions;
typedef struct module_functions_s
{
- /* The order here has to be the same as above for the #defines */
+ /* XXX: The order here has to be the same as above for the #defines */
function_list_t intf;
function_list_t input;
function_list_t decaps;
function_list_t adec;
function_list_t vdec;
+ function_list_t idct;
function_list_t aout;
function_list_t vout;
function_list_t yuv;
* video_decoder.h : video decoder thread
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: video_decoder.h,v 1.1 2000/12/21 17:19:52 massiot Exp $
+ * $Id: video_decoder.h,v 1.22 2001/01/13 12:57:19 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
*****************************************************************************/
void aout_getfunctions( function_list_t * p_function_list )
{
- p_function_list->p_probe = aout_Probe;
- p_function_list->functions.aout.p_open = aout_Open;
- p_function_list->functions.aout.p_setformat = aout_SetFormat;
- p_function_list->functions.aout.p_getbufinfo = aout_GetBufInfo;
- p_function_list->functions.aout.p_play = aout_Play;
- p_function_list->functions.aout.p_close = aout_Close;
+ p_function_list->pf_probe = aout_Probe;
+ p_function_list->functions.aout.pf_open = aout_Open;
+ p_function_list->functions.aout.pf_setformat = aout_SetFormat;
+ p_function_list->functions.aout.pf_getbufinfo = aout_GetBufInfo;
+ p_function_list->functions.aout.pf_play = aout_Play;
+ p_function_list->functions.aout.pf_close = aout_Close;
}
*****************************************************************************
* This function opens an alsa device, through the alsa API
*****************************************************************************/
-
static int aout_Open( aout_thread_t *p_aout )
{
* This function prepares the device, sets the rate, format, the mode
* ("play as soon as you have data"), and buffer information.
*****************************************************************************/
-
-int aout_SetFormat( aout_thread_t *p_aout )
+static int aout_SetFormat( aout_thread_t *p_aout )
{
int i_set_param_returns;
* of data to play, it switches to the "underrun" status. It has to
* be flushed and re-prepared
*****************************************************************************/
-long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
+static long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
{
snd_pcm_channel_status_t alsa_channel_status;
int i_alsa_get_status_returns;
*****************************************************************************
* Plays a sample using the snd_pcm_write function from the alsa API
*****************************************************************************/
-void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
+static void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
{
int i_write_returns;
/*****************************************************************************
* aout_Close : close the Alsa device
*****************************************************************************/
-void aout_Close( aout_thread_t *p_aout )
+static void aout_Close( aout_thread_t *p_aout )
{
int i_close_returns;
intf_DbgMsg( "Alsa plugin : Alsa device closed");
}
+
* aout_beos.cpp: BeOS audio output
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: aout_beos.cpp,v 1.9 2001/01/12 13:15:42 sam Exp $
+ * $Id: aout_beos.cpp,v 1.10 2001/01/13 12:57:19 sam Exp $
*
* Authors:
* Samuel Hocevar <sam@via.ecp.fr>
*****************************************************************************/
void aout_getfunctions( function_list_t * p_function_list )
{
- p_function_list->p_probe = aout_Probe;
- p_function_list->functions.aout.p_open = aout_Open;
- p_function_list->functions.aout.p_setformat = aout_SetFormat;
- p_function_list->functions.aout.p_getbufinfo = aout_GetBufInfo;
- p_function_list->functions.aout.p_play = aout_Play;
- p_function_list->functions.aout.p_close = aout_Close;
+ p_function_list->pf_probe = aout_Probe;
+ p_function_list->functions.aout.pf_open = aout_Open;
+ p_function_list->functions.aout.pf_setformat = aout_SetFormat;
+ p_function_list->functions.aout.pf_getbufinfo = aout_GetBufInfo;
+ p_function_list->functions.aout.pf_play = aout_Play;
+ p_function_list->functions.aout.pf_close = aout_Close;
}
/*****************************************************************************
* aout_Probe: probe the audio device and return a score
*****************************************************************************/
-int aout_Probe( aout_thread_t *p_aout )
+static int aout_Probe( probedata_t *p_data )
{
/* We don't test anything since I don't know what to test. However
* if the module could be loaded it is quite likely to work. */
/*****************************************************************************
* aout_Open: opens a BPushGameSound
*****************************************************************************/
-int aout_Open( aout_thread_t *p_aout )
+static int aout_Open( aout_thread_t *p_aout )
{
/* Allocate structure */
p_aout->p_sys = (aout_sys_t*) malloc( sizeof( aout_sys_t ) );
/*****************************************************************************
* aout_SetFormat: sets the dsp output format
*****************************************************************************/
-int aout_SetFormat( aout_thread_t *p_aout )
+static int aout_SetFormat( aout_thread_t *p_aout )
{
return( 0 );
}
/*****************************************************************************
* aout_GetBufInfo: buffer status query
*****************************************************************************/
-long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
+static long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
{
/* Each value is 4 bytes long (stereo signed 16 bits) */
long i_hard_pos = 4 * p_aout->p_sys->p_sound->CurrentPosition();
*****************************************************************************
* This function writes a buffer of i_length bytes in the dsp
*****************************************************************************/
-void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
+static void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
{
long i_newbuf_pos;
/*****************************************************************************
* aout_Close: closes the dsp audio device
*****************************************************************************/
-void aout_Close( aout_thread_t *p_aout )
+static void aout_Close( aout_thread_t *p_aout )
{
p_aout->p_sys->p_sound->UnlockCyclic();
p_aout->p_sys->p_sound->StopPlaying( );
*****************************************************************************/
void aout_getfunctions( function_list_t * p_function_list )
{
- p_function_list->p_probe = aout_Probe;
- p_function_list->functions.aout.p_open = aout_Open;
- p_function_list->functions.aout.p_setformat = aout_SetFormat;
- p_function_list->functions.aout.p_getbufinfo = aout_GetBufInfo;
- p_function_list->functions.aout.p_play = aout_Play;
- p_function_list->functions.aout.p_close = aout_Close;
+ p_function_list->pf_probe = aout_Probe;
+ p_function_list->functions.aout.pf_open = aout_Open;
+ p_function_list->functions.aout.pf_setformat = aout_SetFormat;
+ p_function_list->functions.aout.pf_getbufinfo = aout_GetBufInfo;
+ p_function_list->functions.aout.pf_play = aout_Play;
+ p_function_list->functions.aout.pf_close = aout_Close;
}
/*****************************************************************************
#include "main.h"
+#include "modules.h"
+
/*****************************************************************************
* vout_dummy_t: dummy video output method descriptor
*****************************************************************************
typedef struct aout_sys_s
{
-
} aout_sys_t;
/*****************************************************************************
- * aout_DummyOpen: opens a dummy audio device
+ * Local prototypes.
+ *****************************************************************************/
+static int aout_Probe ( probedata_t *p_data );
+static int aout_Open ( aout_thread_t *p_aout );
+static int aout_SetFormat ( aout_thread_t *p_aout );
+static long aout_GetBufInfo ( aout_thread_t *p_aout, long l_buffer_info );
+static void aout_Play ( aout_thread_t *p_aout,
+ byte_t *buffer, int i_size );
+static void aout_Close ( aout_thread_t *p_aout );
+
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+void aout_getfunctions( function_list_t * p_function_list )
+{
+ p_function_list->pf_probe = aout_Probe;
+ p_function_list->functions.aout.pf_open = aout_Open;
+ p_function_list->functions.aout.pf_setformat = aout_SetFormat;
+ p_function_list->functions.aout.pf_getbufinfo = aout_GetBufInfo;
+ p_function_list->functions.aout.pf_play = aout_Play;
+ p_function_list->functions.aout.pf_close = aout_Close;
+}
+
+/*****************************************************************************
+ * aout_Probe: probe the audio device and return a score
+ *****************************************************************************/
+static int aout_Probe( probedata_t *p_data )
+{
+ /* The dummy plugin always works but give it the lower possible score */
+ return( 1 );
+}
+
+/*****************************************************************************
+ * aout_Open: opens a dummy audio device
*****************************************************************************/
-int aout_DummyOpen( aout_thread_t *p_aout )
+static int aout_Open( aout_thread_t *p_aout )
{
/* Initialize some variables */
p_aout->i_format = AOUT_FORMAT_DEFAULT;
}
/*****************************************************************************
- * aout_DummySetFormat: pretends to set the dsp output format
+ * aout_SetFormat: pretends to set the dsp output format
*****************************************************************************/
-int aout_DummySetFormat( aout_thread_t *p_aout )
+static int aout_SetFormat( aout_thread_t *p_aout )
{
return( 0 );
}
/*****************************************************************************
- * aout_DummyGetBufInfo: returns available bytes in buffer
+ * aout_GetBufInfo: returns available bytes in buffer
*****************************************************************************/
-long aout_DummyGetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
+static long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
{
return( sizeof(s16) * l_buffer_limit + 1 ); /* value big enough to sleep */
}
/*****************************************************************************
- * aout_DummyPlay: pretends to play a sound
+ * aout_Play: pretends to play a sound
*****************************************************************************/
-void aout_DummyPlay( aout_thread_t *p_aout, byte_t *buffer, int i_size )
+static void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
{
;
}
/*****************************************************************************
- * aout_DummyClose: closes the dummy audio device
+ * aout_Close: closes the dummy audio device
*****************************************************************************/
-void aout_DummyClose( aout_thread_t *p_aout )
+static void aout_Close( aout_thread_t *p_aout )
{
;
}
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
+#define MODULE_NAME dummy
+
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "video.h"
#include "video_output.h"
+#include "modules.h"
+#include "modules_inner.h"
+
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START
+ADD_WINDOW( "Configuration for dummy module" )
+ ADD_COMMENT( "Ha, ha -- nothing to configure yet" )
+MODULE_CONFIG_END
+
+/*****************************************************************************
+ * Capabilities defined in the other files.
+ *****************************************************************************/
+extern void aout_getfunctions( function_list_t * p_function_list );
+
+/*****************************************************************************
+ * InitModule: get the module structure and configuration.
+ *****************************************************************************
+ * We have to fill psz_name, psz_longname and psz_version. These variables
+ * will be strdup()ed later by the main application because the module can
+ * be unloaded later to save memory, and we want to be able to access this
+ * data even after the module has been unloaded.
+ *****************************************************************************/
+int InitModule( module_t * p_module )
+{
+ p_module->psz_name = MODULE_STRING;
+ p_module->psz_longname = "dummy functions module";
+ p_module->psz_version = VERSION;
+
+ p_module->i_capabilities = MODULE_CAPABILITY_NULL
+ | MODULE_CAPABILITY_AOUT;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * ActivateModule: set the module to an usable state.
+ *****************************************************************************
+ * This function fills the capability functions and the configuration
+ * structure. Once ActivateModule() has been called, the i_usage can
+ * be set to 0 and calls to NeedModule() be made to increment it. To unload
+ * the module, one has to wait until i_usage == 0 and call DeactivateModule().
+ *****************************************************************************/
+int ActivateModule( module_t * p_module )
+{
+ p_module->p_functions = malloc( sizeof( module_functions_t ) );
+ if( p_module->p_functions == NULL )
+ {
+ return( -1 );
+ }
+
+ aout_getfunctions( &p_module->p_functions->aout );
+
+ p_module->p_config = p_config;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * DeactivateModule: make sure the module can be unloaded.
+ *****************************************************************************
+ * This function must only be called when i_usage == 0. If it successfully
+ * returns, i_usage can be set to -1 and the module unloaded. Be careful to
+ * lock usage_lock during the whole process.
+ *****************************************************************************/
+int DeactivateModule( module_t * p_module )
+{
+ free( p_module->p_functions );
+
+ return( 0 );
+}
+
+/* OLD MODULE STRUCTURE -- soon to be removed */
+
/*****************************************************************************
* Exported prototypes
*****************************************************************************/
-static void aout_GetPlugin( p_aout_thread_t p_aout );
static void vout_GetPlugin( p_vout_thread_t p_vout );
static void intf_GetPlugin( p_intf_thread_t p_intf );
-/* Audio output */
-int aout_DummyOpen ( aout_thread_t *p_aout );
-int aout_DummySetFormat ( aout_thread_t *p_aout );
-long aout_DummyGetBufInfo ( aout_thread_t *p_aout, long l_buffer_info );
-void aout_DummyPlay ( aout_thread_t *p_aout, byte_t *buffer,
- int i_size );
-void aout_DummyClose ( aout_thread_t *p_aout );
-
/* Video output */
int vout_DummyCreate ( vout_thread_t *p_vout, char *psz_display,
int i_root_window, void *p_data );
p_info->psz_version = VERSION;
p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
- p_info->aout_GetPlugin = aout_GetPlugin;
+ p_info->aout_GetPlugin = NULL;
p_info->vout_GetPlugin = vout_GetPlugin;
p_info->intf_GetPlugin = intf_GetPlugin;
p_info->yuv_GetPlugin = NULL;
p_info->i_score += 0x200;
}
- /* If this plugin was requested, score it higher */
- if( TestMethod( AOUT_METHOD_VAR, "dummy" ) )
- {
- p_info->i_score += 0x200;
- }
-
-
return( p_info );
}
* Following functions are only called through the p_info structure
*****************************************************************************/
-static void aout_GetPlugin( p_aout_thread_t p_aout )
-{
- p_aout->p_open = aout_DummyOpen;
- p_aout->p_setformat = aout_DummySetFormat;
- p_aout->p_getbufinfo = aout_DummyGetBufInfo;
- p_aout->p_play = aout_DummyPlay;
- p_aout->p_close = aout_DummyClose;
-}
-
static void vout_GetPlugin( p_vout_thread_t p_vout )
{
p_vout->p_sys_create = vout_DummyCreate;
*****************************************************************************/
void aout_getfunctions( function_list_t * p_function_list )
{
- p_function_list->p_probe = aout_Probe;
- p_function_list->functions.aout.p_open = aout_Open;
- p_function_list->functions.aout.p_setformat = aout_SetFormat;
- p_function_list->functions.aout.p_getbufinfo = aout_GetBufInfo;
- p_function_list->functions.aout.p_play = aout_Play;
- p_function_list->functions.aout.p_close = aout_Close;
+ p_function_list->pf_probe = aout_Probe;
+ p_function_list->functions.aout.pf_open = aout_Open;
+ p_function_list->functions.aout.pf_setformat = aout_SetFormat;
+ p_function_list->functions.aout.pf_getbufinfo = aout_GetBufInfo;
+ p_function_list->functions.aout.pf_play = aout_Play;
+ p_function_list->functions.aout.pf_close = aout_Close;
}
/*****************************************************************************
/*****************************************************************************
* aout_GetBufInfo: buffer status query
*****************************************************************************/
-long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
+static long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
{
/* arbitrary value that should be changed */
return( l_buffer_limit );
*****************************************************************************
* This function writes a buffer of i_length bytes in the socket
*****************************************************************************/
-void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
+static void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
{
int amount;
/*****************************************************************************
* aout_Close: close the Esound socket
*****************************************************************************/
-void aout_Close( aout_thread_t *p_aout )
+static void aout_Close( aout_thread_t *p_aout )
{
close( p_aout->i_fd );
}
/*****************************************************************************
- * vdec_idct.c : IDCT functions
+ * idct.c : IDCT module
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: vdec_idct.c,v 1.23 2001/01/05 18:46:44 massiot Exp $
+ * $Id: idct.c,v 1.1 2001/01/13 12:57:20 sam Exp $
*
* Authors: Gaël Hendryckx <jimmy@via.ecp.fr>
*
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
+#define MODULE_NAME idct
+
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
+#include <stdlib.h>
+
#include "config.h"
#include "common.h"
#include "threads.h"
#include "video.h"
#include "video_output.h"
-#include "vdec_idct.h"
#include "video_decoder.h"
-#include "vdec_motion.h"
-
-#include "vpar_blocks.h"
-#include "vpar_headers.h"
-#include "vpar_synchro.h"
-#include "video_parser.h"
-#include "video_fifo.h"
-/*
- * Local prototypes
- */
+#include "modules.h"
+#include "modules_inner.h"
-/* Our current implementation is a fast DCT, we might move to a fast DFT or
- * an MMX DCT in the future. */
+#include "idct.h"
/*****************************************************************************
- * vdec_InitIDCT : initialize datas for vdec_SparceIDCT
- * vdec_SparseIDCT : IDCT function for sparse matrices
+ * Local and extern prototypes.
*****************************************************************************/
+static void idct_getfunctions( function_list_t * p_function_list );
-void vdec_InitIDCT (vdec_thread_t * p_vdec)
-{
- int i;
+static int idct_Probe ( probedata_t *p_data );
+static void vdec_InitIDCT ( vdec_thread_t * p_vdec);
+ void vdec_SparseIDCT ( vdec_thread_t * p_vdec, dctelem_t * p_block,
+ int i_sparse_pos);
+static void vdec_IDCT ( vdec_thread_t * p_vdec, dctelem_t * p_block,
+ int i_idontcare );
- dctelem_t * p_pre = p_vdec->p_pre_idct;
- memset( p_pre, 0, 64*64*sizeof(dctelem_t) );
- for( i=0 ; i < 64 ; i++ )
- {
- p_pre[i*64+i] = 1 << SPARSE_SCALE_FACTOR;
- vdec_IDCT( p_vdec, &p_pre[i*64], 0) ;
- }
- return;
-}
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START
+ADD_WINDOW( "Configuration for IDCT module" )
+ ADD_COMMENT( "Ha, ha -- nothing to configure yet" )
+MODULE_CONFIG_END
-void vdec_SparseIDCT (vdec_thread_t * p_vdec, dctelem_t * p_block,
- int i_sparse_pos)
+/*****************************************************************************
+ * InitModule: get the module structure and configuration.
+ *****************************************************************************
+ * We have to fill psz_name, psz_longname and psz_version. These variables
+ * will be strdup()ed later by the main application because the module can
+ * be unloaded later to save memory, and we want to be able to access this
+ * data even after the module has been unloaded.
+ *****************************************************************************/
+int InitModule( module_t * p_module )
{
- short int val;
- int * dp;
- int v;
- short int * p_dest;
- short int * p_source;
- int coeff, rr;
-
- /* If DC Coefficient. */
- if ( i_sparse_pos == 0 )
- {
- dp=(int *)p_block;
- val=RIGHT_SHIFT((*p_block + 4), 3);
- /* Compute int to assign. This speeds things up a bit */
- v = ((val & 0xffff) | (val << 16));
- dp[0] = v; dp[1] = v; dp[2] = v; dp[3] = v;
- dp[4] = v; dp[5] = v; dp[6] = v; dp[7] = v;
- dp[8] = v; dp[9] = v; dp[10] = v; dp[11] = v;
- dp[12] = v; dp[13] = v; dp[14] = v; dp[15] = v;
- dp[16] = v; dp[17] = v; dp[18] = v; dp[19] = v;
- dp[20] = v; dp[21] = v; dp[22] = v; dp[23] = v;
- dp[24] = v; dp[25] = v; dp[26] = v; dp[27] = v;
- dp[28] = v; dp[29] = v; dp[30] = v; dp[31] = v;
- return;
- }
- /* Some other coefficient. */
- p_dest = (s16*)p_block;
- p_source = (s16*)&p_vdec->p_pre_idct[i_sparse_pos];
- coeff = (int)p_dest[i_sparse_pos];
- for( rr=0 ; rr < 4 ; rr++ )
- {
- p_dest[0] = (p_source[0] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[1] = (p_source[1] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[2] = (p_source[2] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[3] = (p_source[3] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[4] = (p_source[4] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[5] = (p_source[5] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[6] = (p_source[6] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[7] = (p_source[7] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[8] = (p_source[8] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[9] = (p_source[9] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[10] = (p_source[10] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[11] = (p_source[11] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[12] = (p_source[12] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[13] = (p_source[13] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[14] = (p_source[14] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest[15] = (p_source[15] * coeff) >> SPARSE_SCALE_FACTOR;
- p_dest += 16;
- p_source += 16;
- }
- return;
-}
+ p_module->psz_name = MODULE_STRING;
+ p_module->psz_longname = "C IDCT module";
+ p_module->psz_version = VERSION;
+ p_module->i_capabilities = MODULE_CAPABILITY_NULL
+ | MODULE_CAPABILITY_IDCT;
+
+ return( 0 );
+}
/*****************************************************************************
- * vdec_IDCT : IDCT function for normal matrices
+ * ActivateModule: set the module to an usable state.
+ *****************************************************************************
+ * This function fills the capability functions and the configuration
+ * structure. Once ActivateModule() has been called, the i_usage can
+ * be set to 0 and calls to NeedModule() be made to increment it. To unload
+ * the module, one has to wait until i_usage == 0 and call DeactivateModule().
*****************************************************************************/
-
-#ifndef HAVE_MMX
-void vdec_IDCT( vdec_thread_t * p_vdec, dctelem_t * p_block, int i_idontcare )
+int ActivateModule( module_t * p_module )
{
-#if 0
- /* dct classique: pour tester la meilleure entre la classique et la */
- /* no classique */
- s32 tmp0, tmp1, tmp2, tmp3;
- s32 tmp10, tmp11, tmp12, tmp13;
- s32 z1, z2, z3, z4, z5;
- dctelem_t * dataptr;
- int rowctr;
- SHIFT_TEMPS
-
- /* Pass 1: process rows. */
- /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
- /* furthermore, we scale the results by 2**PASS1_BITS. */
-
- dataptr = p_block;
- for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--)
+ p_module->p_functions = malloc( sizeof( module_functions_t ) );
+ if( p_module->p_functions == NULL )
{
- /* Due to quantization, we will usually find that many of the input
- * coefficients are zero, especially the AC terms. We can exploit this
- * by short-circuiting the IDCT calculation for any row in which all
- * the AC terms are zero. In that case each output is equal to the
- * DC coefficient (with scale factor as needed).
- * With typical images and quantization tables, half or more of the
- * row DCT calculations can be simplified this way.
- */
-
- if ((dataptr[1] | dataptr[2] | dataptr[3] | dataptr[4] |
- dataptr[5] | dataptr[6] | dataptr[7]) == 0)
- {
- /* AC terms all zero */
- dctelem_t dcval = (dctelem_t) (dataptr[0] << PASS1_BITS);
-
- dataptr[0] = dcval;
- dataptr[1] = dcval;
- dataptr[2] = dcval;
- dataptr[3] = dcval;
- dataptr[4] = dcval;
- dataptr[5] = dcval;
- dataptr[6] = dcval;
- dataptr[7] = dcval;
-
- dataptr += DCTSIZE; /* advance pointer to next row */
- continue;
- }
-
- /* Even part: reverse the even part of the forward DCT. */
- /* The rotator is sqrt(2)*c(-6). */
-
- z2 = (s32) dataptr[2];
- z3 = (s32) dataptr[6];
-
- z1 = MULTIPLY(z2 + z3, FIX(0.541196100));
- tmp2 = z1 + MULTIPLY(z3, - FIX(1.847759065));
- tmp3 = z1 + MULTIPLY(z2, FIX(0.765366865));
-
- tmp0 = ((s32) dataptr[0] + (s32) dataptr[4]) << CONST_BITS;
- tmp1 = ((s32) dataptr[0] - (s32) dataptr[4]) << CONST_BITS;
-
- tmp10 = tmp0 + tmp3;
- tmp13 = tmp0 - tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp1 - tmp2;
-
- /* Odd part per figure 8; the matrix is unitary and hence its
- * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
- */
-
- tmp0 = (s32) dataptr[7];
- tmp1 = (s32) dataptr[5];
- tmp2 = (s32) dataptr[3];
- tmp3 = (s32) dataptr[1];
-
- z1 = tmp0 + tmp3;
- z2 = tmp1 + tmp2;
- z3 = tmp0 + tmp2;
- z4 = tmp1 + tmp3;
- z5 = MULTIPLY(z3 + z4, FIX(1.175875602)); /* sqrt(2) * c3 */
-
- tmp0 = MULTIPLY(tmp0, FIX(0.298631336)); /* sqrt(2) * (-c1+c3+c5-c7) */
- tmp1 = MULTIPLY(tmp1, FIX(2.053119869)); /* sqrt(2) * ( c1+c3-c5+c7) */
- tmp2 = MULTIPLY(tmp2, FIX(3.072711026)); /* sqrt(2) * ( c1+c3+c5-c7) */
- tmp3 = MULTIPLY(tmp3, FIX(1.501321110)); /* sqrt(2) * ( c1+c3-c5-c7) */
- z1 = MULTIPLY(z1, - FIX(0.899976223)); /* sqrt(2) * (c7-c3) */
- z2 = MULTIPLY(z2, - FIX(2.562915447)); /* sqrt(2) * (-c1-c3) */
- z3 = MULTIPLY(z3, - FIX(1.961570560)); /* sqrt(2) * (-c3-c5) */
- z4 = MULTIPLY(z4, - FIX(0.390180644)); /* sqrt(2) * (c5-c3) */
-
- z3 += z5;
- z4 += z5;
-
- tmp0 += z1 + z3;
- tmp1 += z2 + z4;
- tmp2 += z2 + z3;
- tmp3 += z1 + z4;
-
- /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
-
- dataptr[0] = (dctelem_t) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
- dataptr[7] = (dctelem_t) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
- dataptr[1] = (dctelem_t) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
- dataptr[6] = (dctelem_t) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
- dataptr[2] = (dctelem_t) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
- dataptr[5] = (dctelem_t) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
- dataptr[3] = (dctelem_t) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
- dataptr[4] = (dctelem_t) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
-
- dataptr += DCTSIZE; /* advance pointer to next row */
+ return( -1 );
}
- /* Pass 2: process columns. */
- /* Note that we must descale the results by a factor of 8 == 2**3, */
- /* and also undo the PASS1_BITS scaling. */
-
- dataptr = p_block;
- for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--)
- {
- /* Columns of zeroes can be exploited in the same way as we did with rows.
- * However, the row calculation has created many nonzero AC terms, so the
- * simplification applies less often (typically 5% to 10% of the time).
- * On machines with very fast multiplication, it's possible that the
- * test takes more time than it's worth. In that case this section
- * may be commented out.
- */
+ idct_getfunctions( &p_module->p_functions->idct );
-#ifndef NO_ZERO_COLUMN_TEST /*ajoute un test mais evite des calculs */
- if ((dataptr[DCTSIZE*1] | dataptr[DCTSIZE*2] | dataptr[DCTSIZE*3] |
- dataptr[DCTSIZE*4] | dataptr[DCTSIZE*5] | dataptr[DCTSIZE*6] |
- dataptr[DCTSIZE*7]) == 0)
- {
- /* AC terms all zero */
- dctelem_t dcval = (dctelem_t) DESCALE((s32) dataptr[0], PASS1_BITS+3);
-
- dataptr[DCTSIZE*0] = dcval;
- dataptr[DCTSIZE*1] = dcval;
- dataptr[DCTSIZE*2] = dcval;
- dataptr[DCTSIZE*3] = dcval;
- dataptr[DCTSIZE*4] = dcval;
- dataptr[DCTSIZE*5] = dcval;
- dataptr[DCTSIZE*6] = dcval;
- dataptr[DCTSIZE*7] = dcval;
-
- dataptr++; /* advance pointer to next column */
- continue;
- }
-#endif
+ p_module->p_config = p_config;
- /* Even part: reverse the even part of the forward DCT. */
- /* The rotator is sqrt(2)*c(-6). */
+ return( 0 );
+}
- z2 = (s32) dataptr[DCTSIZE*2];
- z3 = (s32) dataptr[DCTSIZE*6];
+/*****************************************************************************
+ * DeactivateModule: make sure the module can be unloaded.
+ *****************************************************************************
+ * This function must only be called when i_usage == 0. If it successfully
+ * returns, i_usage can be set to -1 and the module unloaded. Be careful to
+ * lock usage_lock during the whole process.
+ *****************************************************************************/
+int DeactivateModule( module_t * p_module )
+{
+ free( p_module->p_functions );
- z1 = MULTIPLY(z2 + z3, FIX(0.541196100));
- tmp2 = z1 + MULTIPLY(z3, - FIX(1.847759065));
- tmp3 = z1 + MULTIPLY(z2, FIX(0.765366865));
+ return( 0 );
+}
- tmp0 = ((s32) dataptr[DCTSIZE*0] + (s32) dataptr[DCTSIZE*4]) << CONST_BITS;
- tmp1 = ((s32) dataptr[DCTSIZE*0] - (s32) dataptr[DCTSIZE*4]) << CONST_BITS;
+/* Following functions are local */
- tmp10 = tmp0 + tmp3;
- tmp13 = tmp0 - tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp1 - tmp2;
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+static void idct_getfunctions( function_list_t * p_function_list )
+{
+ p_function_list->pf_probe = idct_Probe;
+ p_function_list->functions.idct.pf_init = vdec_InitIDCT;
+ p_function_list->functions.idct.pf_sparse_idct = vdec_SparseIDCT;
+ p_function_list->functions.idct.pf_idct = vdec_IDCT;
+}
- /* Odd part per figure 8; the matrix is unitary and hence its
- * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
- */
+/*****************************************************************************
+ * idct_Probe: returns a preference score
+ *****************************************************************************/
+static int idct_Probe( probedata_t *p_data )
+{
+ /* This plugin always works */
+ return( 100 );
+}
- tmp0 = (s32) dataptr[DCTSIZE*7];
- tmp1 = (s32) dataptr[DCTSIZE*5];
- tmp2 = (s32) dataptr[DCTSIZE*3];
- tmp3 = (s32) dataptr[DCTSIZE*1];
-
- z1 = tmp0 + tmp3;
- z2 = tmp1 + tmp2;
- z3 = tmp0 + tmp2;
- z4 = tmp1 + tmp3;
- z5 = MULTIPLY(z3 + z4, FIX(1.175875602)); /* sqrt(2) * c3 */
-
- tmp0 = MULTIPLY(tmp0, FIX(0.298631336)); /* sqrt(2) * (-c1+c3+c5-c7) */
- tmp1 = MULTIPLY(tmp1, FIX(2.053119869)); /* sqrt(2) * ( c1+c3-c5+c7) */
- tmp2 = MULTIPLY(tmp2, FIX(3.072711026)); /* sqrt(2) * ( c1+c3+c5-c7) */
- tmp3 = MULTIPLY(tmp3, FIX(1.501321110)); /* sqrt(2) * ( c1+c3-c5-c7) */
- z1 = MULTIPLY(z1, - FIX(0.899976223)); /* sqrt(2) * (c7-c3) */
- z2 = MULTIPLY(z2, - FIX(2.562915447)); /* sqrt(2) * (-c1-c3) */
- z3 = MULTIPLY(z3, - FIX(1.961570560)); /* sqrt(2) * (-c3-c5) */
- z4 = MULTIPLY(z4, - FIX(0.390180644)); /* sqrt(2) * (c5-c3) */
-
- z3 += z5;
- z4 += z5;
-
- tmp0 += z1 + z3;
- tmp1 += z2 + z4;
- tmp2 += z2 + z3;
- tmp3 += z1 + z4;
+/*****************************************************************************
+ * vdec_InitIDCT : initialize datas for vdec_SparseIDCT
+ *****************************************************************************/
+static void vdec_InitIDCT (vdec_thread_t * p_vdec)
+{
+ int i;
- /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
+ dctelem_t * p_pre = p_vdec->p_pre_idct;
+ memset( p_pre, 0, 64*64*sizeof(dctelem_t) );
- dataptr[DCTSIZE*0] = (dctelem_t) DESCALE(tmp10 + tmp3,
- CONST_BITS+PASS1_BITS+3);
- dataptr[DCTSIZE*7] = (dctelem_t) DESCALE(tmp10 - tmp3,
- CONST_BITS+PASS1_BITS+3);
- dataptr[DCTSIZE*1] = (dctelem_t) DESCALE(tmp11 + tmp2,
- CONST_BITS+PASS1_BITS+3);
- dataptr[DCTSIZE*6] = (dctelem_t) DESCALE(tmp11 - tmp2,
- CONST_BITS+PASS1_BITS+3);
- dataptr[DCTSIZE*2] = (dctelem_t) DESCALE(tmp12 + tmp1,
- CONST_BITS+PASS1_BITS+3);
- dataptr[DCTSIZE*5] = (dctelem_t) DESCALE(tmp12 - tmp1,
- CONST_BITS+PASS1_BITS+3);
- dataptr[DCTSIZE*3] = (dctelem_t) DESCALE(tmp13 + tmp0,
- CONST_BITS+PASS1_BITS+3);
- dataptr[DCTSIZE*4] = (dctelem_t) DESCALE(tmp13 - tmp0,
- CONST_BITS+PASS1_BITS+3);
-
- dataptr++; /* advance pointer to next column */
+ for( i=0 ; i < 64 ; i++ )
+ {
+ p_pre[i*64+i] = 1 << SPARSE_SCALE_FACTOR;
+ vdec_IDCT( p_vdec, &p_pre[i*64], 0) ;
}
-#endif
-
-#if 1 /*dct avec non classique*/
+ return;
+}
+/*****************************************************************************
+ * vdec_IDCT : IDCT function for normal matrices
+ *****************************************************************************/
+static void vdec_IDCT( vdec_thread_t * p_vdec, dctelem_t * p_block,
+ int i_idontcare )
+{
s32 tmp0, tmp1, tmp2, tmp3;
s32 tmp10, tmp11, tmp12, tmp13;
s32 z1, z2, z3, z4, z5;
dataptr++; /* advance pointer to next column */
}
-#endif
}
-#endif
+
/*****************************************************************************
- * vdec_idct.h : types for the inverse discrete cosine transform
+ * idct.h : macros for the inverse discrete cosine transform
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: vdec_idct.h,v 1.1 2000/12/21 17:19:52 massiot Exp $
+ * $Id: idct.h,v 1.1 2001/01/13 12:57:20 sam Exp $
*
* Authors: Gaël Hendryckx <jimmy@via.ecp.fr>
* Christophe Massiot <massiot@via.ecp.fr>
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
-/*****************************************************************************
- * Requires:
- * "config.h"
- * "common.h"
- * "threads.h"
- * "video_parser.h"
- *****************************************************************************/
-
-/*****************************************************************************
- * Common declarations
- *****************************************************************************/
-
-#ifndef VDEC_DFT
-typedef short dctelem_t;
-#else
-typedef int dctelem_t;
-#endif
-
-struct vdec_thread_s;
-
#define SPARSE_SCALE_FACTOR 8
#define DCTSIZE 8 /* 8*8 DCT */
#define MULTIPLY(var,const) ((var) * (const))
#endif
-/*****************************************************************************
- * Function pointers
- *****************************************************************************/
-typedef void (*f_idct_t)( struct vdec_thread_s *, dctelem_t*, int );
-
-/*****************************************************************************
- * Prototypes
- *****************************************************************************/
-void vdec_InitIDCT (struct vdec_thread_s * p_vdec);
-void vdec_SparseIDCT( struct vdec_thread_s *, dctelem_t*, int );
-void vdec_IDCT( struct vdec_thread_s *, dctelem_t*, int );
--- /dev/null
+/*****************************************************************************
+ * idct_common.c : common IDCT functions
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ * $Id: idct_common.c,v 1.1 2001/01/13 12:57:20 sam Exp $
+ *
+ * Authors: Gaël Hendryckx <jimmy@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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <stdlib.h>
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "intf_msg.h"
+
+#include "stream_control.h"
+#include "input_ext-dec.h"
+
+#include "video.h"
+#include "video_output.h"
+
+#include "video_decoder.h"
+
+#include "modules.h"
+
+#include "idct.h"
+
+void vdec_SparseIDCT ( vdec_thread_t * p_vdec, dctelem_t * p_block,
+ int i_sparse_pos);
+
+/*****************************************************************************
+ * vdec_SparseIDCT : IDCT function for sparse matrices
+ *****************************************************************************/
+void vdec_SparseIDCT (vdec_thread_t * p_vdec, dctelem_t * p_block,
+ int i_sparse_pos)
+{
+ short int val;
+ int * dp;
+ int v;
+ short int * p_dest;
+ short int * p_source;
+ int coeff, rr;
+
+ /* If DC Coefficient. */
+ if ( i_sparse_pos == 0 )
+ {
+ dp=(int *)p_block;
+ val=RIGHT_SHIFT((*p_block + 4), 3);
+ /* Compute int to assign. This speeds things up a bit */
+ v = ((val & 0xffff) | (val << 16));
+ dp[0] = v; dp[1] = v; dp[2] = v; dp[3] = v;
+ dp[4] = v; dp[5] = v; dp[6] = v; dp[7] = v;
+ dp[8] = v; dp[9] = v; dp[10] = v; dp[11] = v;
+ dp[12] = v; dp[13] = v; dp[14] = v; dp[15] = v;
+ dp[16] = v; dp[17] = v; dp[18] = v; dp[19] = v;
+ dp[20] = v; dp[21] = v; dp[22] = v; dp[23] = v;
+ dp[24] = v; dp[25] = v; dp[26] = v; dp[27] = v;
+ dp[28] = v; dp[29] = v; dp[30] = v; dp[31] = v;
+ return;
+ }
+ /* Some other coefficient. */
+ p_dest = (s16*)p_block;
+ p_source = (s16*)&p_vdec->p_pre_idct[i_sparse_pos];
+ coeff = (int)p_dest[i_sparse_pos];
+ for( rr=0 ; rr < 4 ; rr++ )
+ {
+ p_dest[0] = (p_source[0] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[1] = (p_source[1] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[2] = (p_source[2] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[3] = (p_source[3] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[4] = (p_source[4] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[5] = (p_source[5] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[6] = (p_source[6] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[7] = (p_source[7] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[8] = (p_source[8] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[9] = (p_source[9] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[10] = (p_source[10] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[11] = (p_source[11] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[12] = (p_source[12] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[13] = (p_source[13] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[14] = (p_source[14] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest[15] = (p_source[15] * coeff) >> SPARSE_SCALE_FACTOR;
+ p_dest += 16;
+ p_source += 16;
+ }
+ return;
+}
+
--- /dev/null
+/*****************************************************************************
+ * idctclassic.c : Classic IDCT module
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ * $Id: idctclassic.c,v 1.1 2001/01/13 12:57:20 sam Exp $
+ *
+ * Authors: Gaël Hendryckx <jimmy@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 idctclassic
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <stdlib.h>
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "intf_msg.h"
+
+#include "stream_control.h"
+#include "input_ext-dec.h"
+
+#include "video.h"
+#include "video_output.h"
+
+#include "video_decoder.h"
+
+#include "modules.h"
+#include "modules_inner.h"
+
+#include "idct.h"
+
+/*****************************************************************************
+ * Local and extern prototypes.
+ *****************************************************************************/
+static void idct_getfunctions( function_list_t * p_function_list );
+
+static int idct_Probe ( probedata_t *p_data );
+static void vdec_InitIDCT ( vdec_thread_t * p_vdec);
+ void vdec_SparseIDCT ( vdec_thread_t * p_vdec, dctelem_t * p_block,
+ int i_sparse_pos);
+static void vdec_IDCT ( vdec_thread_t * p_vdec, dctelem_t * p_block,
+ int i_idontcare );
+
+
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START
+ADD_WINDOW( "Configuration for classic IDCT module" )
+ ADD_COMMENT( "Ha, ha -- nothing to configure yet" )
+MODULE_CONFIG_END
+
+/*****************************************************************************
+ * InitModule: get the module structure and configuration.
+ *****************************************************************************
+ * We have to fill psz_name, psz_longname and psz_version. These variables
+ * will be strdup()ed later by the main application because the module can
+ * be unloaded later to save memory, and we want to be able to access this
+ * data even after the module has been unloaded.
+ *****************************************************************************/
+int InitModule( module_t * p_module )
+{
+ p_module->psz_name = MODULE_STRING;
+ p_module->psz_longname = "classic C IDCT module";
+ p_module->psz_version = VERSION;
+
+ p_module->i_capabilities = MODULE_CAPABILITY_NULL
+ | MODULE_CAPABILITY_IDCT;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * ActivateModule: set the module to an usable state.
+ *****************************************************************************
+ * This function fills the capability functions and the configuration
+ * structure. Once ActivateModule() has been called, the i_usage can
+ * be set to 0 and calls to NeedModule() be made to increment it. To unload
+ * the module, one has to wait until i_usage == 0 and call DeactivateModule().
+ *****************************************************************************/
+int ActivateModule( module_t * p_module )
+{
+ p_module->p_functions = malloc( sizeof( module_functions_t ) );
+ if( p_module->p_functions == NULL )
+ {
+ return( -1 );
+ }
+
+ idct_getfunctions( &p_module->p_functions->idct );
+
+ p_module->p_config = p_config;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * DeactivateModule: make sure the module can be unloaded.
+ *****************************************************************************
+ * This function must only be called when i_usage == 0. If it successfully
+ * returns, i_usage can be set to -1 and the module unloaded. Be careful to
+ * lock usage_lock during the whole process.
+ *****************************************************************************/
+int DeactivateModule( module_t * p_module )
+{
+ free( p_module->p_functions );
+
+ return( 0 );
+}
+
+/* Following functions are local */
+
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+static void idct_getfunctions( function_list_t * p_function_list )
+{
+ p_function_list->pf_probe = idct_Probe;
+ p_function_list->functions.idct.pf_init = vdec_InitIDCT;
+ p_function_list->functions.idct.pf_sparse_idct = vdec_SparseIDCT;
+ p_function_list->functions.idct.pf_idct = vdec_IDCT;
+}
+
+/*****************************************************************************
+ * idct_Probe: returns a preference score
+ *****************************************************************************/
+static int idct_Probe( probedata_t *p_data )
+{
+ /* This plugin always works */
+ return( 50 );
+}
+
+/*****************************************************************************
+ * vdec_InitIDCT : initialize datas for vdec_SparseIDCT
+ *****************************************************************************/
+static void vdec_InitIDCT (vdec_thread_t * p_vdec)
+{
+ int i;
+
+ dctelem_t * p_pre = p_vdec->p_pre_idct;
+ memset( p_pre, 0, 64*64*sizeof(dctelem_t) );
+
+ for( i=0 ; i < 64 ; i++ )
+ {
+ p_pre[i*64+i] = 1 << SPARSE_SCALE_FACTOR;
+ vdec_IDCT( p_vdec, &p_pre[i*64], 0) ;
+ }
+ return;
+}
+
+/*****************************************************************************
+ * vdec_IDCT : IDCT function for normal matrices
+ *****************************************************************************/
+static void vdec_IDCT( vdec_thread_t * p_vdec, dctelem_t * p_block,
+ int i_idontcare )
+{
+ /* dct classique: pour tester la meilleure entre la classique et la */
+ /* no classique */
+ s32 tmp0, tmp1, tmp2, tmp3;
+ s32 tmp10, tmp11, tmp12, tmp13;
+ s32 z1, z2, z3, z4, z5;
+ dctelem_t * dataptr;
+ int rowctr;
+ SHIFT_TEMPS
+
+ /* Pass 1: process rows. */
+ /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
+ /* furthermore, we scale the results by 2**PASS1_BITS. */
+
+ dataptr = p_block;
+ for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--)
+ {
+ /* Due to quantization, we will usually find that many of the input
+ * coefficients are zero, especially the AC terms. We can exploit this
+ * by short-circuiting the IDCT calculation for any row in which all
+ * the AC terms are zero. In that case each output is equal to the
+ * DC coefficient (with scale factor as needed).
+ * With typical images and quantization tables, half or more of the
+ * row DCT calculations can be simplified this way.
+ */
+
+ if ((dataptr[1] | dataptr[2] | dataptr[3] | dataptr[4] |
+ dataptr[5] | dataptr[6] | dataptr[7]) == 0)
+ {
+ /* AC terms all zero */
+ dctelem_t dcval = (dctelem_t) (dataptr[0] << PASS1_BITS);
+
+ dataptr[0] = dcval;
+ dataptr[1] = dcval;
+ dataptr[2] = dcval;
+ dataptr[3] = dcval;
+ dataptr[4] = dcval;
+ dataptr[5] = dcval;
+ dataptr[6] = dcval;
+ dataptr[7] = dcval;
+
+ dataptr += DCTSIZE; /* advance pointer to next row */
+ continue;
+ }
+
+ /* Even part: reverse the even part of the forward DCT. */
+ /* The rotator is sqrt(2)*c(-6). */
+
+ z2 = (s32) dataptr[2];
+ z3 = (s32) dataptr[6];
+
+ z1 = MULTIPLY(z2 + z3, FIX(0.541196100));
+ tmp2 = z1 + MULTIPLY(z3, - FIX(1.847759065));
+ tmp3 = z1 + MULTIPLY(z2, FIX(0.765366865));
+
+ tmp0 = ((s32) dataptr[0] + (s32) dataptr[4]) << CONST_BITS;
+ tmp1 = ((s32) dataptr[0] - (s32) dataptr[4]) << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ /* Odd part per figure 8; the matrix is unitary and hence its
+ * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
+ */
+
+ tmp0 = (s32) dataptr[7];
+ tmp1 = (s32) dataptr[5];
+ tmp2 = (s32) dataptr[3];
+ tmp3 = (s32) dataptr[1];
+
+ z1 = tmp0 + tmp3;
+ z2 = tmp1 + tmp2;
+ z3 = tmp0 + tmp2;
+ z4 = tmp1 + tmp3;
+ z5 = MULTIPLY(z3 + z4, FIX(1.175875602)); /* sqrt(2) * c3 */
+
+ tmp0 = MULTIPLY(tmp0, FIX(0.298631336)); /* sqrt(2) * (-c1+c3+c5-c7) */
+ tmp1 = MULTIPLY(tmp1, FIX(2.053119869)); /* sqrt(2) * ( c1+c3-c5+c7) */
+ tmp2 = MULTIPLY(tmp2, FIX(3.072711026)); /* sqrt(2) * ( c1+c3+c5-c7) */
+ tmp3 = MULTIPLY(tmp3, FIX(1.501321110)); /* sqrt(2) * ( c1+c3-c5-c7) */
+ z1 = MULTIPLY(z1, - FIX(0.899976223)); /* sqrt(2) * (c7-c3) */
+ z2 = MULTIPLY(z2, - FIX(2.562915447)); /* sqrt(2) * (-c1-c3) */
+ z3 = MULTIPLY(z3, - FIX(1.961570560)); /* sqrt(2) * (-c3-c5) */
+ z4 = MULTIPLY(z4, - FIX(0.390180644)); /* sqrt(2) * (c5-c3) */
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 += z1 + z4;
+
+ /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
+
+ dataptr[0] = (dctelem_t) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
+ dataptr[7] = (dctelem_t) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
+ dataptr[1] = (dctelem_t) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
+ dataptr[6] = (dctelem_t) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
+ dataptr[2] = (dctelem_t) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
+ dataptr[5] = (dctelem_t) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
+ dataptr[3] = (dctelem_t) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
+ dataptr[4] = (dctelem_t) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
+
+ dataptr += DCTSIZE; /* advance pointer to next row */
+ }
+
+ /* Pass 2: process columns. */
+ /* Note that we must descale the results by a factor of 8 == 2**3, */
+ /* and also undo the PASS1_BITS scaling. */
+
+ dataptr = p_block;
+ for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--)
+ {
+ /* Columns of zeroes can be exploited in the same way as we did with rows.
+ * However, the row calculation has created many nonzero AC terms, so the
+ * simplification applies less often (typically 5% to 10% of the time).
+ * On machines with very fast multiplication, it's possible that the
+ * test takes more time than it's worth. In that case this section
+ * may be commented out.
+ */
+
+#ifndef NO_ZERO_COLUMN_TEST /*ajoute un test mais evite des calculs */
+ if ((dataptr[DCTSIZE*1] | dataptr[DCTSIZE*2] | dataptr[DCTSIZE*3] |
+ dataptr[DCTSIZE*4] | dataptr[DCTSIZE*5] | dataptr[DCTSIZE*6] |
+ dataptr[DCTSIZE*7]) == 0)
+ {
+ /* AC terms all zero */
+ dctelem_t dcval = (dctelem_t) DESCALE((s32) dataptr[0], PASS1_BITS+3);
+
+ dataptr[DCTSIZE*0] = dcval;
+ dataptr[DCTSIZE*1] = dcval;
+ dataptr[DCTSIZE*2] = dcval;
+ dataptr[DCTSIZE*3] = dcval;
+ dataptr[DCTSIZE*4] = dcval;
+ dataptr[DCTSIZE*5] = dcval;
+ dataptr[DCTSIZE*6] = dcval;
+ dataptr[DCTSIZE*7] = dcval;
+
+ dataptr++; /* advance pointer to next column */
+ continue;
+ }
+#endif
+
+ /* Even part: reverse the even part of the forward DCT. */
+ /* The rotator is sqrt(2)*c(-6). */
+
+ z2 = (s32) dataptr[DCTSIZE*2];
+ z3 = (s32) dataptr[DCTSIZE*6];
+
+ z1 = MULTIPLY(z2 + z3, FIX(0.541196100));
+ tmp2 = z1 + MULTIPLY(z3, - FIX(1.847759065));
+ tmp3 = z1 + MULTIPLY(z2, FIX(0.765366865));
+
+ tmp0 = ((s32) dataptr[DCTSIZE*0] + (s32) dataptr[DCTSIZE*4]) << CONST_BITS;
+ tmp1 = ((s32) dataptr[DCTSIZE*0] - (s32) dataptr[DCTSIZE*4]) << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ /* Odd part per figure 8; the matrix is unitary and hence its
+ * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
+ */
+
+ tmp0 = (s32) dataptr[DCTSIZE*7];
+ tmp1 = (s32) dataptr[DCTSIZE*5];
+ tmp2 = (s32) dataptr[DCTSIZE*3];
+ tmp3 = (s32) dataptr[DCTSIZE*1];
+
+ z1 = tmp0 + tmp3;
+ z2 = tmp1 + tmp2;
+ z3 = tmp0 + tmp2;
+ z4 = tmp1 + tmp3;
+ z5 = MULTIPLY(z3 + z4, FIX(1.175875602)); /* sqrt(2) * c3 */
+
+ tmp0 = MULTIPLY(tmp0, FIX(0.298631336)); /* sqrt(2) * (-c1+c3+c5-c7) */
+ tmp1 = MULTIPLY(tmp1, FIX(2.053119869)); /* sqrt(2) * ( c1+c3-c5+c7) */
+ tmp2 = MULTIPLY(tmp2, FIX(3.072711026)); /* sqrt(2) * ( c1+c3+c5-c7) */
+ tmp3 = MULTIPLY(tmp3, FIX(1.501321110)); /* sqrt(2) * ( c1+c3-c5-c7) */
+ z1 = MULTIPLY(z1, - FIX(0.899976223)); /* sqrt(2) * (c7-c3) */
+ z2 = MULTIPLY(z2, - FIX(2.562915447)); /* sqrt(2) * (-c1-c3) */
+ z3 = MULTIPLY(z3, - FIX(1.961570560)); /* sqrt(2) * (-c3-c5) */
+ z4 = MULTIPLY(z4, - FIX(0.390180644)); /* sqrt(2) * (c5-c3) */
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 += z1 + z4;
+
+ /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
+
+ dataptr[DCTSIZE*0] = (dctelem_t) DESCALE(tmp10 + tmp3,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*7] = (dctelem_t) DESCALE(tmp10 - tmp3,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*1] = (dctelem_t) DESCALE(tmp11 + tmp2,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*6] = (dctelem_t) DESCALE(tmp11 - tmp2,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*2] = (dctelem_t) DESCALE(tmp12 + tmp1,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*5] = (dctelem_t) DESCALE(tmp12 - tmp1,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*3] = (dctelem_t) DESCALE(tmp13 + tmp0,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*4] = (dctelem_t) DESCALE(tmp13 - tmp0,
+ CONST_BITS+PASS1_BITS+3);
+
+ dataptr++; /* advance pointer to next column */
+ }
+}
+
--- /dev/null
+/*****************************************************************************
+ * idctmmx.c : MMX IDCT module
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ * $Id: idctmmx.c,v 1.1 2001/01/13 12:57:20 sam Exp $
+ *
+ * Authors: Gaël Hendryckx <jimmy@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 idctmmx
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <stdlib.h>
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "intf_msg.h"
+
+#include "stream_control.h"
+#include "input_ext-dec.h"
+
+#include "video.h"
+#include "video_output.h"
+
+#include "video_decoder.h"
+
+#include "modules.h"
+#include "modules_inner.h"
+
+#include "idct.h"
+
+/*****************************************************************************
+ * Local prototypes.
+ *****************************************************************************/
+static void idct_getfunctions( function_list_t * p_function_list );
+
+static int idct_Probe ( probedata_t *p_data );
+static void vdec_InitIDCT ( vdec_thread_t * p_vdec);
+ void vdec_SparseIDCT ( vdec_thread_t * p_vdec, dctelem_t * p_block,
+ int i_sparse_pos);
+ void vdec_IDCT ( vdec_thread_t * p_vdec, dctelem_t * p_block,
+ int i_idontcare );
+
+
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START
+ADD_WINDOW( "Configuration for MMX IDCT module" )
+ ADD_COMMENT( "Ha, ha -- nothing to configure yet" )
+MODULE_CONFIG_END
+
+/*****************************************************************************
+ * InitModule: get the module structure and configuration.
+ *****************************************************************************
+ * We have to fill psz_name, psz_longname and psz_version. These variables
+ * will be strdup()ed later by the main application because the module can
+ * be unloaded later to save memory, and we want to be able to access this
+ * data even after the module has been unloaded.
+ *****************************************************************************/
+int InitModule( module_t * p_module )
+{
+ p_module->psz_name = MODULE_STRING;
+ p_module->psz_longname = "MMX IDCT module";
+ p_module->psz_version = VERSION;
+
+ p_module->i_capabilities = MODULE_CAPABILITY_NULL
+ | MODULE_CAPABILITY_IDCT;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * ActivateModule: set the module to an usable state.
+ *****************************************************************************
+ * This function fills the capability functions and the configuration
+ * structure. Once ActivateModule() has been called, the i_usage can
+ * be set to 0 and calls to NeedModule() be made to increment it. To unload
+ * the module, one has to wait until i_usage == 0 and call DeactivateModule().
+ *****************************************************************************/
+int ActivateModule( module_t * p_module )
+{
+ p_module->p_functions = malloc( sizeof( module_functions_t ) );
+ if( p_module->p_functions == NULL )
+ {
+ return( -1 );
+ }
+
+ idct_getfunctions( &p_module->p_functions->idct );
+
+ p_module->p_config = p_config;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * DeactivateModule: make sure the module can be unloaded.
+ *****************************************************************************
+ * This function must only be called when i_usage == 0. If it successfully
+ * returns, i_usage can be set to -1 and the module unloaded. Be careful to
+ * lock usage_lock during the whole process.
+ *****************************************************************************/
+int DeactivateModule( module_t * p_module )
+{
+ free( p_module->p_functions );
+
+ return( 0 );
+}
+
+/* Following functions are local */
+
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+static void idct_getfunctions( function_list_t * p_function_list )
+{
+ p_function_list->pf_probe = idct_Probe;
+ p_function_list->functions.idct.pf_init = vdec_InitIDCT;
+ p_function_list->functions.idct.pf_sparse_idct = vdec_SparseIDCT;
+ p_function_list->functions.idct.pf_idct = vdec_IDCT;
+}
+
+/*****************************************************************************
+ * idct_Probe: return a preference score
+ *****************************************************************************/
+static int idct_Probe( probedata_t *p_data )
+{
+ /* This plugin always works */
+ return( 100 );
+}
+
+/*****************************************************************************
+ * vdec_InitIDCT : initialize datas for vdec_SparceIDCT
+ *****************************************************************************/
+static void vdec_InitIDCT (vdec_thread_t * p_vdec)
+{
+ int i;
+
+ dctelem_t * p_pre = p_vdec->p_pre_idct;
+ memset( p_pre, 0, 64*64*sizeof(dctelem_t) );
+
+ for( i=0 ; i < 64 ; i++ )
+ {
+ p_pre[i*64+i] = 1 << SPARSE_SCALE_FACTOR;
+ vdec_IDCT( p_vdec, &p_pre[i*64], 0) ;
+ }
+ return;
+}
+
* vdec_idctmmx.S : MMX IDCT implementation
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: vdec_idctmmx.S,v 1.6 2001/01/05 14:46:37 sam Exp $
+ * $Id: idctmmx_asm.S,v 1.1 2001/01/13 12:57:20 sam Exp $
*
* Authors:
*
}
#define aout_functions p_aout->p_module->p_functions->aout.functions.aout
- p_aout->p_open = aout_functions.p_open;
- p_aout->p_setformat = aout_functions.p_setformat;
- p_aout->p_getbufinfo = aout_functions.p_getbufinfo;
- p_aout->p_play = aout_functions.p_play;
- p_aout->p_close = aout_functions.p_close;
+ p_aout->pf_open = aout_functions.pf_open;
+ p_aout->pf_setformat = aout_functions.pf_setformat;
+ p_aout->pf_getbufinfo = aout_functions.pf_getbufinfo;
+ p_aout->pf_play = aout_functions.pf_play;
+ p_aout->pf_close = aout_functions.pf_close;
#undef aout_functions
/*
* Initialize audio device
*/
- if ( p_aout->p_open( p_aout ) )
+ if ( p_aout->pf_open( p_aout ) )
{
module_Unneed( p_main->p_module_bank, p_aout->p_module );
free( p_aout );
p_aout->b_stereo = ( p_aout->i_channels == 2 ) ? 1 : 0; /* FIXME: only works
for i_channels == 1 or 2 ??*/
- if ( p_aout->p_setformat( p_aout ) )
+ if ( p_aout->pf_setformat( p_aout ) )
{
- p_aout->p_close( p_aout );
+ p_aout->pf_close( p_aout );
module_Unneed( p_main->p_module_bank, p_aout->p_module );
free( p_aout );
return( NULL );
* this thread is only called in main and all calls are blocking */
if( aout_SpawnThread( p_aout ) )
{
- p_aout->p_close( p_aout );
+ p_aout->pf_close( p_aout );
module_Unneed( p_main->p_module_bank, p_aout->p_module );
free( p_aout );
return( NULL );
}
vlc_mutex_destroy( &p_aout->fifos_lock );
+ /* Free the plugin */
+ p_aout->pf_close( p_aout );
+
/* Release the aout module */
module_Unneed( p_main->p_module_bank, p_aout->p_module );
- /* Free the structure */
- p_aout->p_close( p_aout );
- intf_DbgMsg("aout debug: audio device (%s) closed", p_aout->psz_device);
-
/* Free structure */
free( p_aout );
}
((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256 ) + 128 ) * p_aout->vol / 256 );
p_aout->s32_buffer[l_buffer] = 0;
}
- l_bytes = p_aout->p_getbufinfo( p_aout, l_buffer_limit );
+ l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit );
p_aout->date = mdate() + ((((mtime_t)(l_bytes / 1 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 1 */
- p_aout->p_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
+ p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
if ( l_bytes > (l_buffer_limit * sizeof(u8) * 2) ) /* There are 2 channels (left & right) */
{
msleep( p_aout->l_msleep );
((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256) + 128 ) * p_aout->vol / 256 );
p_aout->s32_buffer[l_buffer] = 0;
}
- l_bytes = p_aout->p_getbufinfo( p_aout, l_buffer_limit );
+ l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit );
p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
- p_aout->p_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
+ p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
{
msleep( p_aout->l_msleep );
p_aout->s32_buffer[l_buffer] = 0;
}
- l_bytes = p_aout->p_getbufinfo( p_aout, l_buffer_limit );
+ l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit );
p_aout->date = mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */
- p_aout->p_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
+ p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
{
msleep( p_aout->l_msleep );
if( ( (1 << i_index) & i_capabilities ) )
{
i_score = ( (function_list_t *)p_module->p_functions)
- [i_index].p_probe( p_data );
+ [i_index].pf_probe( p_data );
if( i_score )
{
* video_parser.h : video parser thread
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: video_parser.h,v 1.2 2001/01/10 19:22:11 massiot Exp $
+ * $Id: video_parser.h,v 1.3 2001/01/13 12:57:20 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
/* variable length codes for the structure dct_dc_size for intra blocks */
lookup_t * pppl_dct_dc_size[2][2];
/* Structure to store the tables B14 & B15 (ISO/CEI 13818-2 B.4) */
- dct_lookup_t ppl_dct_coef[2][16384];
-
+ dct_lookup_t ppl_dct_coef[2][16384];
+ /* IDCT plugin used and shortcuts to access its capabilities */
+ struct module_s * p_module;
+ idct_init_t pf_init;
+ f_idct_t pf_sparse_idct;
+ f_idct_t pf_idct;
#ifdef STATS
/* Statistics */
* video_fifo.c : video FIFO management
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: video_fifo.c,v 1.26 2001/01/07 03:56:40 henri Exp $
+ * $Id: video_fifo.c,v 1.27 2001/01/13 12:57:21 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
#include "video.h"
#include "video_output.h"
+#include "video_decoder.h"
#include "../video_decoder/vdec_idct.h"
-#include "../video_decoder/video_decoder.h"
#include "../video_decoder/vdec_motion.h"
#include "../video_decoder/vpar_blocks.h"
* video_parser.c : video parser thread
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: video_parser.c,v 1.65 2001/01/12 17:33:18 massiot Exp $
+ * $Id: video_parser.c,v 1.66 2001/01/13 12:57:21 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
#include "threads.h"
#include "mtime.h"
#include "plugins.h"
+#include "modules.h"
#include "intf_msg.h"
#include "video.h"
#include "video_output.h"
-#include "../video_decoder/vdec_idct.h"
-#include "../video_decoder/video_decoder.h"
+#include "video_decoder.h"
#include "../video_decoder/vdec_motion.h"
+#include "../video_decoder/vdec_idct.h"
#include "../video_decoder/vpar_blocks.h"
#include "../video_decoder/vpar_headers.h"
#include "../video_decoder/video_parser.h"
#include "../video_decoder/video_fifo.h"
+#include "main.h"
+
/*
* Local prototypes
*/
p_vpar->p_vout = p_config->p_vout;
+ /* Choose the best IDCT module */
+ p_vpar->p_module = module_Need( p_main->p_module_bank,
+ MODULE_CAPABILITY_IDCT, NULL );
+
+ if( p_vpar->p_module == NULL )
+ {
+ intf_ErrMsg( "vpar error: no suitable IDCT module" );
+ free( p_vpar );
+ return( 0 );
+ }
+
+#define idct_functions p_vpar->p_module->p_functions->idct.functions.idct
+ p_vpar->pf_init = idct_functions.pf_init;
+ p_vpar->pf_sparse_idct = idct_functions.pf_sparse_idct;
+ p_vpar->pf_idct = idct_functions.pf_idct;
+#undef idct_functions
+
/* Spawn the video parser thread */
if ( vlc_thread_create( &p_vpar->thread_id, "video parser",
(vlc_thread_func_t)RunThread, (void *)p_vpar ) )
{
intf_ErrMsg("vpar error: can't spawn video parser thread");
+ module_Unneed( p_main->p_module_bank, p_vpar->p_module );
free( p_vpar );
return( 0 );
}
vlc_mutex_destroy( &(p_vpar->synchro.fifo_lock) );
+ module_Unneed( p_main->p_module_bank, p_vpar->p_module );
+
free( p_vpar );
intf_DbgMsg("vpar debug: EndThread(%p)", p_vpar);
* vpar_blocks.c : blocks parsing
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_blocks.c,v 1.69 2001/01/05 18:46:45 massiot Exp $
+ * $Id: vpar_blocks.c,v 1.70 2001/01/13 12:57:21 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Jean-Marc Dressler <polux@via.ecp.fr>
#include "video.h"
#include "video_output.h"
+#include "video_decoder.h"
#include "../video_decoder/vdec_idct.h"
-#include "../video_decoder/video_decoder.h"
#include "../video_decoder/vdec_motion.h"
#include "../video_decoder/vpar_blocks.h"
#endif
if( i_nc <= 1 )
{
- p_mb->pf_idct[i_b] = vdec_SparseIDCT;
+ p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct;
p_mb->pi_sparse_pos[i_b] = i_coef;
}
else
{
- p_mb->pf_idct[i_b] = vdec_IDCT;
+ p_mb->pf_idct[i_b] = p_vpar->pf_idct;
}
return;
case DCT_EOB:
if( i_nc <= 1 )
{
- p_mb->pf_idct[i_b] = vdec_SparseIDCT;
+ p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct;
p_mb->pi_sparse_pos[i_b] = i_coef;
}
else
{
- p_mb->pf_idct[i_b] = vdec_IDCT;
+ p_mb->pf_idct[i_b] = p_vpar->pf_idct;
}
return;
#endif
if( i_nc <= 1 )
{
- p_mb->pf_idct[i_b] = vdec_SparseIDCT;
+ p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct;
p_mb->pi_sparse_pos[i_b] = i_coef;
}
else
{
- p_mb->pf_idct[i_b] = vdec_IDCT;
+ p_mb->pf_idct[i_b] = p_vpar->pf_idct;
}
return;
case DCT_EOB:
if( i_nc <= 1 )
{
- p_mb->pf_idct[i_b] = vdec_SparseIDCT;
+ p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct;
p_mb->pi_sparse_pos[i_b] = i_coef;
}
else
{
- p_mb->pf_idct[i_b] = vdec_IDCT;
+ p_mb->pf_idct[i_b] = p_vpar->pf_idct;
}
return;
* vpar_headers.c : headers parsing
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_headers.c,v 1.67 2001/01/07 03:56:40 henri Exp $
+ * $Id: vpar_headers.c,v 1.68 2001/01/13 12:57:21 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Stéphane Borel <stef@via.ecp.fr>
#include "video.h"
#include "video_output.h"
+#include "video_decoder.h"
#include "../video_decoder/vdec_idct.h"
-#include "../video_decoder/video_decoder.h"
#include "../video_decoder/vdec_motion.h"
#include "../video_decoder/vpar_blocks.h"
* vpar_synchro.c : frame dropping routines
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_synchro.c,v 1.70 2001/01/10 19:48:26 sam Exp $
+ * $Id: vpar_synchro.c,v 1.71 2001/01/13 12:57:21 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
#include "video.h"
#include "video_output.h"
+#include "video_decoder.h"
#include "../video_decoder/vdec_idct.h"
-#include "../video_decoder/video_decoder.h"
#include "../video_decoder/vdec_motion.h"
#include "../video_decoder/vpar_blocks.h"