-Tue Jun 20 14:17:56 CEST 2000
+[insert date here]
0.1.99d :
* fixed RPM build
* .deb is now more lintian-friendly
+ * fixed vlc.spec to install nicely
+ * PLUGIN_PATH and DATA_PATH now in include/*.h
+ * removed a few useless warning messages
+ * removed remaining header stuff related to the old non-free decoder
+ * fixed the MGA build (doesn't work yet, though)
+ * new plugin API
+ * updated the INSTALL document
+ * plugin auto-detection
+ * fixed a few misspellings in the code
+ * removed the default --enable-ppro option because it didn't work on K6-2
+ * the framebuffer client now leaves the console in a working state
+ * the dithered 8 bpp YUV transformation works again (blame bbp !)
+ * the YUV transformations are now plugins as well
+ * alternative symlinks like gvlc, fbvlc are now created at compile time
+ * borrowed libmpeg2's GPLed MMX YUV transformations (16 and 32 bits)
Sun Jun 18 18:54:48 CEST 2000
0.1.99c :
* fixed Makefile.in for debug version
* caught Delete Window event in Gnome and X11 modes
- * fixed manpage
+ * fixed man page
* GGI output now works
* fixed a segfault on exit for the Gnome plugin
* fixed compile problems for BeOS
* new VLAN changing code
* created the ChangeLog file :)
+Thu Jun 15 20:48:54 CEST 2000
+0.1.99a :
+
+ * first public release
+
A typical way to configure the vlc is :
- ./configure --prefix=/usr --enable-ppro --enable-mmx --enable-gnome
+ ./configure --prefix=/usr --enable-mmx --enable-gnome
See `./configure --help' for more information.
################################################################################
default:
- @echo "This Makefile should not be called directly - see notes at end of"
- @echo "main Makefile."
+ @echo "This Makefile should not be called directly,"
+ @echo "see notes at end of main Makefile."
################################################################################
# Dependancies creation
@test -d .dep/$(dir $*) || mkdir -p .dep/$(dir $*)
#@echo "generating dependancies for $*.c"
@$(SHELL) -ec '$(CC) $(DCFLAGS) $(CFLAGS) $(DEFINE) $< \
- | sed '\''s/$(subst .,\.,$(notdir $*))\.o[ :]*/$(subst /,\/,$*).o \
- .dep\/$(subst /,\/,$*).d : /g'\'' > $@; \
- [ -s $@ ] || rm -f $@'
+ | sed '\''s/$(subst .,\.,$(notdir $*))\.o[ :]*/$(subst /,\/,$*).o \
+ .dep\/$(subst /,\/,$*).d : /g'\'' > $@; \
+ [ -s $@ ] || rm -f $@'
+
# DEFINE will contain some of the constants definitions decided in Makefile,
# including SYS_xx. It will be passed to C compiler.
DEFINE += -DSYS_$(shell echo $(SYS) | sed 's/-.*//' | tr a-z A-Z)
-DEFINE += -DPLUGIN_PATH="\"$(prefix)/lib/videolan/vlc\""
-DEFINE += -DDATA_PATH="\"$(prefix)/share/videolan/vlc\""
################################################################################
# Tuning and other variables - do not change anything except if you know
misc_obj = misc/mtime.o \
misc/rsc_files.o \
misc/netutils.o \
+ misc/playlist.o \
misc/plugins.o \
misc/decoder_fifo.o
#
PLUGINS := $(PLUGINS:%=lib/%.so)
-PLUGIN_BEOS = plugins/beos/aout_beos.o \
+PLUGIN_BEOS = plugins/beos/beos.o \
+ plugins/beos/aout_beos.o \
plugins/beos/intf_beos.o \
plugins/beos/vout_beos.o
-PLUGIN_DSP = plugins/dsp/aout_dsp.o
+PLUGIN_DSP = plugins/dsp/dsp.o \
+ plugins/dsp/aout_dsp.o \
-PLUGIN_DUMMY = plugins/dummy/aout_dummy.o \
+PLUGIN_DUMMY = plugins/dummy/dummy.o \
+ plugins/dummy/aout_dummy.o \
plugins/dummy/intf_dummy.o \
plugins/dummy/vout_dummy.o
-PLUGIN_ESD = plugins/esd/aout_esd.o
+PLUGIN_ESD = plugins/esd/esd.o \
+ plugins/esd/aout_esd.o
-PLUGIN_FB = plugins/fb/intf_fb.o \
+PLUGIN_FB = plugins/fb/fb.o \
+ plugins/fb/intf_fb.o \
plugins/fb/vout_fb.o
-PLUGIN_GGI = plugins/ggi/intf_ggi.o \
+PLUGIN_GGI = plugins/ggi/ggi.o \
+ plugins/ggi/intf_ggi.o \
plugins/ggi/vout_ggi.o
-PLUGIN_GLIDE = plugins/glide/intf_glide.o \
+PLUGIN_GLIDE = plugins/glide/glide.o \
+ plugins/glide/intf_glide.o \
plugins/glide/vout_glide.o
-PLUGIN_GNOME = plugins/gnome/intf_gnome.o \
+PLUGIN_GNOME = plugins/gnome/gnome.o \
+ plugins/gnome/intf_gnome.o \
plugins/gnome/intf_gnome_callbacks.o \
plugins/gnome/intf_gnome_interface.o \
plugins/gnome/intf_gnome_support.o \
plugins/gnome/vout_gnome.o
-PLUGIN_MGA = plugins/mga/intf_mga.o \
- plugins/fb/vout_mga.o
+PLUGIN_MGA = plugins/mga/mga.o \
+ plugins/mga/intf_mga.o \
+ plugins/mga/vout_mga.o
-PLUGIN_X11 = plugins/x11/intf_x11.o \
+PLUGIN_X11 = plugins/x11/x11.o \
+ plugins/x11/intf_x11.o \
plugins/x11/vout_x11.o
+PLUGIN_YUV = plugins/yuv/yuv.o \
+ plugins/yuv/video_yuv.o \
+ plugins/yuv/video_yuv8.o \
+ plugins/yuv/video_yuv15.o \
+ plugins/yuv/video_yuv16.o \
+ plugins/yuv/video_yuv24.o \
+ plugins/yuv/video_yuv32.o
+
+PLUGIN_YUVMMX = plugins/yuvmmx/yuvmmx.o \
+ plugins/yuvmmx/video_yuv.o \
+ plugins/yuvmmx/video_yuv8.o \
+ plugins/yuvmmx/video_yuv15.o \
+ plugins/yuvmmx/video_yuv16.o \
+ plugins/yuvmmx/video_yuv24.o \
+ plugins/yuvmmx/video_yuv32.o
+
PLUGIN_OBJ = $(PLUGIN_BEOS) $(PLUGIN_DSP) $(PLUGIN_DUMMY) $(PLUGIN_ESD) \
$(PLUGIN_FB) $(PLUGIN_GGI) $(PLUGIN_GLIDE) $(PLUGIN_GNOME) \
- $(PLUGIN_MGA) $(PLUGIN_X11)
+ $(PLUGIN_MGA) $(PLUGIN_X11) $(PLUGIN_YUV) $(PLUGIN_YUVMMX)
#
# Other lists of files
#
#
# Virtual targets
#
-all: vlc plugins
+all: vlc @ALIASES@ plugins
clean:
rm -f $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ) $(PLUGIN_OBJ)
+ rm -f vlc @ALIASES@ lib/*.so
distclean: clean
- rm -f src/*/*.o plugins/*/*.o lib/*.so **/*~ *.log
+ rm -f src/*/*.o plugins/*/*.o **/*~ *.log
rm -f Makefile include/defs.h include/config.h
rm -f config.status config.cache config.log
- rm -f vlc gmon.out core build-stamp
+ rm -f gmon.out core build-stamp
rm -rf .dep
install:
$(INSTALL) vlc $(prefix)/bin
mkdir -p $(prefix)/lib/videolan/vlc
- mkdir -p $(prefix)/share/videolan/vlc
+ mkdir -p $(prefix)/share/videolan
$(INSTALL) -m 644 $(PLUGINS) $(prefix)/lib/videolan/vlc
- $(INSTALL) -m 644 share/*.psf $(prefix)/share/videolan/vlc
- $(INSTALL) -m 644 share/*.png $(prefix)/share/videolan/vlc
+ $(INSTALL) -m 644 share/*.psf $(prefix)/share/videolan
+ $(INSTALL) -m 644 share/*.png $(prefix)/share/videolan
show:
- @echo "Command line for C objects:"
- @echo $(CC) $(CCFLAGS) $(CFLAGS) -c -o "<dest.o>" "<src.c>"
- @echo
- @echo "Command line for assembler objects:"
- @echo $(CC) $(CFLAGS) -c -o "<dest.o>" "<src.S>"
+ @echo CC: $(CC)
+ @echo CCFLAGS: $(CCFLAGS)
+ @echo DCFLAGS: $(DCFLAGS)
+ @echo LCFLAGS: $(CCFLAGS)
# ugliest of all, but I have no time to do it -- sam
snapshot:
$(CC) $(CCFLAGS) $(LCFLAGS) $(CFLAGS) --export-dynamic -rdynamic -o $@ $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ)
endif
+gvlc xvlc fbvlc ggivlc glidevlc: vlc
+ rm -f $@ && ln -s vlc $@
+
plugins: $(PLUGINS)
#
#$(PLUGIN_OBJ): %.so: Makefile.dep
#$(PLUGIN_OBJ): %.so: .dep/%.d
-#$(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
-
lib/beos.so: $(PLUGIN_BEOS)
- ld -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
-$(PLUGIN_BEOS): %.o: %.c
+ $(CC) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
+$(PLUGIN_BEOS): %.o: %.cpp
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
lib/esd.so: $(PLUGIN_ESD)
$(PLUGIN_ESD): %.o: %.c
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
+lib/dsp.so: $(PLUGIN_DSP)
+ ld -shared -o $@ $^
+$(PLUGIN_DSP): %.o: %.c
+ $(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
+
lib/dummy.so: $(PLUGIN_DUMMY)
ld -shared -o $@ $^
$(PLUGIN_DUMMY): %.o: %.c
lib/gnome.so: $(PLUGIN_GNOME)
ld -shared `gnome-config --libs gnomeui | sed 's,-rdynamic,,'` -o $@ $^
$(PLUGIN_GNOME): %.o: %.c
- $(CC) $(CCFLAGS) $(CFLAGS) `gnome-config --cflags gnomeui`-c -o $@ $<
+ $(CC) $(CCFLAGS) $(CFLAGS) `gnome-config --cflags gnomeui` -c -o $@ $<
lib/glide.so: $(PLUGIN_GLIDE)
ld -shared -lglide2x -o $@ $^
$(PLUGIN_GGI): %.o: %.c
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
+lib/yuv.so: $(PLUGIN_YUV)
+ ld -shared -o $@ $^
+$(PLUGIN_YUV): %.o: %.c
+ $(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
+
+lib/yuvmmx.so: $(PLUGIN_YUVMMX)
+ ld -shared -o $@ $^
+$(PLUGIN_YUVMMX): %.o: %.c
+ $(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
+
################################################################################
# Note on generic rules and dependancies
################################################################################
Introduction
============
-[ nothing appropriate yet ]
+The vlc is part of the VideoLAN project, a full MPEG2 client/server
+solution. The VideoLAN Client can also be used as a standalone program
+to play MPEG2 streams from a hard disk or a DVD.
Building, Installing and Running VideoLAN
Resources
=========
-[ nothing appropriate yet ]
+The VideoLAN web site at http://www.videolan.org/ is a good start for
+information about MPEG and DVD playing. Have a look at the documentation
+section, as well as the bookmarks.
+
+You can also try the OpenDVD site at http://www.opendvd.org/ or the
+the LiVid project at http://www.linuxvideo.org/. They have lots of
+information, too.
The team
ac_default_prefix=/usr/local
# Any additions from configure.in:
ac_help="$ac_help
- --enable-dsp Linux /dev/dsp support (default enabled)"
+ --enable-ppro Enable PentiumPro optimizations (default is no)"
+ac_help="$ac_help
+ --enable-mmx Enable MMX optimizations (default is no)"
ac_help="$ac_help
--enable-dummy dummy audio and video support (default enabled)"
+ac_help="$ac_help
+ --enable-dsp Linux /dev/dsp support (default enabled)"
ac_help="$ac_help
--enable-esd Esound library support (default disabled)"
ac_help="$ac_help
--enable-gnome Gnome support (default disabled)"
ac_help="$ac_help
--enable-x11 X11 support (default enabled)"
-ac_help="$ac_help
- --enable-ppro Enable PentiumPro optimizations (default is no)"
-ac_help="$ac_help
- --enable-mmx Enable MMX optimizations (default is no)"
# Initialize some variables set by options.
# The variables have the same names as the options, with
fi
-# Check whether --enable-dsp or --disable-dsp was given.
-if test "${enable_dsp+set}" = set; then
- enableval="$enable_dsp"
- :
+PLUGINS=${PLUGINS}"yuv ";
+
+ARCH=${host_cpu}
+# Check whether --enable-ppro or --disable-ppro was given.
+if test "${enable_ppro+set}" = set; then
+ enableval="$enable_ppro"
+ if test x$enableval = xyes; then ARCH=${ARCH}" pentiumpro"; fi
fi
-if test x$enable_dsp != xno; then PLUGINS=${PLUGINS}"dsp "; fi
+# 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
+fi
+
+
+SYS=${host_os}
+
+# special cases
+if test x$host_os = xbeos; then
+ PLUGINS=${PLUGINS}"dummy beos "
+
+else
+
# Check whether --enable-dummy or --disable-dummy was given.
if test "${enable_dummy+set}" = set; then
enableval="$enable_dummy"
fi
if test x$enable_dummy != xno; then PLUGINS=${PLUGINS}"dummy "; fi
+# Check whether --enable-dsp or --disable-dsp was given.
+if test "${enable_dsp+set}" = set; then
+ enableval="$enable_dsp"
+ :
+fi
+
+if test x$enable_dsp != xno; then PLUGINS=${PLUGINS}"dsp "; fi
# Check whether --enable-esd or --disable-esd was given.
if test "${enable_esd+set}" = set; then
enableval="$enable_esd"
# Check whether --enable-fb or --disable-fb was given.
if test "${enable_fb+set}" = set; then
enableval="$enable_fb"
- if test x$enable_fb = xyes; then PLUGINS=${PLUGINS}"fb "; fi
+ if test x$enable_fb = xyes; then PLUGINS=${PLUGINS}"fb "; ALIASES=${ALIASES}"fbvlc "; fi
fi
# Check whether --enable-ggi or --disable-ggi was given.
if test "${enable_ggi+set}" = set; then
enableval="$enable_ggi"
- if test x$enable_ggi = xyes; then PLUGINS=${PLUGINS}"ggi "; fi
+ if test x$enable_ggi = xyes; then PLUGINS=${PLUGINS}"ggi "; ALIASES=${ALIASES}"ggivlc "; fi
fi
# Check whether --enable-glide or --disable-glide was given.
if test "${enable_glide+set}" = set; then
enableval="$enable_glide"
- if test x$enable_glide = xyes; then PLUGINS=${PLUGINS}"glide "; fi
+ if test x$enable_glide = xyes; then PLUGINS=${PLUGINS}"glide "; ALIASES=${ALIASES}"glidevlc "; fi
fi
# Check whether --enable-gnome or --disable-gnome was given.
if test "${enable_gnome+set}" = set; then
enableval="$enable_gnome"
- if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"gnome "; fi
+ if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"gnome "; ALIASES=${ALIASES}"gvlc "; fi
fi
# Check whether --enable-x11 or --disable-x11 was given.
:
fi
-if test x$enable_x11 != xno; then PLUGINS=${PLUGINS}"x11 "; fi
-
-ARCH=${host_cpu}
-# Check whether --enable-ppro or --disable-ppro was given.
-if test "${enable_ppro+set}" = set; then
- enableval="$enable_ppro"
- if test x$enableval = xyes; then ARCH=${ARCH}" pentiumpro"; fi
-fi
+if test x$enable_x11 != xno; then PLUGINS=${PLUGINS}"x11 "; ALIASES=${ALIASES}"xvlc "; fi
-# 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"; fi
fi
-SYS=${host_os}
-
-# special cases
-if test x$host_os = xbeos; then
- PLUGINS="dummy beos"
-fi
-
s%@SYS@%$SYS%g
s%@ARCH@%$ARCH%g
s%@PLUGINS@%$PLUGINS%g
+s%@ALIASES@%$ALIASES%g
CEOF
EOF
system : ${SYS}
architecture : ${ARCH}
plugins : ${PLUGINS}
+vlc aliases : ${ALIASES}
"
AC_TYPE_SIZE_T
AC_HEADER_TIME
-AC_ARG_ENABLE(dsp,
- [ --enable-dsp Linux /dev/dsp support (default enabled)])
-if test x$enable_dsp != xno; then PLUGINS=${PLUGINS}"dsp "; fi
+dnl default plugins
+PLUGINS=${PLUGINS}"yuv ";
+
+ARCH=${host_cpu}
+AC_ARG_ENABLE(ppro,
+[ --enable-ppro Enable PentiumPro optimizations (default is no)],
+[ if test x$enableval = xyes; then ARCH=${ARCH}" pentiumpro"; fi ])
+AC_ARG_ENABLE(mmx,
+[ --enable-mmx Enable MMX optimizations (default is no)],
+[ if test x$enableval = xyes; then ARCH=${ARCH}" mmx"; PLUGINS=${PLUGINS}"yuvmmx "; fi ])
+
+SYS=${host_os}
+
+# special cases
+if test x$host_os = xbeos; then
+ PLUGINS=${PLUGINS}"dummy beos "
+
+dnl default case
+else
+
AC_ARG_ENABLE(dummy,
[ --enable-dummy dummy audio and video support (default enabled)])
if test x$enable_dummy != xno; then PLUGINS=${PLUGINS}"dummy "; fi
+AC_ARG_ENABLE(dsp,
+ [ --enable-dsp Linux /dev/dsp support (default enabled)])
+if test x$enable_dsp != xno; then PLUGINS=${PLUGINS}"dsp "; fi
AC_ARG_ENABLE(esd,
[ --enable-esd Esound library support (default disabled)],
[if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"esd "; fi])
AC_ARG_ENABLE(fb,
[ --enable-fb Linux framebuffer support (default disabled)],
- [if test x$enable_fb = xyes; then PLUGINS=${PLUGINS}"fb "; fi])
+ [if test x$enable_fb = xyes; then PLUGINS=${PLUGINS}"fb "; ALIASES=${ALIASES}"fbvlc "; fi])
AC_ARG_ENABLE(ggi,
[ --enable-ggi GGI support (default disabled)],
- [if test x$enable_ggi = xyes; then PLUGINS=${PLUGINS}"ggi "; fi])
+ [if test x$enable_ggi = xyes; then PLUGINS=${PLUGINS}"ggi "; ALIASES=${ALIASES}"ggivlc "; fi])
AC_ARG_ENABLE(glide,
[ --enable-glide Glide (3dfx) support (default disabled)],
- [if test x$enable_glide = xyes; then PLUGINS=${PLUGINS}"glide "; fi])
+ [if test x$enable_glide = xyes; then PLUGINS=${PLUGINS}"glide "; ALIASES=${ALIASES}"glidevlc "; fi])
AC_ARG_ENABLE(gnome,
[ --enable-gnome Gnome support (default disabled)],
- [if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"gnome "; fi])
+ [if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"gnome "; ALIASES=${ALIASES}"gvlc "; fi])
AC_ARG_ENABLE(x11,
[ --enable-x11 X11 support (default enabled)])
-if test x$enable_x11 != xno; then PLUGINS=${PLUGINS}"x11 "; fi
+if test x$enable_x11 != xno; then PLUGINS=${PLUGINS}"x11 "; ALIASES=${ALIASES}"xvlc "; fi
-ARCH=${host_cpu}
-AC_ARG_ENABLE(ppro,
-[ --enable-ppro Enable PentiumPro optimizations (default is no)],
-[ if test x$enableval = xyes; then ARCH=${ARCH}" pentiumpro"; fi ])
-AC_ARG_ENABLE(mmx,
-[ --enable-mmx Enable MMX optimizations (default is no)],
-[ if test x$enableval = xyes; then ARCH=${ARCH}" mmx"; fi ])
-
-SYS=${host_os}
-
-# special cases
-if test x$host_os = xbeos; then
- PLUGINS="dummy beos"
fi
AC_SUBST(SYS)
AC_SUBST(ARCH)
AC_SUBST(PLUGINS)
+AC_SUBST(ALIASES)
AC_OUTPUT([Makefile include/config.h])
system : ${SYS}
architecture : ${ARCH}
plugins : ${PLUGINS}
+vlc aliases : ${ALIASES}
"
* .deb is now more lintian-friendly
- -- Samuel Hocevar <sam@via.ecp.fr> Tue, 20 Jun 2000 14:17:33 +0200
+ -- Samuel Hocevar <sam@via.ecp.fr> [Insert date here]
vlc (0.1.99c) unstable; urgency=low
* Copyright (C) 1999, 2000 VideoLAN
*
* Authors:
+ * Michel Kaempf <maxx@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
* Copyright (C) 1999, 2000 VideoLAN
*
* Authors:
+ * Michel Kaempf <maxx@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
* Copyright (C) 1999, 2000 VideoLAN
*
* Authors:
+ * Michel Kaempf <maxx@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
* Copyright (C) 1999, 2000 VideoLAN
*
* Authors:
+ * Michel Kaempf <maxx@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
* Copyright (C) 1999, 2000 VideoLAN
*
* Authors:
+ * Michel Kaempf <maxx@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
aout_fifo_t fifo[ AOUT_MAX_FIFOS ];
/* Plugins */
- plugin_id_t aout_plugin; /* video output plugin */
aout_sys_open_t * p_sys_open;
aout_sys_reset_t * p_sys_reset;
aout_sys_setformat_t * p_sys_setformat;
extern "C" {
#endif
-void beos_Init( void );
-void beos_Clean( void );
+void beos_Create( void );
+void beos_Destroy( void );
char * beos_GetProgramPath( void );
#ifdef __cplusplus
* Classes declaration
*****************************************************************************/
+/* Plugins */
+struct plugin_bank_s;
+struct plugin_info_s;
+
+typedef struct plugin_bank_s * p_plugin_bank_t;
+typedef struct plugin_info_s * p_plugin_info_t;
+
+/* Playlist */
+struct playlist_s;
+
+typedef struct playlist_s * p_playlist_t;
+
/* Interface */
struct intf_thread_s;
struct intf_sys_s;
* - Symbols should begin with a prefix indicating in which module they are
* used, such as INTF_, VOUT_ or ADEC_.
*
- * - Regarding environment variables, which are used as initialization parameters
- * for threads :
+ * - Regarding environment variables, which are used as initialization
+ * parameters for threads :
* + variable names should end with '_VAR'
* + environment variable default value should end with '_DEFAULT'
* + values having a special meaning with '_VAL'
/* Program version and copyright message */
#define VERSION_MESSAGE "vlc @VLC_VERSION@ @VLC_CODENAME@ " \
- /* "(" PROGRAM_BUILD ") (" PROGRAM_OPTIONS ")\n" */ \
+ /* "(" PROGRAM_BUILD ") (" PROGRAM_OPTIONS ")\n" */ \
"Copyright 1996-2000 VideoLAN\n"
#define COPYRIGHT_MESSAGE "VideoLAN Client - version @VLC_VERSION@" \
" @VLC_CODENAME@ - (c)1996-2000 VideoLAN"
/* Size of the FIFO. FIFO_SIZE+1 must be a power of 2 */
#define FIFO_SIZE 1023
+/*
+ * Paths
+ */
+
+#define DATA_PATH "@prefix@/share/videolan"
+#define PLUGIN_PATH "@prefix@/lib/videolan/vlc"
+
+#define MAX_PLUGIN_COUNT 32
/*****************************************************************************
* Interface configuration
#define VOUT_DISPLAY_VAR "vlc_display"
/* Default dimensions for display window - these dimensions are enough for the
- * standard width and height broadcasted MPEG-2 streams */
+ * standard width and height broadcasted MPEG-2 streams or DVDs */
#define VOUT_WIDTH_VAR "vlc_width"
#define VOUT_HEIGHT_VAR "vlc_height"
-#define VOUT_WIDTH_DEFAULT 720
-#define VOUT_HEIGHT_DEFAULT 576
+#define VOUT_WIDTH_DEFAULT 360
+#define VOUT_HEIGHT_DEFAULT 288
/* Maximum width of a scaled source picture - this should be relatively high,
* since higher stream values will result in no display at all. */
/* Optimization level, from 0 to 2 - 1 is generally a good compromise. Remember
* that raising this level dramatically lengthens the compilation time. */
-#define VPAR_OPTIM_LEVEL 1
+#define VPAR_OPTIM_LEVEL 2
/* The following directives only apply if you define VDEC_SMP below. */
*****************************************************************************/
/* FIXME: move to inline functions ??*/
-#define DECODER_FIFO_ISEMPTY( fifo ) ( (fifo).i_start == (fifo).i_end )
-#define DECODER_FIFO_ISFULL( fifo ) ( ( ( (fifo).i_end + 1 - (fifo).i_start ) \
+#define DECODER_FIFO_ISEMPTY( fifo ) ( (fifo).i_start == (fifo).i_end )
+#define DECODER_FIFO_ISFULL( fifo ) ( ( ((fifo).i_end + 1 - (fifo).i_start)\
& FIFO_SIZE ) == 0 )
-#define DECODER_FIFO_START( fifo ) ( (fifo).buffer[ (fifo).i_start ] )
-#define DECODER_FIFO_INCSTART( fifo ) ( (fifo).i_start = ((fifo).i_start + 1)\
- & FIFO_SIZE )
-#define DECODER_FIFO_END( fifo ) ( (fifo).buffer[ (fifo).i_end ] )
-#define DECODER_FIFO_INCEND( fifo ) ( (fifo).i_end = ((fifo).i_end + 1) \
+#define DECODER_FIFO_START( fifo ) ( (fifo).buffer[ (fifo).i_start ] )
+#define DECODER_FIFO_INCSTART( fifo ) ( (fifo).i_start = ((fifo).i_start + 1)\
& FIFO_SIZE )
+#define DECODER_FIFO_END( fifo ) ( (fifo).buffer[ (fifo).i_end ] )
+#define DECODER_FIFO_INCEND( fifo ) ( (fifo).i_end = ((fifo).i_end + 1) \
+ & FIFO_SIZE )
/*****************************************************************************
* decoder_fifo_t
*****************************************************************************/
static __inline__ void RealignBits( bit_stream_t * p_bit_stream )
{
- DumpBits( p_bit_stream, p_bit_stream->fifo.i_available & 7 );
+ DumpBits( p_bit_stream, p_bit_stream->fifo.i_available & 0x7 );
}
+
p_intf_sys_t p_sys; /* system interface */
/* Plugin */
- plugin_id_t intf_plugin; /* interface plugin */
intf_sys_create_t * p_sys_create; /* create interface thread */
intf_sys_manage_t * p_sys_manage; /* main loop */
intf_sys_destroy_t * p_sys_destroy; /* destroy interface */
/* XXX: Channels array - new API */
- //p_intf_channel_t * p_channel[INTF_MAX_CHANNELS];/* channel descriptions */
- /* file list - quick hack */
- char **p_playlist;
- int i_list_index;
+ //p_intf_channel_t * p_channel[INTF_MAX_CHANNELS];/* channel descriptions */
/* Channels array - NULL if not used */
p_intf_channel_t p_channel; /* description of channels */
* it when you can access the members you need in an other way. In fact, it
* should only be used by interface thread.
*****************************************************************************/
+
typedef struct
{
/* Global properties */
/* Shared data - these structures are accessed directly from p_main by
* several modules */
+ p_plugin_bank_t p_bank; /* plugin bank */
+ p_playlist_t p_playlist; /* plugin bank */
p_intf_msg_t p_msg; /* messages interface data */
p_input_vlan_t p_vlan; /* vlan library data */
} main_t;
char * main_GetPszVariable( char *psz_name, char *psz_default );
void main_PutIntVariable( char *psz_name, int i_value );
void main_PutPszVariable( char *psz_name, char *psz_value );
+
--- /dev/null
+/*****************************************************************************
+ * playlist.h : Playlist functions
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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.
+ *****************************************************************************/
+
+typedef struct playlist_s
+{
+ int i_index;
+ char** p_list;
+} playlist_t;
+
+playlist_t * playlist_Create ( void );
+void playlist_Init ( playlist_t * p_playlist, int i_optind );
+void playlist_Destroy ( playlist_t * p_playlist );
+
#ifdef SYS_BEOS
typedef int plugin_id_t;
+#define GET_PLUGIN( p_func, plugin_id, psz_name ) \
+ get_image_symbol( plugin_id, psz_name, B_SYMBOL_TYPE_TEXT, &p_func );
#else
-typedef void* plugin_id_t;
+typedef void *plugin_id_t;
+#define GET_PLUGIN( p_func, plugin_id, psz_name ) \
+ p_func = dlsym( plugin_id, psz_name );
#endif
-int RequestPlugin ( plugin_id_t * p_plugin, char * psz_name );
-void TrashPlugin ( plugin_id_t p_plugin );
-void * GetPluginFunction ( plugin_id_t plugin, char *name );
+typedef struct plugin_info_s
+{
+ plugin_id_t plugin_id;
+
+ char * psz_filename;
+ char * psz_name;
+ char * psz_version;
+ char * psz_author;
+
+ void * aout_GetPlugin;
+ void * vout_GetPlugin;
+ void * intf_GetPlugin;
+ void * yuv_GetPlugin;
+} plugin_info_t;
+
+typedef struct plugin_bank_s
+{
+ int i_plugin_count;
+ plugin_info_t * p_info[ MAX_PLUGIN_COUNT ];
+} plugin_bank_t;
+
+plugin_bank_t * bank_Create ( void );
+void bank_Init ( plugin_bank_t * p_bank );
+void bank_Destroy ( plugin_bank_t * p_bank );
--- /dev/null
+/*****************************************************************************
+ * plugins_export.h : exporting plugins structure
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+
+/* audio output */
+int aout_SysOpen ( aout_thread_t *p_aout );
+int aout_SysReset ( aout_thread_t *p_aout );
+int aout_SysSetFormat ( aout_thread_t *p_aout );
+int aout_SysSetChannels ( aout_thread_t *p_aout );
+int aout_SysSetRate ( aout_thread_t *p_aout );
+long aout_SysGetBufInfo ( aout_thread_t *p_aout, long l_buffer_info );
+void aout_SysPlaySamples ( aout_thread_t *p_aout, byte_t *buffer,
+ int i_size );
+void aout_SysClose ( aout_thread_t *p_aout );
+
+/* video output */
+int vout_SysCreate ( vout_thread_t *p_vout, char *psz_display,
+ int i_root_window, void *p_data );
+int vout_SysInit ( p_vout_thread_t p_vout );
+void vout_SysEnd ( p_vout_thread_t p_vout );
+void vout_SysDestroy ( p_vout_thread_t p_vout );
+int vout_SysManage ( p_vout_thread_t p_vout );
+void vout_SysDisplay ( p_vout_thread_t p_vout );
+void vout_SetPalette ( p_vout_thread_t p_vout,
+ u16 *red, u16 *green, u16 *blue, u16 *transp );
+
+/* interface */
+int intf_SysCreate ( p_intf_thread_t p_intf );
+void intf_SysDestroy ( p_intf_thread_t p_intf );
+void intf_SysManage ( p_intf_thread_t p_intf );
+
+/* YUV transformations */
+int yuv_SysInit ( p_vout_thread_t p_vout );
+int yuv_SysReset ( p_vout_thread_t p_vout );
+void yuv_SysEnd ( p_vout_thread_t p_vout );
+
} spudec_thread_t;
+/*****************************************************************************
+ * SPU commands
+ *****************************************************************************/
+#define SPU_CMD_FORCE_DISPLAY 0x00
+#define SPU_CMD_START_DISPLAY 0x01
+#define SPU_CMD_STOP_DISPLAY 0x02
+#define SPU_CMD_SET_PALETTE 0x03
+#define SPU_CMD_SET_ALPHACHANNEL 0x04
+#define SPU_CMD_SET_COORDINATES 0x05
+#define SPU_CMD_SET_OFFSETS 0x06
+#define SPU_CMD_END 0xff
+
/*****************************************************************************
* Prototypes
*****************************************************************************/
/* XXX?? */
// int *pi_status;
-#ifdef OLD_DECODER
- /* Input properties */
- decoder_fifo_t fifo; /* PES input fifo */
-
- /* The bit stream structure handles the PES stream at the bit level */
- bit_stream_t bit_stream;
-
- /* Output properties */
- vout_thread_t * p_vout; /* video output thread */
- int i_stream; /* video stream id */
-#else
/* idct iformations */
dctelem_t p_pre_idct[64*64];
u8 pi_crop_buf[VDEC_CROPRANGE];
u8 * pi_crop;
//#endif
-#endif
#ifdef STATS
/* Statistics */
count_t c_loops; /* number of loops */
count_t c_idle_loops; /* number of idle loops */
-#ifdef OLD_DECODER
- count_t c_pictures; /* number of pictures read */
- count_t c_i_pictures; /* number of I pictures read */
- count_t c_p_pictures; /* number of P pictures read */
- count_t c_b_pictures; /* number of B pictures read */
-#endif
count_t c_decoded_pictures; /* number of pictures decoded */
count_t c_decoded_i_pictures; /* number of I pictures decoded */
count_t c_decoded_p_pictures; /* number of P pictures decoded */
/*****************************************************************************
* Prototypes
*****************************************************************************/
-#ifndef OLD_DECODER
struct vpar_thread_s;
struct macroblock_s;
-#endif
/* Thread management functions */
-#ifdef OLD_DECODER
-p_vdec_thread_t vdec_CreateThread ( /* video_cfg_t *p_cfg, */ input_thread_t *p_input /*,
- vout_thread_t *p_vout, int *pi_status */ );
-void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_status */ );
-#else
#ifndef VDEC_SMP
int vdec_InitThread ( struct vdec_thread_s *p_vdec );
-void vdec_DecodeMacroblock ( struct vdec_thread_s *p_vdec, struct macroblock_s *p_mb );
-#endif
-vdec_thread_t * vdec_CreateThread ( struct vpar_thread_s *p_vpar /*, int *pi_status */ );
-void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_status */ );
+void vdec_DecodeMacroblock ( struct vdec_thread_s *p_vdec,
+ struct macroblock_s *p_mb );
#endif
+vdec_thread_t * vdec_CreateThread ( struct vpar_thread_s *p_vpar /*,
+ int *pi_status */ );
+void vdec_DestroyThread ( vdec_thread_t *p_vdec /*,
+ int *pi_status */ );
+
typedef void (vout_sys_destroy_t) ( p_vout_thread_t p_vout );
typedef int (vout_sys_manage_t) ( p_vout_thread_t p_vout );
typedef void (vout_sys_display_t) ( p_vout_thread_t p_vout );
+
typedef void (vout_set_palette_t) ( p_vout_thread_t p_vout, u16 *red,
u16 *green, u16 *blue, u16 *transp );
+typedef int (yuv_sys_init_t) ( p_vout_thread_t p_vout );
+typedef int (yuv_sys_reset_t) ( p_vout_thread_t p_vout );
+typedef void (yuv_sys_end_t) ( p_vout_thread_t p_vout );
+
typedef struct vout_thread_s
{
/* Thread properties and lock */
u32 i_blue_pixel; /* blue */
/* Plugins */
- plugin_id_t vout_plugin; /* video output plugin */
vout_sys_create_t * p_sys_create; /* allocate output method */
vout_sys_init_t * p_sys_init; /* initialize output method */
vout_sys_end_t * p_sys_end; /* terminate output method */
vout_sys_destroy_t * p_sys_destroy; /* destroy output method */
vout_sys_manage_t * p_sys_manage; /* handle events */
vout_sys_display_t * p_sys_display; /* display rendered image */
- vout_set_palette_t * p_set_palette; /* sets 8bpp palette */
+
+ vout_set_palette_t * p_set_palette; /* set 8bpp palette */
+
+ yuv_sys_init_t * p_yuv_init; /* initialize YUV tables */
+ yuv_sys_reset_t * p_yuv_reset; /* reset YUV tables */
+ yuv_sys_end_t * p_yuv_end; /* free YUV tables */
/* Pictures and rendering properties */
boolean_t b_grayscale; /* color or grayscale display */
* "video_fifo.h"
*****************************************************************************/
-#define POLUX_SYNCHRO
+#define SAM_SYNCHRO
+//#define POLUX_SYNCHRO
+//#define MEUUH_SYNCHRO
/*****************************************************************************
* video_synchro_t and video_synchro_tab_s : timers for the video synchro
*****************************************************************************/
#ifdef SAM_SYNCHRO
-typedef struct video_synchro_tab_s
-{
- double mean;
- double deviation;
-
-} video_synchro_tab_t;
-
-typedef struct video_synchro_fifo_s
-{
- /* type of image to be decoded, and decoding date */
- int i_image_type;
- mtime_t i_decode_date;
- mtime_t i_pts;
-
-} video_synchro_fifo_t;
-
typedef struct video_synchro_s
{
/* fifo containing decoding dates */
- video_synchro_fifo_t fifo[16];
- unsigned int i_fifo_start;
- unsigned int i_fifo_stop;
+ mtime_t i_date_fifo[16];
+ unsigned int i_start;
+ unsigned int i_stop;
/* mean decoding time */
- mtime_t i_mean_decode_time;
- /* dates */
- mtime_t i_last_display_pts; /* pts of the last displayed image */
- mtime_t i_last_decode_pts; /* pts of the last decoded image */
- mtime_t i_last_i_pts; /* pts of the last I image */
- mtime_t i_last_nondropped_i_pts; /* pts of last non-dropped I image */
- unsigned int i_images_since_pts;
+ mtime_t i_delay;
+ mtime_t i_theorical_delay;
- /* il manquait un compteur */
- unsigned int modulo;
+ /* dates */
+ mtime_t i_last_pts; /* pts of the last displayed image */
+ mtime_t i_last_seen_I_pts; /* date of the last I we decoded */
+ mtime_t i_last_kept_I_pts; /* pts of last non-dropped I image */
/* P images since the last I */
- unsigned int current_p_count;
- unsigned int nondropped_p_count;
- double p_count_predict;
+ unsigned int i_P_seen;
+ unsigned int i_P_kept;
/* B images since the last I */
- unsigned int current_b_count;
- unsigned int nondropped_b_count;
- double b_count_predict;
+ unsigned int i_B_seen;
+ unsigned int i_B_kept;
/* can we display pictures ? */
- unsigned int can_display_i;
- unsigned int can_display_p;
- double displayable_p;
- unsigned int can_display_b;
- double displayable_b;
+ boolean_t b_all_I;
+ boolean_t b_all_P;
+ double displayable_p;
+ boolean_t b_all_B;
+ double displayable_b;
- /* 1 for linear count, 2 for binary count, 3 for ternary count */
- video_synchro_tab_t tab_p[6];
- video_synchro_tab_t tab_b[6];
+} video_synchro_t;
- double theorical_fps;
- double actual_fps;
+#define FIFO_INCREMENT( i_counter ) \
+ p_vpar->synchro.i_counter = (p_vpar->synchro.i_counter + 1) & 0xf;
-} video_synchro_t;
#endif
#ifdef MEUUH_SYNCHRO
/*****************************************************************************
* Prototypes
*****************************************************************************/
-boolean_t vpar_SynchroChoose( struct vpar_thread_s * p_vpar, int i_coding_type,
- int i_structure );
-void vpar_SynchroTrash( struct vpar_thread_s * p_vpar, int i_coding_type,
- int i_structure );
-void vpar_SynchroDecode( struct vpar_thread_s * p_vpar, int i_coding_type,
- int i_structure );
-void vpar_SynchroEnd( struct vpar_thread_s * p_vpar );
-mtime_t vpar_SynchroDate( struct vpar_thread_s * p_vpar );
+boolean_t vpar_SynchroChoose ( struct vpar_thread_s * p_vpar,
+ int i_coding_type, int i_structure );
+void vpar_SynchroTrash ( struct vpar_thread_s * p_vpar,
+ int i_coding_type, int i_structure );
+void vpar_SynchroDecode ( struct vpar_thread_s * p_vpar,
+ int i_coding_type, int i_structure );
+void vpar_SynchroEnd ( struct vpar_thread_s * p_vpar );
+mtime_t vpar_SynchroDate ( struct vpar_thread_s * p_vpar );
#ifndef SAM_SYNCHRO
-void vpar_SynchroKludge( struct vpar_thread_s *, mtime_t );
+void vpar_SynchroKludge ( struct vpar_thread_s *, mtime_t );
#endif
--- /dev/null
+/*****************************************************************************
+ * beos.cpp : BeOS plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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> /* malloc(), free() */
+
+extern "C"
+{
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "interface.h"
+#include "audio_output.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "plugins_export.h"
+
+/*****************************************************************************
+ * Exported prototypes
+ *****************************************************************************/
+void aout_GetPlugin( p_aout_thread_t p_aout );
+void vout_GetPlugin( p_vout_thread_t p_vout );
+void intf_GetPlugin( p_intf_thread_t p_intf );
+
+/*****************************************************************************
+ * GetConfig: get the plugin structure and configuration
+ *****************************************************************************/
+plugin_info_t * GetConfig( void )
+{
+ plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+
+ p_info->psz_name = "BeOS";
+ p_info->psz_version = VERSION;
+ p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
+
+ p_info->aout_GetPlugin = aout_GetPlugin;
+ p_info->vout_GetPlugin = vout_GetPlugin;
+ p_info->intf_GetPlugin = intf_GetPlugin;
+
+ return( p_info );
+}
+
+/*****************************************************************************
+ * Test: tests if the plugin can be launched
+ *****************************************************************************/
+int Test( void )
+{
+ /* the BeOS plugin always works under BeOS :) */
+ return( 1 );
+}
+
+/*****************************************************************************
+ * Following functions are only called through the p_info structure
+ *****************************************************************************/
+
+void aout_GetPlugin( p_aout_thread_t p_aout )
+{
+ p_aout->p_sys_open = aout_SysOpen;
+ p_aout->p_sys_reset = aout_SysReset;
+ p_aout->p_sys_setformat = aout_SysSetFormat;
+ p_aout->p_sys_setchannels = aout_SysSetChannels;
+ p_aout->p_sys_setrate = aout_SysSetRate;
+ p_aout->p_sys_getbufinfo = aout_SysGetBufInfo;
+ p_aout->p_sys_playsamples = aout_SysPlaySamples;
+ p_aout->p_sys_close = aout_SysClose;
+}
+
+void vout_GetPlugin( p_vout_thread_t p_vout )
+{
+ p_vout->p_sys_create = vout_SysCreate;
+ p_vout->p_sys_init = vout_SysInit;
+ p_vout->p_sys_end = vout_SysEnd;
+ p_vout->p_sys_destroy = vout_SysDestroy;
+ p_vout->p_sys_manage = vout_SysManage;
+ p_vout->p_sys_display = vout_SysDisplay;
+}
+
+void intf_GetPlugin( p_intf_thread_t p_intf )
+{
+ p_intf->p_sys_create = intf_SysCreate;
+ p_intf->p_sys_destroy = intf_SysDestroy;
+ p_intf->p_sys_manage = intf_SysManage;
+}
+
+} /* extern "C" */
--- /dev/null
+/*****************************************************************************
+ * dsp.c : OSS /dev/dsp plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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> /* malloc(), free() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "interface.h"
+#include "audio_output.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "plugins_export.h"
+
+/*****************************************************************************
+ * Exported prototypes
+ *****************************************************************************/
+void aout_GetPlugin( p_aout_thread_t p_aout );
+
+/*****************************************************************************
+ * GetConfig: get the plugin structure and configuration
+ *****************************************************************************/
+plugin_info_t * GetConfig( void )
+{
+ plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+
+ p_info->psz_name = "OSS /dev/dsp";
+ p_info->psz_version = VERSION;
+ p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
+
+ p_info->aout_GetPlugin = aout_GetPlugin;
+ p_info->vout_GetPlugin = NULL;
+ p_info->intf_GetPlugin = NULL;
+ p_info->yuv_GetPlugin = NULL;
+
+ return( p_info );
+}
+
+/*****************************************************************************
+ * Test: tests if the plugin can be launched
+ *****************************************************************************/
+int Test( void )
+{
+ /* TODO: check if suitable */
+ return( 1 );
+}
+
+/*****************************************************************************
+ * Following functions are only called through the p_info structure
+ *****************************************************************************/
+
+void aout_GetPlugin( p_aout_thread_t p_aout )
+{
+ p_aout->p_sys_open = aout_SysOpen;
+ p_aout->p_sys_reset = aout_SysReset;
+ p_aout->p_sys_setformat = aout_SysSetFormat;
+ p_aout->p_sys_setchannels = aout_SysSetChannels;
+ p_aout->p_sys_setrate = aout_SysSetRate;
+ p_aout->p_sys_getbufinfo = aout_SysGetBufInfo;
+ p_aout->p_sys_playsamples = aout_SysPlaySamples;
+ p_aout->p_sys_close = aout_SysClose;
+}
+
--- /dev/null
+/*****************************************************************************
+ * dummy.c : dummy plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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> /* malloc(), free() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "interface.h"
+#include "audio_output.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "plugins_export.h"
+
+/*****************************************************************************
+ * Exported prototypes
+ *****************************************************************************/
+void aout_GetPlugin( p_aout_thread_t p_aout );
+void vout_GetPlugin( p_vout_thread_t p_vout );
+void intf_GetPlugin( p_intf_thread_t p_intf );
+
+/*****************************************************************************
+ * GetConfig: get the plugin structure and configuration
+ *****************************************************************************/
+plugin_info_t * GetConfig( void )
+{
+ plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+
+ p_info->psz_name = "Dummy";
+ p_info->psz_version = VERSION;
+ p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
+
+ p_info->aout_GetPlugin = aout_GetPlugin;
+ p_info->vout_GetPlugin = vout_GetPlugin;
+ p_info->intf_GetPlugin = intf_GetPlugin;
+ p_info->yuv_GetPlugin = NULL;
+
+ return( p_info );
+}
+
+/*****************************************************************************
+ * Test: tests if the plugin can be launched
+ *****************************************************************************/
+int Test( void )
+{
+ /* the dummy plugin always works */
+ return( 1 );
+}
+
+/*****************************************************************************
+ * Following functions are only called through the p_info structure
+ *****************************************************************************/
+
+void aout_GetPlugin( p_aout_thread_t p_aout )
+{
+ p_aout->p_sys_open = aout_SysOpen;
+ p_aout->p_sys_reset = aout_SysReset;
+ p_aout->p_sys_setformat = aout_SysSetFormat;
+ p_aout->p_sys_setchannels = aout_SysSetChannels;
+ p_aout->p_sys_setrate = aout_SysSetRate;
+ p_aout->p_sys_getbufinfo = aout_SysGetBufInfo;
+ p_aout->p_sys_playsamples = aout_SysPlaySamples;
+ p_aout->p_sys_close = aout_SysClose;
+}
+
+void vout_GetPlugin( p_vout_thread_t p_vout )
+{
+ p_vout->p_sys_create = vout_SysCreate;
+ p_vout->p_sys_init = vout_SysInit;
+ p_vout->p_sys_end = vout_SysEnd;
+ p_vout->p_sys_destroy = vout_SysDestroy;
+ p_vout->p_sys_manage = vout_SysManage;
+ p_vout->p_sys_display = vout_SysDisplay;
+}
+
+void intf_GetPlugin( p_intf_thread_t p_intf )
+{
+ p_intf->p_sys_create = intf_SysCreate;
+ p_intf->p_sys_destroy = intf_SysDestroy;
+ p_intf->p_sys_manage = intf_SysManage;
+}
+
#include "intf_msg.h"
-#define WIDTH 128
-#define HEIGHT 64
+#define WIDTH 16
+#define HEIGHT 16
#define BITS_PER_PLANE 16
#define BYTES_PER_PIXEL 2
--- /dev/null
+/*****************************************************************************
+ * esd.c : Esound plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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> /* malloc(), free() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "interface.h"
+#include "audio_output.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "plugins_export.h"
+
+/*****************************************************************************
+ * Exported prototypes
+ *****************************************************************************/
+void aout_GetPlugin( p_aout_thread_t p_aout );
+
+/*****************************************************************************
+ * GetConfig: get the plugin structure and configuration
+ *****************************************************************************/
+plugin_info_t * GetConfig( void )
+{
+ plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+
+ p_info->psz_name = "Esound";
+ p_info->psz_version = VERSION;
+ p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
+
+ p_info->aout_GetPlugin = aout_GetPlugin;
+ p_info->vout_GetPlugin = NULL;
+ p_info->intf_GetPlugin = NULL;
+ p_info->yuv_GetPlugin = NULL;
+
+ return( p_info );
+}
+
+/*****************************************************************************
+ * Test: tests if the plugin can be launched
+ *****************************************************************************/
+int Test( void )
+{
+ /* TODO: check if suitable */
+ return( 1 );
+}
+
+/*****************************************************************************
+ * Following functions are only called through the p_info structure
+ *****************************************************************************/
+
+void aout_GetPlugin( p_aout_thread_t p_aout )
+{
+ p_aout->p_sys_open = aout_SysOpen;
+ p_aout->p_sys_reset = aout_SysReset;
+ p_aout->p_sys_setformat = aout_SysSetFormat;
+ p_aout->p_sys_setchannels = aout_SysSetChannels;
+ p_aout->p_sys_setrate = aout_SysSetRate;
+ p_aout->p_sys_getbufinfo = aout_SysGetBufInfo;
+ p_aout->p_sys_playsamples = aout_SysPlaySamples;
+ p_aout->p_sys_close = aout_SysClose;
+}
+
--- /dev/null
+/*****************************************************************************
+ * fb.c : Linux framebuffer plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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> /* malloc(), free() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "interface.h"
+#include "audio_output.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "plugins_export.h"
+
+/*****************************************************************************
+ * Exported prototypes
+ *****************************************************************************/
+void vout_GetPlugin( p_vout_thread_t p_vout );
+void intf_GetPlugin( p_intf_thread_t p_intf );
+
+/*****************************************************************************
+ * GetConfig: get the plugin structure and configuration
+ *****************************************************************************/
+plugin_info_t * GetConfig( void )
+{
+ plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+
+ p_info->psz_name = "Linux framebuffer";
+ p_info->psz_version = VERSION;
+ p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
+
+ p_info->aout_GetPlugin = NULL;
+ p_info->vout_GetPlugin = vout_GetPlugin;
+ p_info->intf_GetPlugin = intf_GetPlugin;
+ p_info->yuv_GetPlugin = NULL;
+
+ return( p_info );
+}
+
+/*****************************************************************************
+ * Test: tests if the plugin can be launched
+ *****************************************************************************/
+int Test( void )
+{
+ /* TODO: detect the framebuffer ioctl()s in the kernel */
+ return( 1 );
+}
+
+/*****************************************************************************
+ * Following functions are only called through the p_info structure
+ *****************************************************************************/
+
+void vout_GetPlugin( p_vout_thread_t p_vout )
+{
+ p_vout->p_sys_create = vout_SysCreate;
+ p_vout->p_sys_init = vout_SysInit;
+ p_vout->p_sys_end = vout_SysEnd;
+ p_vout->p_sys_destroy = vout_SysDestroy;
+ p_vout->p_sys_manage = vout_SysManage;
+ p_vout->p_sys_display = vout_SysDisplay;
+
+ /* optional functions */
+ p_vout->p_set_palette = vout_SetPalette;
+}
+
+void intf_GetPlugin( p_intf_thread_t p_intf )
+{
+ p_intf->p_sys_create = intf_SysCreate;
+ p_intf->p_sys_destroy = intf_SysDestroy;
+ p_intf->p_sys_manage = intf_SysManage;
+}
+
/* set keyboard settings */
if (tcgetattr(0, &p_intf->p_sys->old_termios) == -1)
+ {
intf_ErrMsg( "intf error: tcgetattr" );
+ }
+
if (tcgetattr(0, &p_intf->p_sys->new_termios) == -1)
+ {
intf_ErrMsg( "intf error: tcgetattr" );
+ }
p_intf->p_sys->new_termios.c_lflag &= ~ (ICANON | ISIG);
p_intf->p_sys->new_termios.c_lflag |= (ECHO | ECHOCTL);
p_intf->p_sys->new_termios.c_cc[VTIME] = 0;
if (tcsetattr(0, TCSAFLUSH, &p_intf->p_sys->new_termios) == -1)
+ {
intf_ErrMsg( "intf error: tcsetattr" );
+ }
ioctl(p_intf->p_sys->i_tty_dev, VT_RELDISP, VT_ACKACQ);
if( sigaction( SIGUSR1, &sig_tty, &p_intf->p_sys->sig_usr1 ) ||
sigaction( SIGUSR2, &sig_tty, &p_intf->p_sys->sig_usr2 ) )
{
- intf_ErrMsg("intf error: can't set up signal handler (%s)\n", strerror(errno) );
+ intf_ErrMsg( "intf error: can't set up signal handler (%s)\n",
+ strerror(errno) );
+ tcsetattr(0, 0, &p_intf->p_sys->old_termios);
FBTextMode( p_intf->p_sys->i_tty_dev );
return( 1 );
}
/* Set-up tty according to new signal handler */
- if( ioctl(p_intf->p_sys->i_tty_dev, VT_GETMODE, &p_intf->p_sys->vt_mode) == -1 )
+ if( ioctl(p_intf->p_sys->i_tty_dev, VT_GETMODE, &p_intf->p_sys->vt_mode)
+ == -1 )
{
- intf_ErrMsg("intf error: cant get terminal mode (%s)\n", strerror(errno) );
+ intf_ErrMsg( "intf error: cant get terminal mode (%s)\n",
+ strerror(errno) );
sigaction( SIGUSR1, &p_intf->p_sys->sig_usr1, NULL );
sigaction( SIGUSR2, &p_intf->p_sys->sig_usr2, NULL );
+ tcsetattr(0, 0, &p_intf->p_sys->old_termios);
FBTextMode( p_intf->p_sys->i_tty_dev );
return( 1 );
}
if( ioctl(p_intf->p_sys->i_tty_dev, VT_SETMODE, &vt_mode) == -1 )
{
- intf_ErrMsg("intf error: can't set terminal mode (%s)\n", strerror(errno) );
+ intf_ErrMsg( "intf error: can't set terminal mode (%s)\n",
+ strerror(errno) );
sigaction( SIGUSR1, &p_intf->p_sys->sig_usr1, NULL );
sigaction( SIGUSR2, &p_intf->p_sys->sig_usr2, NULL );
+ tcsetattr(0, 0, &p_intf->p_sys->old_termios);
FBTextMode( p_intf->p_sys->i_tty_dev );
return( 1 );
}
{
p_intf->p_vout = vout_CreateThread( NULL, 0,
p_intf->p_sys->i_width,
- p_intf->p_sys->i_height, NULL, 0, NULL );
+ p_intf->p_sys->i_height,
+ NULL, 0, NULL );
if( p_intf->p_vout == NULL ) /* XXX?? error */
{
intf_ErrMsg("intf error: can't create output thread\n" );
- ioctl(p_intf->p_sys->i_tty_dev, VT_SETMODE, &p_intf->p_sys->vt_mode);
+ ioctl( p_intf->p_sys->i_tty_dev, VT_SETMODE,
+ &p_intf->p_sys->vt_mode );
sigaction( SIGUSR1, &p_intf->p_sys->sig_usr1, NULL );
sigaction( SIGUSR2, &p_intf->p_sys->sig_usr2, NULL );
free( p_intf->p_sys );
+ tcsetattr(0, 0, &p_intf->p_sys->old_termios);
FBTextMode( p_intf->p_sys->i_tty_dev );
return( 1 );
}
/*****************************************************************************
* FBSwitchDisplay: VT change signal handler
*****************************************************************************
- * This function activate or desactivate the output of the thread. It is called
- * by the VT driver, on terminal change.
+ * This function activates or deactivates the output of the thread. It is
+ * called by the VT driver, on terminal change.
*****************************************************************************/
static void FBSwitchDisplay(int i_signal)
{
*****************************************************************************/
static int FBOpenDisplay ( vout_thread_t *p_vout );
static void FBCloseDisplay ( vout_thread_t *p_vout );
-static void FBSetPalette ( p_vout_thread_t p_vout,
- u16 *red, u16 *green, u16 *blue, u16 *transp );
/*****************************************************************************
* vout_SysCreate: allocates FB video thread output method
*****************************************************************************/
int vout_SysInit( vout_thread_t *p_vout )
{
- p_vout->p_set_palette = FBSetPalette;
return( 0 );
}
ioctl( p_vout->p_sys->i_fb_dev, FBIOPAN_DISPLAY, &p_vout->p_sys->var_info );
}
+/*****************************************************************************
+ * vout_SetPalette: sets an 8 bpp palette
+ *****************************************************************************
+ * This function sets the palette given as an argument. It does not return
+ * anything, but could later send information on which colors it was unable
+ * to set.
+ *****************************************************************************/
+void vout_SetPalette( p_vout_thread_t p_vout,
+ u16 *red, u16 *green, u16 *blue, u16 *transp )
+{
+ struct fb_cmap cmap = { 0, 256, red, green, blue, transp };
+ ioctl( p_vout->p_sys->i_fb_dev, FBIOPUTCMAP, &cmap );
+}
+
/* following functions are local */
/*****************************************************************************
close( p_vout->p_sys->i_fb_dev );
}
-/*****************************************************************************
- * FBSetPalette: sets an 8 bpp palette
- *****************************************************************************
- * This function sets the palette given as an argument. It does not return
- * anything, but could later send information on which colors it was unable
- * to set.
- *****************************************************************************/
-static void FBSetPalette ( p_vout_thread_t p_vout,
- u16 *red, u16 *green, u16 *blue, u16 *transp )
-{
- struct fb_cmap cmap = { 0, 256, red, green, blue, transp };
- ioctl( p_vout->p_sys->i_fb_dev, FBIOPUTCMAP, &cmap );
-}
--- /dev/null
+/*****************************************************************************
+ * ggi.c : GGI plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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> /* malloc(), free() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "interface.h"
+#include "audio_output.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "plugins_export.h"
+
+/*****************************************************************************
+ * Exported prototypes
+ *****************************************************************************/
+void vout_GetPlugin( p_vout_thread_t p_vout );
+void intf_GetPlugin( p_intf_thread_t p_intf );
+
+/*****************************************************************************
+ * GetConfig: get the plugin structure and configuration
+ *****************************************************************************/
+plugin_info_t * GetConfig( void )
+{
+ plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+
+ p_info->psz_name = "GGI";
+ p_info->psz_version = VERSION;
+ p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
+
+ p_info->aout_GetPlugin = NULL;
+ p_info->vout_GetPlugin = vout_GetPlugin;
+ p_info->intf_GetPlugin = intf_GetPlugin;
+ p_info->yuv_GetPlugin = NULL;
+
+ return( p_info );
+}
+
+/*****************************************************************************
+ * Test: tests if the plugin can be launched
+ *****************************************************************************/
+int Test( void )
+{
+ /* TODO: detect GGI_DISPLAY or whatever */
+ return( 1 );
+}
+
+/*****************************************************************************
+ * Following functions are only called through the p_info structure
+ *****************************************************************************/
+
+void vout_GetPlugin( p_vout_thread_t p_vout )
+{
+ p_vout->p_sys_create = vout_SysCreate;
+ p_vout->p_sys_init = vout_SysInit;
+ p_vout->p_sys_end = vout_SysEnd;
+ p_vout->p_sys_destroy = vout_SysDestroy;
+ p_vout->p_sys_manage = vout_SysManage;
+ p_vout->p_sys_display = vout_SysDisplay;
+}
+
+void intf_GetPlugin( p_intf_thread_t p_intf )
+{
+ p_intf->p_sys_create = intf_SysCreate;
+ p_intf->p_sys_destroy = intf_SysDestroy;
+ p_intf->p_sys_manage = intf_SysManage;
+}
+
NULL, 0,
(void *)&p_intf->p_sys->p_display );
- fprintf(stderr, "display is %i\n", p_intf->p_sys->p_display);
-
if( p_intf->p_vout == NULL ) /* error */
{
intf_ErrMsg("error: can't create video output thread\n" );
}
/* give the data back to the interface */
- fprintf(stderr, "display is %i\n", p_vout->p_sys->p_display);
*(ggi_visual_t *)p_data = p_vout->p_sys->p_display;
/* Find most appropriate mode */
{
/* Get buffer address */
p_vout->p_sys->p_buffer[ i_index ] =
- ggiDBGetBuffer( p_vout->p_sys->p_display, i_index );
+ (ggi_directbuffer *)ggiDBGetBuffer( p_vout->p_sys->p_display, i_index );
if( p_vout->p_sys->p_buffer[ i_index ] == NULL )
{
intf_ErrMsg("error: double buffering is not possible\n");
--- /dev/null
+/*****************************************************************************
+ * glide.c : 3dfx Glide plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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> /* malloc(), free() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "interface.h"
+#include "audio_output.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "plugins_export.h"
+
+/*****************************************************************************
+ * Exported prototypes
+ *****************************************************************************/
+void vout_GetPlugin( p_vout_thread_t p_vout );
+void intf_GetPlugin( p_intf_thread_t p_intf );
+
+/*****************************************************************************
+ * GetConfig: get the plugin structure and configuration
+ *****************************************************************************/
+plugin_info_t * GetConfig( void )
+{
+ plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+
+ p_info->psz_name = "3dfx Glide";
+ p_info->psz_version = VERSION;
+ p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
+
+ p_info->aout_GetPlugin = NULL;
+ p_info->vout_GetPlugin = vout_GetPlugin;
+ p_info->intf_GetPlugin = intf_GetPlugin;
+ p_info->yuv_GetPlugin = NULL;
+
+ return( p_info );
+}
+
+/*****************************************************************************
+ * Test: tests if the plugin can be launched
+ *****************************************************************************/
+int Test( void )
+{
+ /* TODO: detect a 3dfx card */
+ return( 1 );
+}
+
+/*****************************************************************************
+ * Following functions are only called through the p_info structure
+ *****************************************************************************/
+
+void vout_GetPlugin( p_vout_thread_t p_vout )
+{
+ p_vout->p_sys_create = vout_SysCreate;
+ p_vout->p_sys_init = vout_SysInit;
+ p_vout->p_sys_end = vout_SysEnd;
+ p_vout->p_sys_destroy = vout_SysDestroy;
+ p_vout->p_sys_manage = vout_SysManage;
+ p_vout->p_sys_display = vout_SysDisplay;
+}
+
+void intf_GetPlugin( p_intf_thread_t p_intf )
+{
+ p_intf->p_sys_create = intf_SysCreate;
+ p_intf->p_sys_destroy = intf_SysDestroy;
+ p_intf->p_sys_manage = intf_SysManage;
+}
+
--- /dev/null
+/*****************************************************************************
+ * gnome.c : Gnome plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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> /* malloc(), free() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "interface.h"
+#include "audio_output.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "plugins_export.h"
+
+/*****************************************************************************
+ * Exported prototypes
+ *****************************************************************************/
+void vout_GetPlugin( p_vout_thread_t p_vout );
+void intf_GetPlugin( p_intf_thread_t p_intf );
+
+/*****************************************************************************
+ * GetConfig: get the plugin structure and configuration
+ *****************************************************************************/
+plugin_info_t * GetConfig( void )
+{
+ plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+
+ p_info->psz_name = "Gnome";
+ p_info->psz_version = VERSION;
+ p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
+
+ p_info->aout_GetPlugin = NULL;
+ p_info->vout_GetPlugin = vout_GetPlugin;
+ p_info->intf_GetPlugin = intf_GetPlugin;
+ p_info->yuv_GetPlugin = NULL;
+
+ return( p_info );
+}
+
+/*****************************************************************************
+ * Test: tests if the plugin can be launched
+ *****************************************************************************/
+int Test( void )
+{
+ /* TODO: detect an X display or Gnome libs */
+ return( 1 );
+}
+
+/*****************************************************************************
+ * Following functions are only called through the p_info structure
+ *****************************************************************************/
+
+void vout_GetPlugin( p_vout_thread_t p_vout )
+{
+ p_vout->p_sys_create = vout_SysCreate;
+ p_vout->p_sys_init = vout_SysInit;
+ p_vout->p_sys_end = vout_SysEnd;
+ p_vout->p_sys_destroy = vout_SysDestroy;
+ p_vout->p_sys_manage = vout_SysManage;
+ p_vout->p_sys_display = vout_SysDisplay;
+
+ /* optional functions */
+ p_vout->p_set_palette = vout_SetPalette;
+}
+
+void intf_GetPlugin( p_intf_thread_t p_intf )
+{
+ p_intf->p_sys_create = intf_SysCreate;
+ p_intf->p_sys_destroy = intf_SysDestroy;
+ p_intf->p_sys_manage = intf_SysManage;
+}
+
XShmSegmentInfo *p_shm_info );
static void X11DestroyShmImage ( vout_thread_t *p_vout, XImage *p_ximage,
XShmSegmentInfo *p_shm_info );
-static void X11SetPalette ( p_vout_thread_t p_vout,
- u16 *red, u16 *green, u16 *blue, u16 *transp );
/*****************************************************************************
* vout_SysCreate: allocate X11 video thread output method
{
int i_err;
- /* Initialize palette changing procedure */
- p_vout->p_set_palette = X11SetPalette;
-
/* Create XImages using XShm extension - on failure, fall back to regular
* way (and destroy the first image if it was created successfully) */
if( p_vout->p_sys->b_shm )
}
if( i_err ) /* an error occured */
{
- intf_Msg("XShm video sextension desactivated\n" );
+ intf_Msg("XShm video extension deactivated\n" );
p_vout->p_sys->b_shm = 0;
}
}
}
}
+/*****************************************************************************
+ * vout_SetPalette: sets an 8 bpp palette
+ *****************************************************************************
+ * This function sets the palette given as an argument. It does not return
+ * anything, but could later send information on which colors it was unable
+ * to set.
+ *****************************************************************************/
+void vout_SetPalette( p_vout_thread_t p_vout,
+ u16 *red, u16 *green, u16 *blue, u16 *transp )
+{
+ int i;
+ XColor color[255];
+
+ intf_DbgMsg( "Palette change called\n" );
+
+ /* allocate palette */
+ for( i = 0; i < 255; i++ )
+ {
+ /* kludge: colors are indexed reversely because color 255 seems
+ * to be reserved for black even if we try to set it to white */
+ color[i].pixel = 255-i;
+ color[i].pad = 0;
+ color[i].flags = DoRed|DoGreen|DoBlue;
+ color[i].red = red[255-i];
+ color[i].blue = blue[255-i];
+ color[i].green = green[255-i];
+ }
+
+ XStoreColors( p_vout->p_sys->p_display, p_vout->p_sys->colormap, color, 256 );
+}
+
/* following functions are local */
/*****************************************************************************
}
}
-/*****************************************************************************
- * X11SetPalette: sets an 8 bpp palette
- *****************************************************************************
- * This function sets the palette given as an argument. It does not return
- * anything, but could later send information on which colors it was unable
- * to set.
- *****************************************************************************/
-static void X11SetPalette ( p_vout_thread_t p_vout,
- u16 *red, u16 *green, u16 *blue, u16 *transp )
-{
- int i;
- XColor color[255];
-
- intf_DbgMsg( "Palette change called\n" );
-
- /* allocate palette */
- for( i = 0; i < 255; i++ )
- {
- /* kludge: colors are indexed reversely because color 255 seems
- * to be reserved for black even if we try to set it to white */
- color[i].pixel = 255-i;
- color[i].pad = 0;
- color[i].flags = DoRed|DoGreen|DoBlue;
- color[i].red = red[255-i];
- color[i].blue = blue[255-i];
- color[i].green = green[255-i];
- }
-
- XStoreColors( p_vout->p_sys->p_display, p_vout->p_sys->colormap, color, 256 );
-}
--- /dev/null
+/*****************************************************************************
+ * mga.c : Matrox Graphic Array plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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> /* malloc(), free() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "interface.h"
+#include "audio_output.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "plugins_export.h"
+
+/*****************************************************************************
+ * Exported prototypes
+ *****************************************************************************/
+void vout_GetPlugin( p_vout_thread_t p_vout );
+void intf_GetPlugin( p_intf_thread_t p_intf );
+
+/*****************************************************************************
+ * GetConfig: get the plugin structure and configuration
+ *****************************************************************************/
+plugin_info_t * GetConfig( void )
+{
+ plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+
+ p_info->psz_name = "Matrox Acceleration";
+ p_info->psz_version = VERSION;
+ p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
+
+ p_info->aout_GetPlugin = NULL;
+ p_info->vout_GetPlugin = vout_GetPlugin;
+ p_info->intf_GetPlugin = intf_GetPlugin;
+ p_info->yuv_GetPlugin = NULL;
+
+ return( p_info );
+}
+
+/*****************************************************************************
+ * Test: tests if the plugin can be launched
+ *****************************************************************************/
+int Test( void )
+{
+ /* TODO: detect an MGA card ? */
+ return( 1 );
+}
+
+/*****************************************************************************
+ * Following functions are only called through the p_info structure
+ *****************************************************************************/
+
+void vout_GetPlugin( p_vout_thread_t p_vout )
+{
+ p_vout->p_sys_create = vout_SysCreate;
+ p_vout->p_sys_init = vout_SysInit;
+ p_vout->p_sys_end = vout_SysEnd;
+ p_vout->p_sys_destroy = vout_SysDestroy;
+ p_vout->p_sys_manage = vout_SysManage;
+ p_vout->p_sys_display = vout_SysDisplay;
+}
+
+void intf_GetPlugin( p_intf_thread_t p_intf )
+{
+ p_intf->p_sys_create = intf_SysCreate;
+ p_intf->p_sys_destroy = intf_SysDestroy;
+ p_intf->p_sys_manage = intf_SysManage;
+}
+
*****************************************************************************/
int vout_SysInit( vout_thread_t *p_vout )
{
- int i_err, i_dummy;
+ int i_err;
/* create the MGA output */
p_vout->p_sys->p_mga->src_width = p_vout->i_width;
}
if( i_err ) /* an error occured */
{
- intf_Msg("XShm video sextension desactivated\n" );
+ intf_Msg("XShm video sextension deactivated\n" );
p_vout->p_sys->b_shm = 0;
}
}
XShmSegmentInfo *p_shm_info );
static void X11DestroyShmImage ( vout_thread_t *p_vout, XImage *p_ximage,
XShmSegmentInfo *p_shm_info );
-static void X11SetPalette ( p_vout_thread_t p_vout,
- u16 *red, u16 *green, u16 *blue, u16 *transp );
/*****************************************************************************
* vout_SysCreate: allocate X11 video thread output method
{
int i_err;
- /* Initialize palette changing procedure */
- p_vout->p_set_palette = X11SetPalette;
-
/* Create XImages using XShm extension - on failure, fall back to regular
* way (and destroy the first image if it was created successfully) */
if( p_vout->p_sys->b_shm )
}
if( i_err ) /* an error occured */
{
- intf_Msg("XShm video sextension desactivated\n" );
+ intf_Msg("XShm video sextension deactivated\n" );
p_vout->p_sys->b_shm = 0;
}
}
/*
* Color/Grayscale or gamma change: in 8bpp, just change the colormap
*/
- if( (p_vout->i_changes & VOUT_GRAYSCALE_CHANGE) && (p_vout->i_screen_depth == 8) )
+ if( (p_vout->i_changes & VOUT_GRAYSCALE_CHANGE)
+ && (p_vout->i_screen_depth == 8) )
{
/* FIXME: clear flags ?? */
}
}
/* Tell the video output thread that it will need to rebuild YUV
- * tables. This is needed since conversion buffer size may have changed */
+ * tables. This is needed since conversion buffer size may have
+ * changed */
p_vout->i_changes |= VOUT_YUV_CHANGE;
intf_Msg("Video display resized (%dx%d)\n", p_vout->i_width, p_vout->i_height);
}
}
}
+/*****************************************************************************
+ * vout_SetPalette: sets an 8 bpp palette
+ *****************************************************************************
+ * This function sets the palette given as an argument. It does not return
+ * anything, but could later send information on which colors it was unable
+ * to set.
+ *****************************************************************************/
+void vout_SetPalette( p_vout_thread_t p_vout,
+ u16 *red, u16 *green, u16 *blue, u16 *transp )
+{
+ int i;
+ XColor color[255];
+
+ intf_DbgMsg( "Palette change called\n" );
+
+ /* allocate palette */
+ for( i = 0; i < 255; i++ )
+ {
+ /* kludge: colors are indexed reversely because color 255 seems
+ * to be reserved for black even if we try to set it to white */
+ color[i].pixel = 255-i;
+ color[i].pad = 0;
+ color[i].flags = DoRed|DoGreen|DoBlue;
+ color[i].red = red[255-i];
+ color[i].blue = blue[255-i];
+ color[i].green = green[255-i];
+ }
+
+ XStoreColors( p_vout->p_sys->p_display, p_vout->p_sys->colormap, color, 256 );
+}
+
/* following functions are local */
/*****************************************************************************
}
}
-/*****************************************************************************
- * X11SetPalette: sets an 8 bpp palette
- *****************************************************************************
- * This function sets the palette given as an argument. It does not return
- * anything, but could later send information on which colors it was unable
- * to set.
- *****************************************************************************/
-static void X11SetPalette ( p_vout_thread_t p_vout,
- u16 *red, u16 *green, u16 *blue, u16 *transp )
-{
- int i;
- XColor color[255];
-
- intf_DbgMsg( "Palette change called\n" );
-
- /* allocate palette */
- for( i = 0; i < 255; i++ )
- {
- /* kludge: colors are indexed reversely because color 255 seems
- * to be reserved for black even if we try to set it to white */
- color[i].pixel = 255-i;
- color[i].pad = 0;
- color[i].flags = DoRed|DoGreen|DoBlue;
- color[i].red = red[255-i];
- color[i].blue = blue[255-i];
- color[i].green = green[255-i];
- }
-
- XStoreColors( p_vout->p_sys->p_display, p_vout->p_sys->colormap, color, 256 );
-}
--- /dev/null
+/*****************************************************************************
+ * x11.c : X11 plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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> /* malloc(), free() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "interface.h"
+#include "audio_output.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "plugins_export.h"
+
+/*****************************************************************************
+ * Exported prototypes
+ *****************************************************************************/
+void vout_GetPlugin( p_vout_thread_t p_vout );
+void intf_GetPlugin( p_intf_thread_t p_intf );
+
+/*****************************************************************************
+ * GetConfig: get the plugin structure and configuration
+ *****************************************************************************/
+plugin_info_t * GetConfig( void )
+{
+ plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+
+ p_info->psz_name = "X Window System";
+ p_info->psz_version = VERSION;
+ p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
+
+ p_info->aout_GetPlugin = NULL;
+ p_info->vout_GetPlugin = vout_GetPlugin;
+ p_info->intf_GetPlugin = intf_GetPlugin;
+ p_info->yuv_GetPlugin = NULL;
+
+ return( p_info );
+}
+
+/*****************************************************************************
+ * Test: tests if the plugin can be launched
+ *****************************************************************************/
+int Test( void )
+{
+ /* TODO: detect an X display */
+ return( 1 );
+}
+
+/*****************************************************************************
+ * Following functions are only called through the p_info structure
+ *****************************************************************************/
+
+void vout_GetPlugin( p_vout_thread_t p_vout )
+{
+ p_vout->p_sys_create = vout_SysCreate;
+ p_vout->p_sys_init = vout_SysInit;
+ p_vout->p_sys_end = vout_SysEnd;
+ p_vout->p_sys_destroy = vout_SysDestroy;
+ p_vout->p_sys_manage = vout_SysManage;
+ p_vout->p_sys_display = vout_SysDisplay;
+
+ /* optional functions */
+ p_vout->p_set_palette = vout_SetPalette;
+}
+
+void intf_GetPlugin( p_intf_thread_t p_intf )
+{
+ p_intf->p_sys_create = intf_SysCreate;
+ p_intf->p_sys_destroy = intf_SysDestroy;
+ p_intf->p_sys_manage = intf_SysManage;
+}
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv.c: YUV transformation functions
+ * Provides functions to perform the YUV conversion. The functions provided here
+ * are a complete and portable C implementation, and may be replaced in certain
+ * case by optimized functions.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <math.h> /* exp(), pow() */
+#include <errno.h> /* ENOMEM */
+#include <stdlib.h> /* free() */
+#include <string.h> /* strerror() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+#include "video.h"
+#include "video_output.h"
+#include "video_yuv.h"
+
+#include "intf_msg.h"
+
+/*****************************************************************************
+ * Constants
+ *****************************************************************************/
+
+int yuv_SysInit ( vout_thread_t *p_vout );
+int yuv_SysReset ( vout_thread_t *p_vout );
+void yuv_SysEnd ( vout_thread_t *p_vout );
+
+/*****************************************************************************
+ * vout_InitYUV: allocate and initialize translations tables
+ *****************************************************************************
+ * This function will allocate memory to store translation tables, depending
+ * of the screen depth.
+ *****************************************************************************/
+int yuv_SysInit( vout_thread_t *p_vout )
+{
+ size_t tables_size; /* tables size, in bytes */
+
+ /* Computes tables size - 3 Bpp use 32 bits pixel entries in tables */
+ switch( p_vout->i_bytes_per_pixel )
+ {
+ case 1:
+ tables_size = sizeof( u8 )
+ * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : PALETTE_TABLE_SIZE);
+ break;
+ case 2:
+ tables_size = sizeof( u16 )
+ * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
+ break;
+ case 3:
+ case 4:
+ default:
+ tables_size = sizeof( u32 )
+ * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
+ break;
+ }
+
+ /* Allocate memory */
+ p_vout->yuv.p_base = malloc( tables_size );
+ if( p_vout->yuv.p_base == NULL )
+ {
+ intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+ return( 1 );
+ }
+
+ /* Allocate memory for conversion buffer and offset array */
+ p_vout->yuv.p_buffer = malloc( VOUT_MAX_WIDTH * p_vout->i_bytes_per_pixel );
+ if( p_vout->yuv.p_buffer == NULL )
+ {
+ intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+ free( p_vout->yuv.p_base );
+ return( 1 );
+ }
+ p_vout->yuv.p_offset = malloc( p_vout->i_width * sizeof( int ) );
+ if( p_vout->yuv.p_offset == NULL )
+ {
+ intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+ free( p_vout->yuv.p_base );
+ free( p_vout->yuv.p_buffer );
+ return( 1 );
+ }
+
+ /* Initialize tables */
+ SetYUV( p_vout );
+ return( 0 );
+}
+
+/*****************************************************************************
+ * yuv_SysReset: re-initialize translations tables
+ *****************************************************************************
+ * This function will initialize the tables allocated by vout_CreateTables and
+ * set functions pointers.
+ *****************************************************************************/
+int yuv_SysReset( vout_thread_t *p_vout )
+{
+ yuv_SysEnd( p_vout );
+ return( yuv_SysInit( p_vout ) );
+}
+
+/*****************************************************************************
+ * yuv_SysEnd: destroy translations tables
+ *****************************************************************************
+ * Free memory allocated by yuv_SysCreate.
+ *****************************************************************************/
+void yuv_SysEnd( vout_thread_t *p_vout )
+{
+ free( p_vout->yuv.p_base );
+ free( p_vout->yuv.p_buffer );
+ free( p_vout->yuv.p_offset );
+}
+
+/* following functions are local */
+
+/*****************************************************************************
+ * SetGammaTable: return intensity table transformed by gamma curve.
+ *****************************************************************************
+ * pi_table is a table of 256 entries from 0 to 255.
+ *****************************************************************************/
+void SetGammaTable( int *pi_table, double f_gamma )
+{
+ int i_y; /* base intensity */
+
+ /* Use exp(gamma) instead of gamma */
+ f_gamma = exp( f_gamma );
+
+ /* Build gamma table */
+ for( i_y = 0; i_y < 256; i_y++ )
+ {
+ pi_table[ i_y ] = pow( (double)i_y / 256, f_gamma ) * 256;
+ }
+ }
+
+/*****************************************************************************
+ * SetYUV: compute tables and set function pointers
++ *****************************************************************************/
+void SetYUV( vout_thread_t *p_vout )
+{
+ int pi_gamma[256]; /* gamma table */
+ int i_index; /* index in tables */
+
+ /* Build gamma table */
+ SetGammaTable( pi_gamma, p_vout->f_gamma );
+
+ /*
+ * Set pointers and build YUV tables
+ */
+ if( p_vout->b_grayscale )
+ {
+ /* Grayscale: build gray table */
+ switch( p_vout->i_bytes_per_pixel )
+ {
+ case 1:
+ {
+ u16 bright[256], transp[256];
+
+ p_vout->yuv.yuv.p_gray8 = (u8 *)p_vout->yuv.p_base + GRAY_MARGIN;
+ for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_gray8[ -i_index ] = RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
+ p_vout->yuv.yuv.p_gray8[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
+ }
+ for( i_index = 0; i_index < 256; i_index++)
+ {
+ p_vout->yuv.yuv.p_gray8[ i_index ] = pi_gamma[ i_index ];
+ bright[ i_index ] = i_index << 8;
+ transp[ i_index ] = 0;
+ }
+ /* the colors have been allocated, we can set the palette */
+ p_vout->p_set_palette( p_vout, bright, bright, bright, transp );
+ p_vout->i_white_pixel = 0xff;
+ p_vout->i_black_pixel = 0x00;
+ p_vout->i_gray_pixel = 0x44;
+ p_vout->i_blue_pixel = 0x3b;
+
+ break;
+ }
+ case 2:
+ p_vout->yuv.yuv.p_gray16 = (u16 *)p_vout->yuv.p_base + GRAY_MARGIN;
+ for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_gray16[ -i_index ] = RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
+ p_vout->yuv.yuv.p_gray16[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
+ }
+ for( i_index = 0; i_index < 256; i_index++)
+ {
+ p_vout->yuv.yuv.p_gray16[ i_index ] = RGB2PIXEL( p_vout, pi_gamma[i_index], pi_gamma[i_index], pi_gamma[i_index] );
+ }
+ break;
+ case 3:
+ case 4:
+ p_vout->yuv.yuv.p_gray32 = (u32 *)p_vout->yuv.p_base + GRAY_MARGIN;
+ for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_gray32[ -i_index ] = RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
+ p_vout->yuv.yuv.p_gray32[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
+ }
+ for( i_index = 0; i_index < 256; i_index++)
+ {
+ p_vout->yuv.yuv.p_gray32[ i_index ] = RGB2PIXEL( p_vout, pi_gamma[i_index], pi_gamma[i_index], pi_gamma[i_index] );
+ }
+ break;
+ }
+ }
+ else
+ {
+ /* Color: build red, green and blue tables */
+ switch( p_vout->i_bytes_per_pixel )
+ {
+ case 1:
+ {
+ #define RGB_MIN 0
+ #define RGB_MAX 255
+ #define CLIP( x ) ( ((x < 0) ? 0 : (x > 255) ? 255 : x) << 8 )
+
+ int y,u,v;
+ int r,g,b;
+ int uvr, uvg, uvb;
+ int i = 0, j = 0;
+ u16 red[256], green[256], blue[256], transp[256];
+ unsigned char lookup[PALETTE_TABLE_SIZE];
+
+ p_vout->yuv.yuv.p_rgb8 = (u8 *)p_vout->yuv.p_base;
+
+ /* this loop calculates the intersection of an YUV box
+ * and the RGB cube. */
+ for ( y = 0; y <= 256; y += 16 )
+ {
+ for ( u = 0; u <= 256; u += 32 )
+ for ( v = 0; v <= 256; v += 32 )
+ {
+ uvr = (V_RED_COEF*(v-128)) >> SHIFT;
+ uvg = (U_GREEN_COEF*(u-128) + V_GREEN_COEF*(v-128)) >> SHIFT;
+ uvb = (U_BLUE_COEF*(u-128)) >> SHIFT;
+ r = y + uvr;
+ g = y + uvg;
+ b = y + uvb;
+
+ if( r >= RGB_MIN && g >= RGB_MIN && b >= RGB_MIN
+ && r <= RGB_MAX && g <= RGB_MAX && b <= RGB_MAX )
+ {
+ /* this one should never happen unless someone fscked up my code */
+ if(j == 256) { intf_ErrMsg( "vout error: no colors left to build palette\n" ); break; }
+
+ /* clip the colors */
+ red[j] = CLIP( r );
+ green[j] = CLIP( g );
+ blue[j] = CLIP( b );
+ transp[j] = 0;
+
+ /* allocate color */
+ lookup[i] = 1;
+ p_vout->yuv.yuv.p_rgb8[i++] = j;
+ j++;
+ }
+ else
+ {
+ lookup[i] = 0;
+ p_vout->yuv.yuv.p_rgb8[i++] = 0;
+ }
+ }
+ i += 128-81;
+ }
+
+ /* the colors have been allocated, we can set the palette */
+ /* there will eventually be a way to know which colors
+ * couldn't be allocated and try to find a replacement */
+ p_vout->p_set_palette( p_vout, red, green, blue, transp );
+
+ p_vout->i_white_pixel = 0xff;
+ p_vout->i_black_pixel = 0x00;
+ p_vout->i_gray_pixel = 0x44;
+ p_vout->i_blue_pixel = 0x3b;
+
+ i = 0;
+ /* this loop allocates colors that got outside
+ * the RGB cube */
+ for ( y = 0; y <= 256; y += 16 )
+ {
+ for ( u = 0; u <= 256; u += 32 )
+ for ( v = 0; v <= 256; v += 32 )
+ {
+ int u2, v2;
+ int dist, mindist = 100000000;
+
+ if( lookup[i] || y==0)
+ {
+ i++;
+ continue;
+ }
+
+ /* heavy. yeah. */
+ for( u2 = 0; u2 <= 256; u2 += 32 )
+ for( v2 = 0; v2 <= 256; v2 += 32 )
+ {
+ j = ((y>>4)<<7) + (u2>>5)*9 + (v2>>5);
+ dist = (u-u2)*(u-u2) + (v-v2)*(v-v2);
+ if( lookup[j] )
+ /* find the nearest color */
+ if( dist < mindist )
+ {
+ p_vout->yuv.yuv.p_rgb8[i] = p_vout->yuv.yuv.p_rgb8[j];
+ mindist = dist;
+ }
+ j -= 128;
+ if( lookup[j] )
+ /* find the nearest color */
+ if( dist + 128 < mindist )
+ {
+ p_vout->yuv.yuv.p_rgb8[i] = p_vout->yuv.yuv.p_rgb8[j];
+ mindist = dist + 128;
+ }
+ }
+ i++;
+ }
+ i += 128-81;
+ }
+
+ break;
+ }
+ case 2:
+ p_vout->yuv.yuv.p_rgb16 = (u16 *)p_vout->yuv.p_base;
+ for( i_index = 0; i_index < RED_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb16[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
+ p_vout->yuv.yuv.p_rgb16[RED_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
+ }
+ for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
+ p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
+ }
+ for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
+ p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
+ }
+ for( i_index = 0; i_index < 256; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb16[RED_OFFSET + i_index] = RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
+ p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
+ p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] );
+ }
+ break;
+ case 3:
+ case 4:
+ p_vout->yuv.yuv.p_rgb32 = (u32 *)p_vout->yuv.p_base;
+ for( i_index = 0; i_index < RED_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb32[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
+ p_vout->yuv.yuv.p_rgb32[RED_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
+ }
+ for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
+ p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
+ }
+ for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
+ p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
+ }
+ for( i_index = 0; i_index < 256; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb32[RED_OFFSET + i_index] = RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
+ p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
+ p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] );
+ }
+ break;
+ }
+ }
+
+ /*
+ * Set functions pointers
+ */
+ if( p_vout->b_grayscale )
+ {
+ /* Grayscale */
+ switch( p_vout->i_bytes_per_pixel )
+ {
+ case 1:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray8;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray8;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray8;
+ break;
+ case 2:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray16;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray16;
+ break;
+ case 3:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray24;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray24;
+ break;
+ case 4:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray32;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray32;
+ break;
+ }
+ }
+ else
+ {
+ /* Color */
+ switch( p_vout->i_bytes_per_pixel )
+ {
+ case 1:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB8;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB8;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB8;
+ break;
+ case 2:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB16;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB16;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB16;
+ break;
+ case 3:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB24;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB24;
+ break;
+ case 4:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB32;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB32;
+ break;
+ }
+ }
+}
+
+/*****************************************************************************
+ * SetOffset: build offset array for conversion functions
+ *****************************************************************************
+ * This function will build an offset array used in later conversion functions.
+ * It will also set horizontal and vertical scaling indicators.
+ *****************************************************************************/
+void SetOffset( int i_width, int i_height, int i_pic_width, int i_pic_height,
+ boolean_t *pb_h_scaling, int *pi_v_scaling, int *p_offset )
+{
+ int i_x; /* x position in destination */
+ int i_scale_count; /* modulo counter */
+
+ /*
+ * Prepare horizontal offset array
+ */
+ if( i_pic_width - i_width > 0 )
+ {
+ /* Prepare scaling array for horizontal extension */
+ *pb_h_scaling = 1;
+ i_scale_count = i_pic_width;
+ for( i_x = i_width; i_x--; )
+ {
+ while( (i_scale_count -= i_width) > 0 )
+ {
+ *p_offset++ = 0;
+ }
+ *p_offset++ = 1;
+ i_scale_count += i_pic_width;
+ }
+ }
+ else if( i_pic_width - i_width < 0 )
+ {
+ /* Prepare scaling array for horizontal reduction */
+ *pb_h_scaling = 1;
+ i_scale_count = i_pic_width;
+ for( i_x = i_pic_width; i_x--; )
+ {
+ *p_offset = 1;
+ while( (i_scale_count -= i_pic_width) >= 0 )
+ {
+ *p_offset += 1;
+ }
+ p_offset++;
+ i_scale_count += i_width;
+ }
+ }
+ else
+ {
+ /* No horizontal scaling: YUV conversion is done directly to picture */
+ *pb_h_scaling = 0;
+ }
+
+ /*
+ * Set vertical scaling indicator
+ */
+ if( i_pic_height - i_height > 0 )
+ {
+ *pi_v_scaling = 1;
+ }
+ else if( i_pic_height - i_height < 0 )
+ {
+ *pi_v_scaling = -1;
+ }
+ else
+ {
+ *pi_v_scaling = 0;
+ }
+}
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv.h: YUV transformation functions
+ * Provides functions to perform the YUV conversion. The functions provided here
+ * are a complete and portable C implementation, and may be replaced in certain
+ * case by optimized functions.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Constants
+ *****************************************************************************/
+
+/* Margins and offsets in conversion tables - Margins are used in case a RGB
+ * RGB conversion would give a value outside the 0-255 range. Offsets have been
+ * calculated to avoid using the same cache line for 2 tables. conversion tables
+ * are 2*MARGIN + 256 long and stores pixels.*/
+#define RED_MARGIN 178
+#define GREEN_MARGIN 135
+#define BLUE_MARGIN 224
+#define RED_OFFSET 1501 /* 1323 to 1935 */
+#define GREEN_OFFSET 135 /* 0 to 526 */
+#define BLUE_OFFSET 818 /* 594 to 1298 */
+#define RGB_TABLE_SIZE 1935 /* total table size */
+
+#define GRAY_MARGIN 384
+#define GRAY_TABLE_SIZE 1024 /* total table size */
+
+#define PALETTE_TABLE_SIZE 2176 /* YUV -> 8bpp palette lookup table */
+
+/* macros used for YUV pixel conversions */
+#define SHIFT 20
+#define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
+#define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
+#define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
+#define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
+
+/* argument lists for YUV functions */
+#define YUV_ARGS_8BPP p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, \
+yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, \
+int i_pic_height, int i_pic_line_width, int i_matrix_coefficients
+
+#define YUV_ARGS_16BPP p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, \
+yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, \
+int i_pic_height, int i_pic_line_width, int i_matrix_coefficients
+
+#define YUV_ARGS_24BPP p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, \
+yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, \
+int i_pic_height, int i_pic_line_width, int i_matrix_coefficients
+
+#define YUV_ARGS_32BPP p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, \
+yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, \
+int i_pic_height, int i_pic_line_width, int i_matrix_coefficients
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+void SetGammaTable ( int *pi_table, double f_gamma );
+void SetYUV ( vout_thread_t *p_vout );
+void SetOffset ( int i_width, int i_height, int i_pic_width,
+ int i_pic_height, boolean_t *pb_h_scaling,
+ int *pi_v_scaling, int *p_offset );
+
+void ConvertY4Gray8 ( YUV_ARGS_8BPP );
+void ConvertYUV420RGB8 ( YUV_ARGS_8BPP );
+void ConvertYUV422RGB8 ( YUV_ARGS_8BPP );
+void ConvertYUV444RGB8 ( YUV_ARGS_8BPP );
+
+void ConvertY4Gray16 ( YUV_ARGS_16BPP );
+void ConvertYUV420RGB16 ( YUV_ARGS_16BPP );
+void ConvertYUV422RGB16 ( YUV_ARGS_16BPP );
+void ConvertYUV444RGB16 ( YUV_ARGS_16BPP );
+
+void ConvertY4Gray24 ( YUV_ARGS_24BPP );
+void ConvertYUV420RGB24 ( YUV_ARGS_24BPP );
+void ConvertYUV422RGB24 ( YUV_ARGS_24BPP );
+void ConvertYUV444RGB24 ( YUV_ARGS_24BPP );
+
+void ConvertY4Gray32 ( YUV_ARGS_32BPP );
+void ConvertYUV420RGB32 ( YUV_ARGS_32BPP );
+void ConvertYUV422RGB32 ( YUV_ARGS_32BPP );
+void ConvertYUV444RGB32 ( YUV_ARGS_32BPP );
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv16.c: YUV transformation functions for 16bpp
+ * Provides functions to perform the YUV conversion. The functions provided here
+ * are a complete and portable C implementation, and may be replaced in certain
+ * case by optimized functions.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <math.h> /* exp(), pow() */
+#include <errno.h> /* ENOMEM */
+#include <stdlib.h> /* free() */
+#include <string.h> /* strerror() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+#include "video.h"
+#include "video_output.h"
+#include "video_yuv.h"
+#include "video_yuv_macros.h"
+
+#include "intf_msg.h"
+
+/*****************************************************************************
+ * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertY4Gray16( YUV_ARGS_16BPP )
+{
+ boolean_t b_horizontal_scaling; /* horizontal scaling type */
+ int i_vertical_scaling; /* vertical scaling type */
+ int i_x, i_y; /* horizontal and vertical indexes */
+ int i_scale_count; /* scale modulo counter */
+ int i_chroma_width; /* chroma width, not used */
+ u16 * p_gray; /* base conversion table */
+ u16 * p_pic_start; /* beginning of the current line for copy */
+ u16 * p_buffer_start; /* conversion buffer start */
+ u16 * p_buffer; /* conversion buffer pointer */
+ int * p_offset_start; /* offset array start */
+ int * p_offset; /* offset array pointer */
+
+ /*
+ * Initialize some values - i_pic_line_width will store the line skip
+ */
+ i_pic_line_width -= i_pic_width;
+ p_gray = p_vout->yuv.yuv.p_gray16;
+ p_buffer_start = p_vout->yuv.p_buffer;
+ p_offset_start = p_vout->yuv.p_offset;
+ SetOffset( i_width, i_height, i_pic_width, i_pic_height,
+ &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
+
+ /*
+ * Perform conversion
+ */
+ i_scale_count = i_pic_height;
+ for( i_y = 0; i_y < i_height; i_y++ )
+ {
+ /* Mark beginnning of line for possible later line copy, and initialize
+ * buffer */
+ p_pic_start = p_pic;
+ p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
+
+ /* Do YUV conversion to buffer - YUV picture is always formed of 16
+ * pixels wide blocks */
+ for( i_x = i_width / 16; i_x--; )
+ {
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ }
+
+ /* Do horizontal and vertical scaling */
+ SCALE_WIDTH;
+ SCALE_HEIGHT(400, 2);
+ }
+}
+
+/*****************************************************************************
+ * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertYUV420RGB16( YUV_ARGS_16BPP )
+{
+ boolean_t b_horizontal_scaling; /* horizontal scaling type */
+ int i_vertical_scaling; /* vertical scaling type */
+ int i_x, i_y; /* horizontal and vertical indexes */
+ int i_scale_count; /* scale modulo counter */
+ int i_uval, i_vval; /* U and V samples */
+ int i_red, i_green, i_blue; /* U and V modified samples */
+ int i_chroma_width; /* chroma width */
+ u16 * p_yuv; /* base conversion table */
+ u16 * p_ybase; /* Y dependant conversion table */
+ u16 * p_pic_start; /* beginning of the current line for copy */
+ u16 * p_buffer_start; /* conversion buffer start */
+ u16 * p_buffer; /* conversion buffer pointer */
+ int * p_offset_start; /* offset array start */
+ int * p_offset; /* offset array pointer */
+
+ /*
+ * Initialize some values - i_pic_line_width will store the line skip
+ */
+ i_pic_line_width -= i_pic_width;
+ i_chroma_width = i_width / 2;
+ p_yuv = p_vout->yuv.yuv.p_rgb16;
+ p_buffer_start = p_vout->yuv.p_buffer;
+ p_offset_start = p_vout->yuv.p_offset;
+ SetOffset( i_width, i_height, i_pic_width, i_pic_height,
+ &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
+
+ /*
+ * Perform conversion
+ */
+ i_scale_count = i_pic_height;
+ for( i_y = 0; i_y < i_height; i_y++ )
+ {
+ /* Mark beginnning of line for possible later line copy, and initialize
+ * buffer */
+ p_pic_start = p_pic;
+ p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
+
+ /* Do YUV conversion to buffer - YUV picture is always formed of 16
+ * pixels wide blocks */
+ for( i_x = i_width / 16; i_x--; )
+ {
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ }
+
+ /* Do horizontal and vertical scaling */
+ SCALE_WIDTH;
+ SCALE_HEIGHT(420, 2);
+ }
+}
+
+/*****************************************************************************
+ * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertYUV422RGB16( YUV_ARGS_16BPP )
+{
+ boolean_t b_horizontal_scaling; /* horizontal scaling type */
+ int i_vertical_scaling; /* vertical scaling type */
+ int i_x, i_y; /* horizontal and vertical indexes */
+ int i_scale_count; /* scale modulo counter */
+ int i_uval, i_vval; /* U and V samples */
+ int i_red, i_green, i_blue; /* U and V modified samples */
+ int i_chroma_width; /* chroma width */
+ u16 * p_yuv; /* base conversion table */
+ u16 * p_ybase; /* Y dependant conversion table */
+ u16 * p_pic_start; /* beginning of the current line for copy */
+ u16 * p_buffer_start; /* conversion buffer start */
+ u16 * p_buffer; /* conversion buffer pointer */
+ int * p_offset_start; /* offset array start */
+ int * p_offset; /* offset array pointer */
+
+ /*
+ * Initialize some values - i_pic_line_width will store the line skip
+ */
+ i_pic_line_width -= i_pic_width;
+ i_chroma_width = i_width / 2;
+ p_yuv = p_vout->yuv.yuv.p_rgb16;
+ p_buffer_start = p_vout->yuv.p_buffer;
+ p_offset_start = p_vout->yuv.p_offset;
+ SetOffset( i_width, i_height, i_pic_width, i_pic_height,
+ &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
+
+ /*
+ * Perform conversion
+ */
+ i_scale_count = i_pic_height;
+ for( i_y = 0; i_y < i_height; i_y++ )
+ {
+ /* Mark beginnning of line for possible later line copy, and initialize
+ * buffer */
+ p_pic_start = p_pic;
+ p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
+
+ /* Do YUV conversion to buffer - YUV picture is always formed of 16
+ * pixels wide blocks */
+ for( i_x = i_width / 16; i_x--; )
+ {
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
+ }
+
+ /* Do horizontal and vertical scaling */
+ SCALE_WIDTH;
+ SCALE_HEIGHT(422, 2);
+ }
+}
+
+/*****************************************************************************
+ * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertYUV444RGB16( YUV_ARGS_16BPP )
+{
+ boolean_t b_horizontal_scaling; /* horizontal scaling type */
+ int i_vertical_scaling; /* vertical scaling type */
+ int i_x, i_y; /* horizontal and vertical indexes */
+ int i_scale_count; /* scale modulo counter */
+ int i_uval, i_vval; /* U and V samples */
+ int i_red, i_green, i_blue; /* U and V modified samples */
+ int i_chroma_width; /* chroma width, not used */
+ u16 * p_yuv; /* base conversion table */
+ u16 * p_ybase; /* Y dependant conversion table */
+ u16 * p_pic_start; /* beginning of the current line for copy */
+ u16 * p_buffer_start; /* conversion buffer start */
+ u16 * p_buffer; /* conversion buffer pointer */
+ int * p_offset_start; /* offset array start */
+ int * p_offset; /* offset array pointer */
+
+ /*
+ * Initialize some values - i_pic_line_width will store the line skip
+ */
+ i_pic_line_width -= i_pic_width;
+ p_yuv = p_vout->yuv.yuv.p_rgb16;
+ p_buffer_start = p_vout->yuv.p_buffer;
+ p_offset_start = p_vout->yuv.p_offset;
+ SetOffset( i_width, i_height, i_pic_width, i_pic_height,
+ &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
+
+ /*
+ * Perform conversion
+ */
+ i_scale_count = i_pic_height;
+ for( i_y = 0; i_y < i_height; i_y++ )
+ {
+ /* Mark beginnning of line for possible later line copy, and initialize
+ * buffer */
+ p_pic_start = p_pic;
+ p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
+
+ /* Do YUV conversion to buffer - YUV picture is always formed of 16
+ * pixels wide blocks */
+ for( i_x = i_width / 16; i_x--; )
+ {
+ CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
+ CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
+ }
+
+ /* Do horizontal and vertical scaling */
+ SCALE_WIDTH;
+ SCALE_HEIGHT(444, 2);
+ }
+}
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv24.c: YUV transformation functions for 24 bpp
+ * Provides functions to perform the YUV conversion. The functions provided here
+ * are a complete and portable C implementation, and may be replaced in certain
+ * case by optimized functions.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <math.h> /* exp(), pow() */
+#include <errno.h> /* ENOMEM */
+#include <stdlib.h> /* free() */
+#include <string.h> /* strerror() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+#include "video.h"
+#include "video_output.h"
+#include "video_yuv.h"
+#include "video_yuv_macros.h"
+
+#include "intf_msg.h"
+
+/*****************************************************************************
+ * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertY4Gray24( YUV_ARGS_24BPP )
+{
+ intf_ErrMsg( "yuv error: unhandled function, grayscale, bpp = 24\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertYUV420RGB24( YUV_ARGS_24BPP )
+{
+ intf_ErrMsg( "yuv error: unhandled function, chroma = 420, bpp = 24\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertYUV422RGB24( YUV_ARGS_24BPP )
+{
+ intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 24\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertYUV444RGB24( YUV_ARGS_24BPP )
+{
+ intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 24\n" );
+}
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv32.c: YUV transformation functions for 32 bpp
+ * Provides functions to perform the YUV conversion. The functions provided here
+ * are a complete and portable C implementation, and may be replaced in certain
+ * case by optimized functions.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <math.h> /* exp(), pow() */
+#include <errno.h> /* ENOMEM */
+#include <stdlib.h> /* free() */
+#include <string.h> /* strerror() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+#include "video.h"
+#include "video_output.h"
+#include "video_yuv.h"
+#include "video_yuv_macros.h"
+
+#include "intf_msg.h"
+
+/*****************************************************************************
+ * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
+ *****************************************************************************/
+void ConvertY4Gray32( YUV_ARGS_32BPP )
+{
+ boolean_t b_horizontal_scaling; /* horizontal scaling type */
+ int i_vertical_scaling; /* vertical scaling type */
+ int i_x, i_y; /* horizontal and vertical indexes */
+ int i_scale_count; /* scale modulo counter */
+ int i_chroma_width; /* chroma width, not used */
+ u32 * p_gray; /* base conversion table */
+ u32 * p_pic_start; /* beginning of the current line for copy */
+ u32 * p_buffer_start; /* conversion buffer start */
+ u32 * p_buffer; /* conversion buffer pointer */
+ int * p_offset_start; /* offset array start */
+ int * p_offset; /* offset array pointer */
+
+ /*
+ * Initialize some values - i_pic_line_width will store the line skip
+ */
+ i_pic_line_width -= i_pic_width;
+ p_gray = p_vout->yuv.yuv.p_gray32;
+ p_buffer_start = p_vout->yuv.p_buffer;
+ p_offset_start = p_vout->yuv.p_offset;
+ SetOffset( i_width, i_height, i_pic_width, i_pic_height,
+ &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
+
+ /*
+ * Perform conversion
+ */
+ i_scale_count = i_pic_height;
+ for( i_y = 0; i_y < i_height; i_y++ )
+ {
+ /* Mark beginnning of line for possible later line copy, and initialize
+ * buffer */
+ p_pic_start = p_pic;
+ p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
+
+ /* Do YUV conversion to buffer - YUV picture is always formed of 16
+ * pixels wide blocks */
+ for( i_x = i_width / 16; i_x--; )
+ {
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ }
+
+ /* Do horizontal and vertical scaling */
+ SCALE_WIDTH;
+ SCALE_HEIGHT(400, 4);
+ }
+}
+
+/*****************************************************************************
+ * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
+ *****************************************************************************/
+void ConvertYUV420RGB32( YUV_ARGS_32BPP )
+{
+ boolean_t b_horizontal_scaling; /* horizontal scaling type */
+ int i_vertical_scaling; /* vertical scaling type */
+ int i_x, i_y; /* horizontal and vertical indexes */
+ int i_scale_count; /* scale modulo counter */
+ int i_uval, i_vval; /* U and V samples */
+ int i_red, i_green, i_blue; /* U and V modified samples */
+ int i_chroma_width; /* chroma width */
+ u32 * p_yuv; /* base conversion table */
+ u32 * p_ybase; /* Y dependant conversion table */
+ u32 * p_pic_start; /* beginning of the current line for copy */
+ u32 * p_buffer_start; /* conversion buffer start */
+ u32 * p_buffer; /* conversion buffer pointer */
+ int * p_offset_start; /* offset array start */
+ int * p_offset; /* offset array pointer */
+
+ /*
+ * Initialize some values - i_pic_line_width will store the line skip
+ */
+ i_pic_line_width -= i_pic_width;
+ i_chroma_width = i_width / 2;
+ p_yuv = p_vout->yuv.yuv.p_rgb32;
+ p_buffer_start = p_vout->yuv.p_buffer;
+ p_offset_start = p_vout->yuv.p_offset;
+ SetOffset( i_width, i_height, i_pic_width, i_pic_height,
+ &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
+
+ /*
+ * Perform conversion
+ */
+ i_scale_count = i_pic_height;
+ for( i_y = 0; i_y < i_height; i_y++ )
+ {
+ /* Mark beginnning of line for possible later line copy, and initialize
+ * buffer */
+ p_pic_start = p_pic;
+ p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
+
+ /* Do YUV conversion to buffer - YUV picture is always formed of 16
+ * pixels wide blocks */
+ for( i_x = i_width / 16; i_x--; )
+ {
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ }
+
+ /* Do horizontal and vertical scaling */
+ SCALE_WIDTH;
+ SCALE_HEIGHT(420, 4);
+ }
+}
+
+/*****************************************************************************
+ * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
+ *****************************************************************************/
+void ConvertYUV422RGB32( YUV_ARGS_32BPP )
+{
+ boolean_t b_horizontal_scaling; /* horizontal scaling type */
+ int i_vertical_scaling; /* vertical scaling type */
+ int i_x, i_y; /* horizontal and vertical indexes */
+ int i_scale_count; /* scale modulo counter */
+ int i_uval, i_vval; /* U and V samples */
+ int i_red, i_green, i_blue; /* U and V modified samples */
+ int i_chroma_width; /* chroma width */
+ u32 * p_yuv; /* base conversion table */
+ u32 * p_ybase; /* Y dependant conversion table */
+ u32 * p_pic_start; /* beginning of the current line for copy */
+ u32 * p_buffer_start; /* conversion buffer start */
+ u32 * p_buffer; /* conversion buffer pointer */
+ int * p_offset_start; /* offset array start */
+ int * p_offset; /* offset array pointer */
+
+ /*
+ * Initialize some values - i_pic_line_width will store the line skip
+ */
+ i_pic_line_width -= i_pic_width;
+ i_chroma_width = i_width / 2;
+ p_yuv = p_vout->yuv.yuv.p_rgb32;
+ p_buffer_start = p_vout->yuv.p_buffer;
+ p_offset_start = p_vout->yuv.p_offset;
+ SetOffset( i_width, i_height, i_pic_width, i_pic_height,
+ &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
+
+ /*
+ * Perform conversion
+ */
+ i_scale_count = i_pic_height;
+ for( i_y = 0; i_y < i_height; i_y++ )
+ {
+ /* Mark beginnning of line for possible later line copy, and initialize
+ * buffer */
+ p_pic_start = p_pic;
+ p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
+
+ /* Do YUV conversion to buffer - YUV picture is always formed of 16
+ * pixels wide blocks */
+ for( i_x = i_width / 16; i_x--; )
+ {
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
+ }
+
+ /* Do horizontal and vertical scaling */
+ SCALE_WIDTH;
+ SCALE_HEIGHT(422, 4);
+ }
+}
+
+/*****************************************************************************
+ * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
+ *****************************************************************************/
+void ConvertYUV444RGB32( YUV_ARGS_32BPP )
+{
+ boolean_t b_horizontal_scaling; /* horizontal scaling type */
+ int i_vertical_scaling; /* vertical scaling type */
+ int i_x, i_y; /* horizontal and vertical indexes */
+ int i_scale_count; /* scale modulo counter */
+ int i_uval, i_vval; /* U and V samples */
+ int i_red, i_green, i_blue; /* U and V modified samples */
+ int i_chroma_width; /* chroma width, not used */
+ u32 * p_yuv; /* base conversion table */
+ u32 * p_ybase; /* Y dependant conversion table */
+ u32 * p_pic_start; /* beginning of the current line for copy */
+ u32 * p_buffer_start; /* conversion buffer start */
+ u32 * p_buffer; /* conversion buffer pointer */
+ int * p_offset_start; /* offset array start */
+ int * p_offset; /* offset array pointer */
+
+ /*
+ * Initialize some values - i_pic_line_width will store the line skip
+ */
+ i_pic_line_width -= i_pic_width;
+ p_yuv = p_vout->yuv.yuv.p_rgb32;
+ p_buffer_start = p_vout->yuv.p_buffer;
+ p_offset_start = p_vout->yuv.p_offset;
+ SetOffset( i_width, i_height, i_pic_width, i_pic_height,
+ &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
+
+ /*
+ * Perform conversion
+ */
+ i_scale_count = i_pic_height;
+ for( i_y = 0; i_y < i_height; i_y++ )
+ {
+ /* Mark beginnning of line for possible later line copy, and initialize
+ * buffer */
+ p_pic_start = p_pic;
+ p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
+
+ /* Do YUV conversion to buffer - YUV picture is always formed of 16
+ * pixels wide blocks */
+ for( i_x = i_width / 16; i_x--; )
+ {
+ CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
+ CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
+ }
+
+ /* Do horizontal and vertical scaling */
+ SCALE_WIDTH;
+ SCALE_HEIGHT(444, 4);
+ }
+}
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv8.c: YUV transformation functions for 8bpp
+ * Provides functions to perform the YUV conversion. The functions provided here
+ * are a complete and portable C implementation, and may be replaced in certain
+ * case by optimized functions.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <math.h> /* exp(), pow() */
+#include <errno.h> /* ENOMEM */
+#include <stdlib.h> /* free() */
+#include <string.h> /* strerror() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+#include "video.h"
+#include "video_output.h"
+#include "video_yuv.h"
+#include "video_yuv_macros.h"
+#include "video_yuv_macros_8bpp.h"
+
+#include "intf_msg.h"
+
+/*****************************************************************************
+ * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
+ *****************************************************************************/
+void ConvertY4Gray8( YUV_ARGS_8BPP )
+{
+ boolean_t b_horizontal_scaling; /* horizontal scaling type */
+ int i_vertical_scaling; /* vertical scaling type */
+ int i_x, i_y; /* horizontal and vertical indexes */
+ int i_scale_count; /* scale modulo counter */
+ int i_chroma_width; /* chroma width, not used */
+ u8 * p_gray; /* base conversion table */
+ u8 * p_pic_start; /* beginning of the current line for copy */
+ u8 * p_buffer_start; /* conversion buffer start */
+ u8 * p_buffer; /* conversion buffer pointer */
+ int * p_offset_start; /* offset array start */
+ int * p_offset; /* offset array pointer */
+
+ /*
+ * Initialize some values - i_pic_line_width will store the line skip
+ */
+ i_pic_line_width -= i_pic_width;
+ p_gray = p_vout->yuv.yuv.p_gray8;
+ p_buffer_start = p_vout->yuv.p_buffer;
+ p_offset_start = p_vout->yuv.p_offset;
+ SetOffset( i_width, i_height, i_pic_width, i_pic_height,
+ &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
+
+ /*
+ * Perform conversion
+ */
+ i_scale_count = i_pic_height;
+ for( i_y = 0; i_y < i_height; i_y++ )
+ {
+ /* Mark beginnning of line for possible later line copy, and initialize
+ * buffer */
+ p_pic_start = p_pic;
+ p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
+
+ /* Do YUV conversion to buffer - YUV picture is always formed of 16
+ * pixels wide blocks */
+ for( i_x = i_width / 16; i_x--; )
+ {
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
+ }
+
+ /* Do horizontal and vertical scaling */
+ SCALE_WIDTH;
+ SCALE_HEIGHT(400, 1);
+ }
+}
+
+/*****************************************************************************
+ * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
+ *****************************************************************************/
+void ConvertYUV420RGB8( YUV_ARGS_8BPP )
+{
+ boolean_t b_horizontal_scaling; /* horizontal scaling type */
+ int i_vertical_scaling; /* vertical scaling type */
+ int i_x, i_y; /* horizontal and vertical indexes */
+ int i_scale_count; /* scale modulo counter */
+ int b_jump_uv; /* should we jump u and v ? */
+ int i_real_y; /* y % 4 */
+ u8 * p_lookup; /* lookup table */
+ int i_chroma_width; /* chroma width */
+ int * p_offset_start; /* offset array start */
+ int * p_offset; /* offset array pointer */
+
+ /*
+ * The dither matrices
+ */
+ int dither10[4] = { 0x0, 0x8, 0x2, 0xa };
+ int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
+ int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
+ int dither13[4] = { 0xf, 0x7, 0xd, 0x5 };
+
+ int dither20[4] = { 0x0, 0x10, 0x4, 0x14 };
+ int dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
+ int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
+ int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
+
+ return;
+ /*
+ * Initialize some values - i_pic_line_width will store the line skip
+ */
+ i_pic_line_width -= i_pic_width;
+ i_chroma_width = i_width / 2;
+ p_offset_start = p_vout->yuv.p_offset;
+ p_lookup = p_vout->yuv.p_base;
+ SetOffset( i_width, i_height, i_pic_width, i_pic_height,
+ &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
+
+ /*
+ * Perform conversion
+ */
+ i_scale_count = i_pic_height;
+ i_real_y = 0;
+ for( i_y = 0; i_y < i_height; i_y++ )
+ {
+ /* Do horizontal and vertical scaling */
+ SCALE_WIDTH_DITHER( 420 );
+ SCALE_HEIGHT_DITHER( 420 );
+ }
+}
+
+/*****************************************************************************
+ * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
+ *****************************************************************************/
+void ConvertYUV422RGB8( YUV_ARGS_8BPP )
+{
+ intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 8\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
+ *****************************************************************************/
+void ConvertYUV444RGB8( YUV_ARGS_8BPP )
+{
+ intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 8\n" );
+}
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv_macros_truecolor.h: YUV transformation macros for truecolor
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * CONVERT_YUV_PIXEL, CONVERT_Y_PIXEL: pixel conversion blocks
+ *****************************************************************************
+ * These conversion routines are used by YUV conversion functions.
+ * conversion are made from p_y, p_u, p_v, which are modified, to p_buffer,
+ * which is also modified.
+ *****************************************************************************/
+#define CONVERT_Y_PIXEL( BPP ) \
+ /* Only Y sample is present */ \
+ p_ybase = p_yuv + *p_y++; \
+ *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] | \
+ p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) \
+ + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];
+
+#define CONVERT_YUV_PIXEL( BPP ) \
+ /* Y, U and V samples are present */ \
+ i_uval = *p_u++; \
+ i_vval = *p_v++; \
+ i_red = (V_RED_COEF * i_vval) >> SHIFT; \
+ i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \
+ i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
+ CONVERT_Y_PIXEL( BPP ) \
+
+/*****************************************************************************
+ * SCALE_WIDTH: scale a line horizontally
+ *****************************************************************************
+ * This macro scales a line using rendering buffer and offset array. It works
+ * for 1, 2 and 4 Bpp.
+ *****************************************************************************/
+#define SCALE_WIDTH \
+ if( b_horizontal_scaling ) \
+ { \
+ /* Horizontal scaling, conversion has been done to buffer. \
+ * Rewind buffer and offset, then copy and scale line */ \
+ p_buffer = p_buffer_start; \
+ p_offset = p_offset_start; \
+ for( i_x = i_pic_width / 16; i_x--; ) \
+ { \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ } \
+ p_pic += i_pic_line_width; \
+ } \
+ else \
+ { \
+ /* No scaling, conversion has been done directly in picture memory. \
+ * Increment of picture pointer to end of line is still needed */ \
+ p_pic += i_pic_width + i_pic_line_width; \
+ } \
+
+/*****************************************************************************
+ * SCALE_HEIGHT: handle vertical scaling
+ *****************************************************************************
+ * This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
+ * 444 for RGB conversion, or 400 for gray conversion. It works for 1, 2, 3
+ * and 4 Bpp.
+ *****************************************************************************/
+#define SCALE_HEIGHT( CHROMA, BPP ) \
+ /* If line is odd, rewind 4:2:0 U and V samples */ \
+ if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
+ { \
+ p_u -= i_chroma_width; \
+ p_v -= i_chroma_width; \
+ } \
+ \
+ /* \
+ * Handle vertical scaling. The current line can be copied or next one \
+ * can be ignored. \
+ */ \
+ switch( i_vertical_scaling ) \
+ { \
+ case -1: /* vertical scaling factor is < 1 */ \
+ while( (i_scale_count -= i_pic_height) >= 0 ) \
+ { \
+ /* Height reduction: skip next source line */ \
+ p_y += i_width; \
+ i_y++; \
+ if( (CHROMA == 420) || (CHROMA == 422) ) \
+ { \
+ if( i_y & 0x1 ) \
+ { \
+ p_u += i_chroma_width; \
+ p_v += i_chroma_width; \
+ } \
+ } \
+ else if( CHROMA == 444 ) \
+ { \
+ p_u += i_width; \
+ p_v += i_width; \
+ } \
+ } \
+ i_scale_count += i_height; \
+ break; \
+ case 1: /* vertical scaling factor is > 1 */ \
+ while( (i_scale_count -= i_height) > 0 ) \
+ { \
+ /* Height increment: copy previous picture line */ \
+ for( i_x = i_pic_width / 16; i_x--; ) \
+ { \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ if( BPP > 1 ) /* 2, 3, 4 Bpp */ \
+ { \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ } \
+ if( BPP > 2 ) /* 3, 4 Bpp */ \
+ { \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ } \
+ if( BPP > 3 ) /* 4 Bpp */ \
+ { \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ } \
+ } \
+ p_pic += i_pic_line_width; \
+ p_pic_start += i_pic_line_width; \
+ } \
+ i_scale_count += i_pic_height; \
+ break; \
+ } \
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv_macros_8bpp.h: YUV transformation macros for 8bpp
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * CONVERT_4YUV_PIXELS: dither 4 pixels in 8 bpp
+ *****************************************************************************
+ * These macros dither 4 pixels in 8 bpp
+ *****************************************************************************/
+#define CONVERT_4YUV_PIXELS( CHROMA ) \
+ *p_pic++ = p_lookup[ \
+ (((*p_y++ + dither10[i_real_y]) >> 4) << 7) \
+ + ((*p_u + dither20[i_real_y]) >> 5) * 9 \
+ + ((*p_v + dither20[i_real_y]) >> 5) ]; \
+ *p_pic++ = p_lookup[ \
+ (((*p_y++ + dither11[i_real_y]) >> 4) << 7) \
+ + ((*p_u++ + dither21[i_real_y]) >> 5) * 9 \
+ + ((*p_v++ + dither21[i_real_y]) >> 5) ]; \
+ *p_pic++ = p_lookup[ \
+ (((*p_y++ + dither12[i_real_y]) >> 4) << 7) \
+ + ((*p_u + dither22[i_real_y]) >> 5) * 9 \
+ + ((*p_v + dither22[i_real_y]) >> 5) ]; \
+ *p_pic++ = p_lookup[ \
+ (((*p_y++ + dither13[i_real_y]) >> 4) << 7) \
+ + ((*p_u++ + dither23[i_real_y]) >> 5) * 9 \
+ + ((*p_v++ + dither23[i_real_y]) >> 5) ]; \
+
+/*****************************************************************************
+ * CONVERT_4YUV_PIXELS_SCALE: dither and scale 4 pixels in 8 bpp
+ *****************************************************************************
+ * These macros dither 4 pixels in 8 bpp, with horizontal scaling
+ *****************************************************************************/
+#define CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
+ *p_pic++ = p_lookup[ \
+ ( ((*p_y + dither10[i_real_y]) >> 4) << 7) \
+ + ((*p_u + dither20[i_real_y]) >> 5) * 9 \
+ + ((*p_v + dither20[i_real_y]) >> 5) ]; \
+ b_jump_uv += *p_offset; \
+ p_y += *p_offset; \
+ p_u += *p_offset & b_jump_uv; \
+ p_v += *p_offset++ & b_jump_uv; \
+ *p_pic++ = p_lookup[ \
+ ( ((*p_y + dither11[i_real_y]) >> 4) << 7) \
+ + ((*p_u + dither21[i_real_y]) >> 5) * 9 \
+ + ((*p_v + dither21[i_real_y]) >> 5) ]; \
+ b_jump_uv += *p_offset; \
+ p_y += *p_offset; \
+ p_u += *p_offset & b_jump_uv; \
+ p_v += *p_offset++ & b_jump_uv; \
+ *p_pic++ = p_lookup[ \
+ ( ((*p_y + dither12[i_real_y]) >> 4) << 7) \
+ + ((*p_u + dither22[i_real_y]) >> 5) * 9 \
+ + ((*p_v + dither22[i_real_y]) >> 5) ]; \
+ b_jump_uv += *p_offset; \
+ p_y += *p_offset; \
+ p_u += *p_offset & b_jump_uv; \
+ p_v += *p_offset++ & b_jump_uv; \
+ *p_pic++ = p_lookup[ \
+ ( ((*p_y + dither13[i_real_y]) >> 4) << 7) \
+ + ((*p_u + dither23[i_real_y]) >> 5) * 9 \
+ + ((*p_v + dither23[i_real_y]) >> 5) ]; \
+ b_jump_uv += *p_offset; \
+ p_y += *p_offset; \
+ p_u += *p_offset & b_jump_uv; \
+ p_v += *p_offset++ & b_jump_uv; \
+
+/*****************************************************************************
+ * SCALE_WIDTH_DITHER: scale a line horizontally for dithered 8 bpp
+ *****************************************************************************
+ * This macro scales a line using an offset array.
+ *****************************************************************************/
+#define SCALE_WIDTH_DITHER( CHROMA ) \
+ if( b_horizontal_scaling ) \
+ { \
+ /* Horizontal scaling, but we can't use a buffer due to dither */ \
+ p_offset = p_offset_start; \
+ b_jump_uv = 0; \
+ for( i_x = i_pic_width / 16; i_x--; ) \
+ { \
+ CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
+ CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
+ CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
+ CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
+ } \
+ } \
+ else \
+ { \
+ for( i_x = i_width / 16; i_x--; ) \
+ { \
+ CONVERT_4YUV_PIXELS( CHROMA ) \
+ CONVERT_4YUV_PIXELS( CHROMA ) \
+ CONVERT_4YUV_PIXELS( CHROMA ) \
+ CONVERT_4YUV_PIXELS( CHROMA ) \
+ } \
+ } \
+ /* Increment of picture pointer to end of line is still needed */ \
+ p_pic += i_pic_line_width; \
+ i_real_y = (i_real_y + 1) & 0x3; \
+
+/*****************************************************************************
+ * SCALE_HEIGHT_DITHER: handle vertical scaling for dithered 8 bpp
+ *****************************************************************************
+ * This macro handles vertical scaling for a picture. CHROMA may be 420, 422 or
+ * 444 for RGB conversion, or 400 for gray conversion.
+ *****************************************************************************/
+#define SCALE_HEIGHT_DITHER( CHROMA ) \
+ \
+ /* If line is odd, rewind 4:2:0 U and V samples */ \
+ if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
+ { \
+ p_u -= i_chroma_width; \
+ p_v -= i_chroma_width; \
+ } \
+ \
+ /* \
+ * Handle vertical scaling. The current line can be copied or next one \
+ * can be ignored. \
+ */ \
+ \
+ switch( i_vertical_scaling ) \
+ { \
+ case -1: /* vertical scaling factor is < 1 */ \
+ while( (i_scale_count -= i_pic_height) >= 0 ) \
+ { \
+ /* Height reduction: skip next source line */ \
+ p_y += i_width; \
+ i_y++; \
+ if( (CHROMA == 420) || (CHROMA == 422) ) \
+ { \
+ if( i_y & 0x1 ) \
+ { \
+ p_u += i_chroma_width; \
+ p_v += i_chroma_width; \
+ } \
+ } \
+ else if( CHROMA == 444 ) \
+ { \
+ p_u += i_width; \
+ p_v += i_width; \
+ } \
+ } \
+ i_scale_count += i_height; \
+ break; \
+ case 1: /* vertical scaling factor is > 1 */ \
+ while( (i_scale_count -= i_height) > 0 ) \
+ { \
+ SCALE_WIDTH_DITHER( CHROMA ); \
+ p_y -= i_width; \
+ p_u -= i_chroma_width; \
+ p_v -= i_chroma_width; \
+ p_pic += i_pic_line_width; \
+ } \
+ i_scale_count += i_pic_height; \
+ break; \
+ } \
+
--- /dev/null
+/*****************************************************************************
+ * yuv.c : C YUV functions for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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> /* malloc(), free() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "interface.h"
+#include "audio_output.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "plugins_export.h"
+
+/*****************************************************************************
+ * Exported prototypes
+ *****************************************************************************/
+void yuv_GetPlugin( p_vout_thread_t p_vout );
+
+/*****************************************************************************
+ * GetConfig: get the plugin structure and configuration
+ *****************************************************************************/
+plugin_info_t * GetConfig( void )
+{
+ plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+
+ p_info->psz_name = "C YUV to RGB transformations";
+ p_info->psz_version = VERSION;
+ p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
+
+ p_info->aout_GetPlugin = NULL;
+ p_info->vout_GetPlugin = NULL;
+ p_info->intf_GetPlugin = NULL;
+ p_info->yuv_GetPlugin = yuv_GetPlugin;
+
+ return( p_info );
+}
+
+/*****************************************************************************
+ * Test: tests if the plugin can be launched
+ *****************************************************************************/
+int Test( void )
+{
+ return( 1 );
+}
+
+/*****************************************************************************
+ * Following functions are only called through the p_info structure
+ *****************************************************************************/
+
+void yuv_GetPlugin( p_vout_thread_t p_vout )
+{
+ p_vout->p_yuv_init = yuv_SysInit;
+ p_vout->p_yuv_reset = yuv_SysReset;
+ p_vout->p_yuv_end = yuv_SysEnd;
+}
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv.c: YUV transformation functions
+ * Provides functions to perform the YUV conversion. The functions provided here
+ * are a complete and portable C implementation, and may be replaced in certain
+ * case by optimized functions.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <math.h> /* exp(), pow() */
+#include <errno.h> /* ENOMEM */
+#include <stdlib.h> /* free() */
+#include <string.h> /* strerror() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+#include "video.h"
+#include "video_output.h"
+#include "video_yuv.h"
+
+#include "intf_msg.h"
+
+/*****************************************************************************
+ * Constants
+ *****************************************************************************/
+
+int yuv_SysInit ( vout_thread_t *p_vout );
+int yuv_SysReset ( vout_thread_t *p_vout );
+void yuv_SysEnd ( vout_thread_t *p_vout );
+
+/*****************************************************************************
+ * vout_InitYUV: allocate and initialize translations tables
+ *****************************************************************************
+ * This function will allocate memory to store translation tables, depending
+ * of the screen depth.
+ *****************************************************************************/
+int yuv_SysInit( vout_thread_t *p_vout )
+{
+ size_t tables_size; /* tables size, in bytes */
+
+ /* Computes tables size - 3 Bpp use 32 bits pixel entries in tables */
+ switch( p_vout->i_bytes_per_pixel )
+ {
+ case 1:
+ tables_size = sizeof( u8 )
+ * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : PALETTE_TABLE_SIZE);
+ break;
+ case 2:
+ tables_size = sizeof( u16 )
+ * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
+ break;
+ case 3:
+ case 4:
+ default:
+ tables_size = sizeof( u32 )
+ * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
+ break;
+ }
+
+ /* Allocate memory */
+ p_vout->yuv.p_base = malloc( tables_size );
+ if( p_vout->yuv.p_base == NULL )
+ {
+ intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+ return( 1 );
+ }
+
+ /* Allocate memory for conversion buffer and offset array */
+ p_vout->yuv.p_buffer = malloc( VOUT_MAX_WIDTH * p_vout->i_bytes_per_pixel );
+ if( p_vout->yuv.p_buffer == NULL )
+ {
+ intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+ free( p_vout->yuv.p_base );
+ return( 1 );
+ }
+ p_vout->yuv.p_offset = malloc( p_vout->i_width * sizeof( int ) );
+ if( p_vout->yuv.p_offset == NULL )
+ {
+ intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+ free( p_vout->yuv.p_base );
+ free( p_vout->yuv.p_buffer );
+ return( 1 );
+ }
+
+ /* Initialize tables */
+ SetYUV( p_vout );
+ return( 0 );
+}
+
+/*****************************************************************************
+ * yuv_SysReset: re-initialize translations tables
+ *****************************************************************************
+ * This function will initialize the tables allocated by vout_CreateTables and
+ * set functions pointers.
+ *****************************************************************************/
+int yuv_SysReset( vout_thread_t *p_vout )
+{
+ yuv_SysEnd( p_vout );
+ return( yuv_SysInit( p_vout ) );
+}
+
+/*****************************************************************************
+ * yuv_SysEnd: destroy translations tables
+ *****************************************************************************
+ * Free memory allocated by yuv_SysCreate.
+ *****************************************************************************/
+void yuv_SysEnd( vout_thread_t *p_vout )
+{
+ free( p_vout->yuv.p_base );
+ free( p_vout->yuv.p_buffer );
+ free( p_vout->yuv.p_offset );
+}
+
+/* following functions are local */
+
+/*****************************************************************************
+ * SetGammaTable: return intensity table transformed by gamma curve.
+ *****************************************************************************
+ * pi_table is a table of 256 entries from 0 to 255.
+ *****************************************************************************/
+void SetGammaTable( int *pi_table, double f_gamma )
+{
+ int i_y; /* base intensity */
+
+ /* Use exp(gamma) instead of gamma */
+ f_gamma = exp( f_gamma );
+
+ /* Build gamma table */
+ for( i_y = 0; i_y < 256; i_y++ )
+ {
+ pi_table[ i_y ] = pow( (double)i_y / 256, f_gamma ) * 256;
+ }
+ }
+
+/*****************************************************************************
+ * SetYUV: compute tables and set function pointers
++ *****************************************************************************/
+void SetYUV( vout_thread_t *p_vout )
+{
+ int pi_gamma[256]; /* gamma table */
+ int i_index; /* index in tables */
+
+ /* Build gamma table */
+ SetGammaTable( pi_gamma, p_vout->f_gamma );
+
+ /*
+ * Set pointers and build YUV tables
+ */
+ if( p_vout->b_grayscale )
+ {
+ /* Grayscale: build gray table */
+ switch( p_vout->i_bytes_per_pixel )
+ {
+ case 1:
+ {
+ u16 bright[256], transp[256];
+
+ p_vout->yuv.yuv.p_gray8 = (u8 *)p_vout->yuv.p_base + GRAY_MARGIN;
+ for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_gray8[ -i_index ] = RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
+ p_vout->yuv.yuv.p_gray8[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
+ }
+ for( i_index = 0; i_index < 256; i_index++)
+ {
+ p_vout->yuv.yuv.p_gray8[ i_index ] = pi_gamma[ i_index ];
+ bright[ i_index ] = i_index << 8;
+ transp[ i_index ] = 0;
+ }
+ /* the colors have been allocated, we can set the palette */
+ p_vout->p_set_palette( p_vout, bright, bright, bright, transp );
+ p_vout->i_white_pixel = 0xff;
+ p_vout->i_black_pixel = 0x00;
+ p_vout->i_gray_pixel = 0x44;
+ p_vout->i_blue_pixel = 0x3b;
+
+ break;
+ }
+ case 2:
+ p_vout->yuv.yuv.p_gray16 = (u16 *)p_vout->yuv.p_base + GRAY_MARGIN;
+ for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_gray16[ -i_index ] = RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
+ p_vout->yuv.yuv.p_gray16[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
+ }
+ for( i_index = 0; i_index < 256; i_index++)
+ {
+ p_vout->yuv.yuv.p_gray16[ i_index ] = RGB2PIXEL( p_vout, pi_gamma[i_index], pi_gamma[i_index], pi_gamma[i_index] );
+ }
+ break;
+ case 3:
+ case 4:
+ p_vout->yuv.yuv.p_gray32 = (u32 *)p_vout->yuv.p_base + GRAY_MARGIN;
+ for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_gray32[ -i_index ] = RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
+ p_vout->yuv.yuv.p_gray32[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
+ }
+ for( i_index = 0; i_index < 256; i_index++)
+ {
+ p_vout->yuv.yuv.p_gray32[ i_index ] = RGB2PIXEL( p_vout, pi_gamma[i_index], pi_gamma[i_index], pi_gamma[i_index] );
+ }
+ break;
+ }
+ }
+ else
+ {
+ /* Color: build red, green and blue tables */
+ switch( p_vout->i_bytes_per_pixel )
+ {
+ case 1:
+ {
+ #define RGB_MIN 0
+ #define RGB_MAX 255
+ #define CLIP( x ) ( ((x < 0) ? 0 : (x > 255) ? 255 : x) << 8 )
+
+ int y,u,v;
+ int r,g,b;
+ int uvr, uvg, uvb;
+ int i = 0, j = 0;
+ u16 red[256], green[256], blue[256], transp[256];
+ unsigned char lookup[PALETTE_TABLE_SIZE];
+
+ p_vout->yuv.yuv.p_rgb8 = (u8 *)p_vout->yuv.p_base;
+
+ /* this loop calculates the intersection of an YUV box
+ * and the RGB cube. */
+ for ( y = 0; y <= 256; y += 16 )
+ {
+ for ( u = 0; u <= 256; u += 32 )
+ for ( v = 0; v <= 256; v += 32 )
+ {
+ uvr = (V_RED_COEF*(v-128)) >> SHIFT;
+ uvg = (U_GREEN_COEF*(u-128) + V_GREEN_COEF*(v-128)) >> SHIFT;
+ uvb = (U_BLUE_COEF*(u-128)) >> SHIFT;
+ r = y + uvr;
+ g = y + uvg;
+ b = y + uvb;
+
+ if( r >= RGB_MIN && g >= RGB_MIN && b >= RGB_MIN
+ && r <= RGB_MAX && g <= RGB_MAX && b <= RGB_MAX )
+ {
+ /* this one should never happen unless someone fscked up my code */
+ if(j == 256) { intf_ErrMsg( "vout error: no colors left to build palette\n" ); break; }
+
+ /* clip the colors */
+ red[j] = CLIP( r );
+ green[j] = CLIP( g );
+ blue[j] = CLIP( b );
+ transp[j] = 0;
+
+ /* allocate color */
+ lookup[i] = 1;
+ p_vout->yuv.yuv.p_rgb8[i++] = j;
+ j++;
+ }
+ else
+ {
+ lookup[i] = 0;
+ p_vout->yuv.yuv.p_rgb8[i++] = 0;
+ }
+ }
+ i += 128-81;
+ }
+
+ /* the colors have been allocated, we can set the palette */
+ /* there will eventually be a way to know which colors
+ * couldn't be allocated and try to find a replacement */
+ p_vout->p_set_palette( p_vout, red, green, blue, transp );
+
+ p_vout->i_white_pixel = 0xff;
+ p_vout->i_black_pixel = 0x00;
+ p_vout->i_gray_pixel = 0x44;
+ p_vout->i_blue_pixel = 0x3b;
+
+ i = 0;
+ /* this loop allocates colors that got outside
+ * the RGB cube */
+ for ( y = 0; y <= 256; y += 16 )
+ {
+ for ( u = 0; u <= 256; u += 32 )
+ for ( v = 0; v <= 256; v += 32 )
+ {
+ int u2, v2;
+ int dist, mindist = 100000000;
+
+ if( lookup[i] || y==0)
+ {
+ i++;
+ continue;
+ }
+
+ /* heavy. yeah. */
+ for( u2 = 0; u2 <= 256; u2 += 32 )
+ for( v2 = 0; v2 <= 256; v2 += 32 )
+ {
+ j = ((y>>4)<<7) + (u2>>5)*9 + (v2>>5);
+ dist = (u-u2)*(u-u2) + (v-v2)*(v-v2);
+ if( lookup[j] )
+ /* find the nearest color */
+ if( dist < mindist )
+ {
+ p_vout->yuv.yuv.p_rgb8[i] = p_vout->yuv.yuv.p_rgb8[j];
+ mindist = dist;
+ }
+ j -= 128;
+ if( lookup[j] )
+ /* find the nearest color */
+ if( dist + 128 < mindist )
+ {
+ p_vout->yuv.yuv.p_rgb8[i] = p_vout->yuv.yuv.p_rgb8[j];
+ mindist = dist + 128;
+ }
+ }
+ i++;
+ }
+ i += 128-81;
+ }
+
+ break;
+ }
+ case 2:
+ p_vout->yuv.yuv.p_rgb16 = (u16 *)p_vout->yuv.p_base;
+ for( i_index = 0; i_index < RED_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb16[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
+ p_vout->yuv.yuv.p_rgb16[RED_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
+ }
+ for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
+ p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
+ }
+ for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
+ p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
+ }
+ for( i_index = 0; i_index < 256; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb16[RED_OFFSET + i_index] = RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
+ p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
+ p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] );
+ }
+ break;
+ case 3:
+ case 4:
+ p_vout->yuv.yuv.p_rgb32 = (u32 *)p_vout->yuv.p_base;
+ for( i_index = 0; i_index < RED_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb32[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
+ p_vout->yuv.yuv.p_rgb32[RED_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
+ }
+ for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
+ p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
+ }
+ for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
+ p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
+ }
+ for( i_index = 0; i_index < 256; i_index++ )
+ {
+ p_vout->yuv.yuv.p_rgb32[RED_OFFSET + i_index] = RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
+ p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
+ p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] );
+ }
+ break;
+ }
+ }
+
+ /*
+ * Set functions pointers
+ */
+ if( p_vout->b_grayscale )
+ {
+ /* Grayscale */
+ switch( p_vout->i_bytes_per_pixel )
+ {
+ case 1:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray8;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray8;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray8;
+ break;
+ case 2:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray16;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray16;
+ break;
+ case 3:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray24;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray24;
+ break;
+ case 4:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray32;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray32;
+ break;
+ }
+ }
+ else
+ {
+ /* Color */
+ switch( p_vout->i_bytes_per_pixel )
+ {
+ case 1:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB8;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB8;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB8;
+ break;
+ case 2:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB16;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB16;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB16;
+ break;
+ case 3:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB24;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB24;
+ break;
+ case 4:
+ p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
+ p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB32;
+ p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB32;
+ break;
+ }
+ }
+}
+
+/*****************************************************************************
+ * SetOffset: build offset array for conversion functions
+ *****************************************************************************
+ * This function will build an offset array used in later conversion functions.
+ * It will also set horizontal and vertical scaling indicators.
+ *****************************************************************************/
+void SetOffset( int i_width, int i_height, int i_pic_width, int i_pic_height,
+ boolean_t *pb_h_scaling, int *pi_v_scaling, int *p_offset )
+{
+ int i_x; /* x position in destination */
+ int i_scale_count; /* modulo counter */
+
+ /*
+ * Prepare horizontal offset array
+ */
+ if( i_pic_width - i_width > 0 )
+ {
+ /* Prepare scaling array for horizontal extension */
+ *pb_h_scaling = 1;
+ i_scale_count = i_pic_width;
+ for( i_x = i_width; i_x--; )
+ {
+ while( (i_scale_count -= i_width) > 0 )
+ {
+ *p_offset++ = 0;
+ }
+ *p_offset++ = 1;
+ i_scale_count += i_pic_width;
+ }
+ }
+ else if( i_pic_width - i_width < 0 )
+ {
+ /* Prepare scaling array for horizontal reduction */
+ *pb_h_scaling = 1;
+ i_scale_count = i_pic_width;
+ for( i_x = i_pic_width; i_x--; )
+ {
+ *p_offset = 1;
+ while( (i_scale_count -= i_pic_width) >= 0 )
+ {
+ *p_offset += 1;
+ }
+ p_offset++;
+ i_scale_count += i_width;
+ }
+ }
+ else
+ {
+ /* No horizontal scaling: YUV conversion is done directly to picture */
+ *pb_h_scaling = 0;
+ }
+
+ /*
+ * Set vertical scaling indicator
+ */
+ if( i_pic_height - i_height > 0 )
+ {
+ *pi_v_scaling = 1;
+ }
+ else if( i_pic_height - i_height < 0 )
+ {
+ *pi_v_scaling = -1;
+ }
+ else
+ {
+ *pi_v_scaling = 0;
+ }
+}
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv.h: YUV transformation functions
+ * Provides functions to perform the YUV conversion. The functions provided here
+ * are a complete and portable C implementation, and may be replaced in certain
+ * case by optimized functions.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Constants
+ *****************************************************************************/
+
+/* Margins and offsets in conversion tables - Margins are used in case a RGB
+ * RGB conversion would give a value outside the 0-255 range. Offsets have been
+ * calculated to avoid using the same cache line for 2 tables. conversion tables
+ * are 2*MARGIN + 256 long and stores pixels.*/
+#define RED_MARGIN 178
+#define GREEN_MARGIN 135
+#define BLUE_MARGIN 224
+#define RED_OFFSET 1501 /* 1323 to 1935 */
+#define GREEN_OFFSET 135 /* 0 to 526 */
+#define BLUE_OFFSET 818 /* 594 to 1298 */
+#define RGB_TABLE_SIZE 1935 /* total table size */
+
+#define GRAY_MARGIN 384
+#define GRAY_TABLE_SIZE 1024 /* total table size */
+
+#define PALETTE_TABLE_SIZE 2176 /* YUV -> 8bpp palette lookup table */
+
+/* macros used for YUV pixel conversions */
+#define SHIFT 20
+#define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
+#define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
+#define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
+#define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
+
+/* argument lists for YUV functions */
+#define YUV_ARGS_8BPP p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, \
+yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, \
+int i_pic_height, int i_pic_line_width, int i_matrix_coefficients
+
+#define YUV_ARGS_16BPP p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, \
+yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, \
+int i_pic_height, int i_pic_line_width, int i_matrix_coefficients
+
+#define YUV_ARGS_24BPP p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, \
+yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, \
+int i_pic_height, int i_pic_line_width, int i_matrix_coefficients
+
+#define YUV_ARGS_32BPP p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, \
+yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, \
+int i_pic_height, int i_pic_line_width, int i_matrix_coefficients
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+void SetGammaTable ( int *pi_table, double f_gamma );
+void SetYUV ( vout_thread_t *p_vout );
+void SetOffset ( int i_width, int i_height, int i_pic_width,
+ int i_pic_height, boolean_t *pb_h_scaling,
+ int *pi_v_scaling, int *p_offset );
+
+void ConvertY4Gray8 ( YUV_ARGS_8BPP );
+void ConvertYUV420RGB8 ( YUV_ARGS_8BPP );
+void ConvertYUV422RGB8 ( YUV_ARGS_8BPP );
+void ConvertYUV444RGB8 ( YUV_ARGS_8BPP );
+
+void ConvertY4Gray16 ( YUV_ARGS_16BPP );
+void ConvertYUV420RGB16 ( YUV_ARGS_16BPP );
+void ConvertYUV422RGB16 ( YUV_ARGS_16BPP );
+void ConvertYUV444RGB16 ( YUV_ARGS_16BPP );
+
+void ConvertY4Gray24 ( YUV_ARGS_24BPP );
+void ConvertYUV420RGB24 ( YUV_ARGS_24BPP );
+void ConvertYUV422RGB24 ( YUV_ARGS_24BPP );
+void ConvertYUV444RGB24 ( YUV_ARGS_24BPP );
+
+void ConvertY4Gray32 ( YUV_ARGS_32BPP );
+void ConvertYUV420RGB32 ( YUV_ARGS_32BPP );
+void ConvertYUV422RGB32 ( YUV_ARGS_32BPP );
+void ConvertYUV444RGB32 ( YUV_ARGS_32BPP );
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv16.c: YUV transformation functions for 16bpp
+ * Provides functions to perform the YUV conversion. The functions provided here
+ * are a complete and portable C implementation, and may be replaced in certain
+ * case by optimized functions.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <math.h> /* exp(), pow() */
+#include <errno.h> /* ENOMEM */
+#include <stdlib.h> /* free() */
+#include <string.h> /* strerror() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+#include "video.h"
+#include "video_output.h"
+#include "video_yuv.h"
+#include "video_yuv_macros.h"
+#include "video_yuv_asm.h"
+
+#include "intf_msg.h"
+
+/*****************************************************************************
+ * ConvertY4Gray16: color YUV 4:4:4 to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertY4Gray16( YUV_ARGS_16BPP )
+{
+ intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 16\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertYUV420RGB16( YUV_ARGS_16BPP )
+{
+ boolean_t b_horizontal_scaling; /* horizontal scaling type */
+ int i_vertical_scaling; /* vertical scaling type */
+ int i_x, i_y; /* horizontal and vertical indexes */
+ int i_scale_count; /* scale modulo counter */
+ int i_chroma_width; /* chroma width */
+ u16 * p_yuv; /* base conversion table */
+ u16 * p_pic_start; /* beginning of the current line for copy */
+ u16 * p_buffer_start; /* conversion buffer start */
+ u16 * p_buffer; /* conversion buffer pointer */
+ int * p_offset_start; /* offset array start */
+ int * p_offset; /* offset array pointer */
+
+ /*
+ * Initialize some values - i_pic_line_width will store the line skip
+ */
+ i_pic_line_width -= i_pic_width;
+ i_chroma_width = i_width / 2;
+ p_yuv = p_vout->yuv.yuv.p_rgb16;
+ p_buffer_start = p_vout->yuv.p_buffer;
+ p_offset_start = p_vout->yuv.p_offset;
+ SetOffset( i_width, i_height, i_pic_width, i_pic_height,
+ &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
+
+ /*
+ * Perform conversion
+ */
+ i_scale_count = i_pic_height;
+ for( i_y = 0; i_y < i_height; i_y++ )
+ {
+ /* Mark beginnning of line for possible later line copy, and initialize
+ * buffer */
+ p_pic_start = p_pic;
+ p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
+
+ for ( i_x = i_width / 8; i_x--; )
+ {
+ __asm__( MMX_INIT_16
+ : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
+
+ __asm__( ".align 8" MMX_YUV_MUL MMX_YUV_ADD MMX_UNPACK_16
+ : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
+
+ p_y += 8;
+ p_u += 4;
+ p_v += 4;
+ p_buffer += 8;
+ }
+
+ SCALE_WIDTH;
+ SCALE_HEIGHT( 420, 2 );
+ }
+ __asm__( "emms" );
+}
+
+/*****************************************************************************
+ * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertYUV422RGB16( YUV_ARGS_16BPP )
+{
+ intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 16\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertYUV444RGB16( YUV_ARGS_16BPP )
+{
+ intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 16\n" );
+}
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv24.c: YUV transformation functions for 24 bpp
+ * Provides functions to perform the YUV conversion. The functions provided here
+ * are a complete and portable C implementation, and may be replaced in certain
+ * case by optimized functions.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <math.h> /* exp(), pow() */
+#include <errno.h> /* ENOMEM */
+#include <stdlib.h> /* free() */
+#include <string.h> /* strerror() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+#include "video.h"
+#include "video_output.h"
+#include "video_yuv.h"
+
+#include "intf_msg.h"
+
+/*****************************************************************************
+ * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertY4Gray24( YUV_ARGS_24BPP )
+{
+ intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 24\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertYUV420RGB24( YUV_ARGS_24BPP )
+{
+ intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, bpp = 24\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertYUV422RGB24( YUV_ARGS_24BPP )
+{
+ intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 24\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 2 Bpp
+ *****************************************************************************/
+void ConvertYUV444RGB24( YUV_ARGS_24BPP )
+{
+ intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 24\n" );
+}
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv32.c: YUV transformation functions for 32 bpp
+ * Provides functions to perform the YUV conversion. The functions provided here
+ * are a complete and portable C implementation, and may be replaced in certain
+ * case by optimized functions.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <math.h> /* exp(), pow() */
+#include <errno.h> /* ENOMEM */
+#include <stdlib.h> /* free() */
+#include <string.h> /* strerror() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+#include "video.h"
+#include "video_output.h"
+#include "video_yuv.h"
+#include "video_yuv_macros.h"
+#include "video_yuv_asm.h"
+
+#include "intf_msg.h"
+
+/*****************************************************************************
+ * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
+ *****************************************************************************/
+void ConvertY4Gray32( YUV_ARGS_32BPP )
+{
+ intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 32\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
+ *****************************************************************************/
+void ConvertYUV420RGB32( YUV_ARGS_32BPP )
+{
+ boolean_t b_horizontal_scaling; /* horizontal scaling type */
+ int i_vertical_scaling; /* vertical scaling type */
+ int i_x, i_y; /* horizontal and vertical indexes */
+ int i_scale_count; /* scale modulo counter */
+ int i_chroma_width; /* chroma width */
+ u32 * p_yuv; /* base conversion table */
+ u32 * p_pic_start; /* beginning of the current line for copy */
+ u32 * p_buffer_start; /* conversion buffer start */
+ u32 * p_buffer; /* conversion buffer pointer */
+ int * p_offset_start; /* offset array start */
+ int * p_offset; /* offset array pointer */
+
+ /*
+ * Initialize some values - i_pic_line_width will store the line skip
+ */
+ i_pic_line_width -= i_pic_width;
+ i_chroma_width = i_width / 2;
+ p_yuv = p_vout->yuv.yuv.p_rgb32;
+ p_buffer_start = p_vout->yuv.p_buffer;
+ p_offset_start = p_vout->yuv.p_offset;
+ SetOffset( i_width, i_height, i_pic_width, i_pic_height,
+ &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
+
+ /*
+ * Perform conversion
+ */
+ i_scale_count = i_pic_height;
+ for( i_y = 0; i_y < i_height; i_y++ )
+ {
+ /* Mark beginnning of line for possible later line copy, and initialize
+ * buffer */
+ p_pic_start = p_pic;
+ p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
+
+ for ( i_x = i_width / 8; i_x--; )
+ {
+ __asm__( ".align 8" MMX_INIT_32
+ : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
+
+ __asm__( ".align 8" MMX_YUV_ADD MMX_YUV_MUL MMX_UNPACK_32
+ : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
+
+ p_y += 8;
+ p_u += 4;
+ p_v += 4;
+ p_buffer += 8;
+ }
+
+ SCALE_WIDTH;
+ SCALE_HEIGHT( 420, 2 );
+ }
+ __asm__( "emms" );
+}
+
+/*****************************************************************************
+ * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
+ *****************************************************************************/
+void ConvertYUV422RGB32( YUV_ARGS_32BPP )
+{
+ intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 32\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
+ *****************************************************************************/
+void ConvertYUV444RGB32( YUV_ARGS_32BPP )
+{
+ intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 32\n" );
+}
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv8.c: YUV transformation functions for 8bpp
+ * Provides functions to perform the YUV conversion. The functions provided here
+ * are a complete and portable C implementation, and may be replaced in certain
+ * case by optimized functions.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <math.h> /* exp(), pow() */
+#include <errno.h> /* ENOMEM */
+#include <stdlib.h> /* free() */
+#include <string.h> /* strerror() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+#include "video.h"
+#include "video_output.h"
+#include "video_yuv.h"
+
+#include "intf_msg.h"
+
+/*****************************************************************************
+ * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
+ *****************************************************************************/
+void ConvertY4Gray8( YUV_ARGS_8BPP )
+{
+ intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 8\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
+ *****************************************************************************/
+void ConvertYUV420RGB8( YUV_ARGS_8BPP )
+{
+ intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, bpp = 8\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
+ *****************************************************************************/
+void ConvertYUV422RGB8( YUV_ARGS_8BPP )
+{
+ intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 8\n" );
+}
+
+/*****************************************************************************
+ * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
+ *****************************************************************************/
+void ConvertYUV444RGB8( YUV_ARGS_8BPP )
+{
+ intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 8\n" );
+}
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv_asm.h: YUV transformation assembly
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ * Olie Lho <ollie@sis.com.tw>
+ *
+ * Adapted to VideoLAN by:
+ * Gaël Hendryckx <jimmy@via.ecp.fr>
+ * Samuel Hocevar <sam@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-1307, USA.
+ *****************************************************************************/
+
+/* hope these constant values are cache line aligned */
+static unsigned long long mmx_80w = 0x0080008000800080;
+static unsigned long long mmx_10w = 0x1010101010101010;
+static unsigned long long mmx_00ffw = 0x00ff00ff00ff00ff;
+static unsigned long long mmx_Y_coeff = 0x253f253f253f253f;
+
+static unsigned long long mmx_U_green = 0xf37df37df37df37d;
+static unsigned long long mmx_U_blue = 0x4093409340934093;
+static unsigned long long mmx_V_red = 0x3312331233123312;
+static unsigned long long mmx_V_green = 0xe5fce5fce5fce5fc;
+
+static unsigned long long mmx_redmask = 0xf8f8f8f8f8f8f8f8;
+static unsigned long long mmx_grnmask = 0xfcfcfcfcfcfcfcfc;
+static unsigned long long mmx_grnshift = 0x03;
+static unsigned long long mmx_blueshift = 0x03;
+
+#define MMX_INIT_16 " \n\
+ \n\
+movd (%1), %%mm0 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
+movd (%2), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
+pxor %%mm4, %%mm4 # zero mm4 \n\
+movq (%0), %%mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
+#movl $0, (%3) # cache preload for image \n\
+"
+
+#define MMX_INIT_32 " \n\
+ \n\
+movd (%1), %%mm0 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
+movl $0, (%3) # cache preload for image \n\
+movd (%2), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
+pxor %%mm4, %%mm4 # zero mm4 \n\
+movq (%0), %%mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
+"
+
+/*
+ * Do the multiply part of the conversion for even and odd pixels,
+ * register usage:
+ * mm0 -> Cblue, mm1 -> Cred, mm2 -> Cgreen even pixels,
+ * mm3 -> Cblue, mm4 -> Cred, mm5 -> Cgreen odd pixels,
+ * mm6 -> Y even, mm7 -> Y odd
+ */
+
+#define MMX_YUV_MUL " \n\
+ \n\
+# convert the chroma part \n\
+punpcklbw %%mm4, %%mm0 # scatter 4 Cb 00 u3 00 u2 00 u1 00 u0 \n\
+punpcklbw %%mm4, %%mm1 # scatter 4 Cr 00 v3 00 v2 00 v1 00 v0 \n\
+psubsw mmx_80w, %%mm0 # Cb -= 128 \n\
+psubsw mmx_80w, %%mm1 # Cr -= 128 \n\
+psllw $3, %%mm0 # Promote precision \n\
+psllw $3, %%mm1 # Promote precision \n\
+movq %%mm0, %%mm2 # Copy 4 Cb 00 u3 00 u2 00 u1 00 u0 \n\
+movq %%mm1, %%mm3 # Copy 4 Cr 00 v3 00 v2 00 v1 00 v0 \n\
+pmulhw mmx_U_green, %%mm2 # Mul Cb with green coeff -> Cb green \n\
+pmulhw mmx_V_green, %%mm3 # Mul Cr with green coeff -> Cr green \n\
+pmulhw mmx_U_blue, %%mm0 # Mul Cb -> Cblue 00 b3 00 b2 00 b1 00 b0 \n\
+pmulhw mmx_V_red, %%mm1 # Mul Cr -> Cred 00 r3 00 r2 00 r1 00 \n\
+paddsw %%mm3, %%mm2 # Cb green + Cr green -> Cgreen \n\
+ \n\
+# convert the luma part \n\
+psubusb mmx_10w, %%mm6 # Y -= 16 \n\
+movq %%mm6, %%mm7 # Copy 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
+pand mmx_00ffw, %%mm6 # get Y even 00 Y6 00 Y4 00 Y2 00 Y0 \n\
+psrlw $8, %%mm7 # get Y odd 00 Y7 00 Y5 00 Y3 00 Y1 \n\
+psllw $3, %%mm6 # Promote precision \n\
+psllw $3, %%mm7 # Promote precision \n\
+pmulhw mmx_Y_coeff, %%mm6 # Mul 4 Y even 00 y6 00 y4 00 y2 00 y0 \n\
+pmulhw mmx_Y_coeff, %%mm7 # Mul 4 Y odd 00 y7 00 y5 00 y3 00 y1 \n\
+"
+
+/*
+ * Do the addition part of the conversion for even and odd pixels,
+ * register usage:
+ * mm0 -> Cblue, mm1 -> Cred, mm2 -> Cgreen even pixels,
+ * mm3 -> Cblue, mm4 -> Cred, mm5 -> Cgreen odd pixels,
+ * mm6 -> Y even, mm7 -> Y odd
+ */
+
+#define MMX_YUV_ADD " \n\
+ \n\
+# Do horizontal and vertical scaling \n\
+movq %%mm0, %%mm3 # Copy Cblue \n\
+movq %%mm1, %%mm4 # Copy Cred \n\
+movq %%mm2, %%mm5 # Copy Cgreen \n\
+paddsw %%mm6, %%mm0 # Y even + Cblue 00 B6 00 B4 00 B2 00 B0 \n\
+paddsw %%mm7, %%mm3 # Y odd + Cblue 00 B7 00 B5 00 B3 00 B1 \n\
+paddsw %%mm6, %%mm1 # Y even + Cred 00 R6 00 R4 00 R2 00 R0 \n\
+paddsw %%mm7, %%mm4 # Y odd + Cred 00 R7 00 R5 00 R3 00 R1 \n\
+paddsw %%mm6, %%mm2 # Y even + Cgreen 00 G6 00 G4 00 G2 00 G0 \n\
+paddsw %%mm7, %%mm5 # Y odd + Cgreen 00 G7 00 G5 00 G3 00 G1 \n\
+ \n\
+# Limit RGB even to 0..255 \n\
+packuswb %%mm0, %%mm0 # B6 B4 B2 B0 | B6 B4 B2 B0 \n\
+packuswb %%mm1, %%mm1 # R6 R4 R2 R0 | R6 R4 R2 R0 \n\
+packuswb %%mm2, %%mm2 # G6 G4 G2 G0 | G6 G4 G2 G0 \n\
+ \n\
+# Limit RGB odd to 0..255 \n\
+packuswb %%mm3, %%mm3 # B7 B5 B3 B1 | B7 B5 B3 B1 \n\
+packuswb %%mm4, %%mm4 # R7 R5 R3 R1 | R7 R5 R3 R1 \n\
+packuswb %%mm5, %%mm5 # G7 G5 G3 G1 | G7 G5 G3 G1 \n\
+ \n\
+# Interleave RGB even and odd \n\
+punpcklbw %%mm3, %%mm0 # B7 B6 B5 B4 B3 B2 B1 B0 \n\
+punpcklbw %%mm4, %%mm1 # R7 R6 R5 R4 R3 R2 R1 R0 \n\
+punpcklbw %%mm5, %%mm2 # G7 G6 G5 G4 G3 G2 G1 G0 \n\
+"
+
+#define MMX_UNPACK_16 " \n\
+ \n\
+# mask unneeded bits off \n\
+pand mmx_redmask, %%mm0 # b7b6b5b4 b3_0_0_0 b7b6b5b4 b3_0_0_0 \n\
+pand mmx_grnmask, %%mm2 # g7g6g5g4 g3g2_0_0 g7g6g5g4 g3g2_0_0 \n\
+pand mmx_redmask, %%mm1 # r7r6r5r4 r3_0_0_0 r7r6r5r4 r3_0_0_0 \n\
+psrlw mmx_blueshift,%%mm0 # 0_0_0_b7 b6b5b4b3 0_0_0_b7 b6b5b4b3 \n\
+pxor %%mm4, %%mm4 # zero mm4 \n\
+movq %%mm0, %%mm5 # Copy B7-B0 \n\
+movq %%mm2, %%mm7 # Copy G7-G0 \n\
+ \n\
+# convert rgb24 plane to rgb16 pack for pixel 0-3 \n\
+punpcklbw %%mm4, %%mm2 # 0_0_0_0 0_0_0_0 g7g6g5g4 g3g2_0_0 \n\
+punpcklbw %%mm1, %%mm0 # r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3 \n\
+psllw mmx_blueshift,%%mm2 # 0_0_0_0 0_g7g6g5 g4g3g2_0 0_0_0_0 \n\
+por %%mm2, %%mm0 # r7r6r5r4 r3g7g6g5 g4g3g2b7 b6b5b4b3 \n\
+movq 8(%0), %%mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
+movq %%mm0, (%3) # store pixel 0-3 \n\
+ \n\
+# convert rgb24 plane to rgb16 pack for pixel 0-3 \n\
+punpckhbw %%mm4, %%mm7 # 0_0_0_0 0_0_0_0 g7g6g5g4 g3g2_0_0 \n\
+punpckhbw %%mm1, %%mm5 # r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3 \n\
+psllw mmx_blueshift,%%mm7 # 0_0_0_0 0_g7g6g5 g4g3g2_0 0_0_0_0 \n\
+movd 4(%1), %%mm0 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
+por %%mm7, %%mm5 # r7r6r5r4 r3g7g6g5 g4g3g2b7 b6b5b4b3 \n\
+movd 4(%2), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
+movq %%mm5, 8(%3) # store pixel 4-7 \n\
+"
+
+/*
+ * convert RGB plane to RGB packed format,
+ * mm0 -> B, mm1 -> R, mm2 -> G, mm3 -> 0,
+ * mm4 -> GB, mm5 -> AR pixel 4-7,
+ * mm6 -> GB, mm7 -> AR pixel 0-3
+ */
+
+#define MMX_UNPACK_32 " \n\
+ \n\
+pxor %%mm3, %%mm3 # zero mm3 \n\
+movq %%mm0, %%mm6 # B7 B6 B5 B4 B3 B2 B1 B0 \n\
+movq %%mm1, %%mm7 # R7 R6 R5 R4 R3 R2 R1 R0 \n\
+movq %%mm0, %%mm4 # B7 B6 B5 B4 B3 B2 B1 B0 \n\
+movq %%mm1, %%mm5 # R7 R6 R5 R4 R3 R2 R1 R0 \n\
+punpcklbw %%mm2, %%mm6 # G3 B3 G2 B2 G1 B1 G0 B0 \n\
+punpcklbw %%mm3, %%mm7 # 00 R3 00 R2 00 R1 00 R0 \n\
+punpcklwd %%mm7, %%mm6 # 00 R1 B1 G1 00 R0 B0 G0 \n\
+movq %%mm6, (%3) # Store ARGB1 ARGB0 \n\
+movq %%mm0, %%mm6 # B7 B6 B5 B4 B3 B2 B1 B0 \n\
+punpcklbw %%mm2, %%mm6 # G3 B3 G2 B2 G1 B1 G0 B0 \n\
+punpckhwd %%mm7, %%mm6 # 00 R3 G3 B3 00 R2 B3 G2 \n\
+movq %%mm6, 8(%3) # Store ARGB3 ARGB2 \n\
+punpckhbw %%mm2, %%mm4 # G7 B7 G6 B6 G5 B5 G4 B4 \n\
+punpckhbw %%mm3, %%mm5 # 00 R7 00 R6 00 R5 00 R4 \n\
+punpcklwd %%mm5, %%mm4 # 00 R5 B5 G5 00 R4 B4 G4 \n\
+movq %%mm4, 16(%3) # Store ARGB5 ARGB4 \n\
+movq %%mm0, %%mm4 # B7 B6 B5 B4 B3 B2 B1 B0 \n\
+punpckhbw %%mm2, %%mm4 # G7 B7 G6 B6 G5 B5 G4 B4 \n\
+punpckhwd %%mm5, %%mm4 # 00 R7 G7 B7 00 R6 B6 G6 \n\
+movq %%mm4, 24(%3) # Store ARGB7 ARGB6 \n\
+movd 4(%1), %%mm0 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
+movd 4(%2), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
+pxor %%mm4, %%mm4 # zero mm4 \n\
+movq 8(%0), %%mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
+"
+
--- /dev/null
+/*****************************************************************************
+ * video_yuv_macros.h: YUV transformation macros
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * SCALE_WIDTH: scale a line horizontally
+ *****************************************************************************
+ * This macro scales a line using rendering buffer and offset array. It works
+ * for 1, 2 and 4 Bpp.
+ *****************************************************************************/
+#define SCALE_WIDTH \
+ if( b_horizontal_scaling ) \
+ { \
+ /* Horizontal scaling, conversion has been done to buffer. \
+ * Rewind buffer and offset, then copy and scale line */ \
+ p_buffer = p_buffer_start; \
+ p_offset = p_offset_start; \
+ for( i_x = i_pic_width / 16; i_x--; ) \
+ { \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
+ } \
+ p_pic += i_pic_line_width; \
+ } \
+ else \
+ { \
+ /* No scaling, conversion has been done directly in picture memory. \
+ * Increment of picture pointer to end of line is still needed */ \
+ p_pic += i_pic_width + i_pic_line_width; \
+ } \
+
+/*****************************************************************************
+ * SCALE_HEIGHT: handle vertical scaling
+ *****************************************************************************
+ * This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
+ * 444 for RGB conversion, or 400 for gray conversion. It works for 1, 2, 3
+ * and 4 Bpp.
+ *****************************************************************************/
+#define SCALE_HEIGHT( CHROMA, BPP ) \
+ /* If line is odd, rewind 4:2:0 U and V samples */ \
+ if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
+ { \
+ p_u -= i_chroma_width; \
+ p_v -= i_chroma_width; \
+ } \
+ \
+ /* \
+ * Handle vertical scaling. The current line can be copied or next one \
+ * can be ignored. \
+ */ \
+ switch( i_vertical_scaling ) \
+ { \
+ case -1: /* vertical scaling factor is < 1 */ \
+ while( (i_scale_count -= i_pic_height) >= 0 ) \
+ { \
+ /* Height reduction: skip next source line */ \
+ p_y += i_width; \
+ i_y++; \
+ if( (CHROMA == 420) || (CHROMA == 422) ) \
+ { \
+ if( i_y & 0x1 ) \
+ { \
+ p_u += i_chroma_width; \
+ p_v += i_chroma_width; \
+ } \
+ } \
+ else if( CHROMA == 444 ) \
+ { \
+ p_u += i_width; \
+ p_v += i_width; \
+ } \
+ } \
+ i_scale_count += i_height; \
+ break; \
+ case 1: /* vertical scaling factor is > 1 */ \
+ while( (i_scale_count -= i_height) > 0 ) \
+ { \
+ /* Height increment: copy previous picture line */ \
+ for( i_x = i_pic_width / 16; i_x--; ) \
+ { \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ if( BPP > 1 ) /* 2, 3, 4 Bpp */ \
+ { \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ } \
+ if( BPP > 2 ) /* 3, 4 Bpp */ \
+ { \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ } \
+ if( BPP > 3 ) /* 4 Bpp */ \
+ { \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
+ } \
+ } \
+ p_pic += i_pic_line_width; \
+ p_pic_start += i_pic_line_width; \
+ } \
+ i_scale_count += i_pic_height; \
+ break; \
+ } \
+
--- /dev/null
+/*****************************************************************************
+ * yuvmmx.c : Accelerated MMX YUV functions for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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> /* malloc(), free() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "interface.h"
+#include "audio_output.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "plugins_export.h"
+
+/*****************************************************************************
+ * Exported prototypes
+ *****************************************************************************/
+void yuv_GetPlugin( p_vout_thread_t p_vout );
+
+/*****************************************************************************
+ * GetConfig: get the plugin structure and configuration
+ *****************************************************************************/
+plugin_info_t * GetConfig( void )
+{
+ plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
+
+ p_info->psz_name = "Accelerated MMX YUV to RGB transformations";
+ p_info->psz_version = VERSION;
+ p_info->psz_author = "the VideoLAN team <vlc@videolan.org>";
+
+ p_info->aout_GetPlugin = NULL;
+ p_info->vout_GetPlugin = NULL;
+ p_info->intf_GetPlugin = NULL;
+ p_info->yuv_GetPlugin = yuv_GetPlugin;
+
+ return( p_info );
+}
+
+/*****************************************************************************
+ * Test: tests if the plugin can be launched
+ *****************************************************************************/
+int Test( void )
+{
+ return( 1 );
+}
+
+/*****************************************************************************
+ * Following functions are only called through the p_info structure
+ *****************************************************************************/
+
+void yuv_GetPlugin( p_vout_thread_t p_vout )
+{
+ p_vout->p_yuv_init = yuv_SysInit;
+ p_vout->p_yuv_reset = yuv_SysReset;
+ p_vout->p_yuv_end = yuv_SysEnd;
+}
+
{
ac3dec_thread_t * p_ac3dec;
- intf_DbgMsg ("ac3dec debug: creating ac3 decoder thread\n");
+ intf_DbgMsg( "ac3dec debug: creating ac3 decoder thread\n" );
/* Allocate the memory needed to store the thread's structure */
if ((p_ac3dec = (ac3dec_thread_t *)malloc (sizeof(ac3dec_thread_t))) == NULL) {
- intf_ErrMsg ("ac3dec error: not enough memory for ac3dec_CreateThread() to create the new thread\n");
+ intf_ErrMsg ( "ac3dec error: not enough memory "
+ "for ac3dec_CreateThread() to create the new thread\n");
return NULL;
}
/* Spawn the ac3 decoder thread */
if (vlc_thread_create(&p_ac3dec->thread_id, "ac3 decoder", (vlc_thread_func_t)RunThread, (void *)p_ac3dec)) {
- intf_ErrMsg ("ac3dec error: can't spawn ac3 decoder thread\n");
+ intf_ErrMsg( "ac3dec error: can't spawn ac3 decoder thread\n" );
free (p_ac3dec);
return NULL;
}
p_ac3dec->p_ts = DECODER_FIFO_START (p_ac3dec->fifo)->p_first_ts;
byte_stream = ac3_byte_stream (&p_ac3dec->ac3_decoder);
byte_stream->p_byte =
- p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_start;
+ p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_start;
byte_stream->p_end =
- p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_end;
+ p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_end;
byte_stream->info = p_ac3dec;
vlc_mutex_unlock (&p_ac3dec->fifo.data_lock);
/* ac3 decoder thread's main loop */
/* FIXME : do we have enough room to store the decoded frames ?? */
while ((!p_ac3dec->b_die) && (!p_ac3dec->b_error)) {
- s16 * buffer;
- ac3_sync_info_t sync_info;
+ s16 * buffer;
+ ac3_sync_info_t sync_info;
- if (!sync) { /* have to find a synchro point */
- int ptr;
- ac3_byte_stream_t * p_byte_stream;
+ if (!sync) { /* have to find a synchro point */
+ int ptr;
+ ac3_byte_stream_t * p_byte_stream;
- intf_Msg ("ac3dec: sync\n");
+ intf_Msg ("ac3dec: sync\n");
- p_byte_stream = ac3_byte_stream (&p_ac3dec->ac3_decoder);
+ p_byte_stream = ac3_byte_stream (&p_ac3dec->ac3_decoder);
- /* first read till next ac3 magic header */
- do {
- ac3_byte_stream_next (p_byte_stream);
- } while ((!p_ac3dec->sync_ptr) &&
- (!p_ac3dec->b_die) &&
- (!p_ac3dec->b_error));
- /* skip the specified number of bytes */
+ /* first read till next ac3 magic header */
+ do {
+ ac3_byte_stream_next (p_byte_stream);
+ } while ((!p_ac3dec->sync_ptr) &&
+ (!p_ac3dec->b_die) &&
+ (!p_ac3dec->b_error));
+ /* skip the specified number of bytes */
- ptr = p_ac3dec->sync_ptr;
- while (--ptr && (!p_ac3dec->b_die) && (!p_ac3dec->b_error)) {
- if (p_byte_stream->p_byte >= p_byte_stream->p_end) {
- ac3_byte_stream_next (p_byte_stream);
- }
- p_byte_stream->p_byte++;
- }
+ ptr = p_ac3dec->sync_ptr;
+ while (--ptr && (!p_ac3dec->b_die) && (!p_ac3dec->b_error)) {
+ if (p_byte_stream->p_byte >= p_byte_stream->p_end) {
+ ac3_byte_stream_next (p_byte_stream);
+ }
+ p_byte_stream->p_byte++;
+ }
- /* we are in sync now */
+ /* we are in sync now */
- sync = 1;
- p_ac3dec->sync_ptr = 0;
- }
+ sync = 1;
+ p_ac3dec->sync_ptr = 0;
+ }
if (DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts) {
- p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = DECODER_FIFO_START(p_ac3dec->fifo)->i_pts;
- DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts = 0;
+ p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = DECODER_FIFO_START(p_ac3dec->fifo)->i_pts;
+ DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts = 0;
} else {
- p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE;
+ p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE;
}
if (ac3_sync_frame (&p_ac3dec->ac3_decoder, &sync_info)) {
- sync = 0;
- goto bad_frame;
- }
+ sync = 0;
+ goto bad_frame;
+ }
- p_ac3dec->p_aout_fifo->l_rate = sync_info.sample_rate;
+ p_ac3dec->p_aout_fifo->l_rate = sync_info.sample_rate;
- buffer = ((s16 *)p_ac3dec->p_aout_fifo->buffer) + (p_ac3dec->p_aout_fifo->l_end_frame * AC3DEC_FRAME_SIZE);
+ buffer = ((s16 *)p_ac3dec->p_aout_fifo->buffer) + (p_ac3dec->p_aout_fifo->l_end_frame * AC3DEC_FRAME_SIZE);
- if (ac3_decode_frame (&p_ac3dec->ac3_decoder, buffer)) {
- sync = 0;
- goto bad_frame;
- }
+ if (ac3_decode_frame (&p_ac3dec->ac3_decoder, buffer)) {
+ sync = 0;
+ goto bad_frame;
+ }
- vlc_mutex_lock (&p_ac3dec->p_aout_fifo->data_lock);
- p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
- vlc_cond_signal (&p_ac3dec->p_aout_fifo->data_wait);
- vlc_mutex_unlock (&p_ac3dec->p_aout_fifo->data_lock);
+ vlc_mutex_lock (&p_ac3dec->p_aout_fifo->data_lock);
+ p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
+ vlc_cond_signal (&p_ac3dec->p_aout_fifo->data_wait);
+ vlc_mutex_unlock (&p_ac3dec->p_aout_fifo->data_lock);
bad_frame:
}
/* We are looking for the next TS packet that contains real data,
* and not just a PES header */
do {
- /* We were reading the last TS packet of this PES packet... It's
- * time to jump to the next PES packet */
- if (p_ac3dec->p_ts->p_next_ts == NULL) {
- int ptr;
-
- /* We are going to read/write the start and end indexes of the
- * decoder fifo and to use the fifo's conditional variable,
- * that's why we need to take the lock before */
- vlc_mutex_lock (&p_ac3dec->fifo.data_lock);
-
- /* Is the input thread dying ? */
- if (p_ac3dec->p_input->b_die) {
- vlc_mutex_unlock (&(p_ac3dec->fifo.data_lock));
- return;
- }
-
- /* We should increase the start index of the decoder fifo, but
+ /* We were reading the last TS packet of this PES packet... It's
+ * time to jump to the next PES packet */
+ if (p_ac3dec->p_ts->p_next_ts == NULL) {
+ int ptr;
+
+ /* We are going to read/write the start and end indexes of the
+ * decoder fifo and to use the fifo's conditional variable,
+ * that's why we need to take the lock before */
+ vlc_mutex_lock (&p_ac3dec->fifo.data_lock);
+
+ /* Is the input thread dying ? */
+ if (p_ac3dec->p_input->b_die) {
+ vlc_mutex_unlock (&(p_ac3dec->fifo.data_lock));
+ return;
+ }
+
+ /* We should increase the start index of the decoder fifo, but
* if we do this now, the input thread could overwrite the
* pointer to the current PES packet, and we weren't able to
* give it back to the netlist. That's why we free the PES
* packet first. */
- input_NetlistFreePES (p_ac3dec->p_input, DECODER_FIFO_START(p_ac3dec->fifo));
-
- DECODER_FIFO_INCSTART (p_ac3dec->fifo);
-
- while (DECODER_FIFO_ISEMPTY(p_ac3dec->fifo)) {
- vlc_cond_wait (&p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock);
-
- if (p_ac3dec->p_input->b_die) {
- vlc_mutex_unlock (&(p_ac3dec->fifo.data_lock));
- return;
- }
- }
-
- /* The next byte could be found in the next PES packet */
- p_ac3dec->p_ts = DECODER_FIFO_START (p_ac3dec->fifo)->p_first_ts;
-
- /* parse ac3 magic header */
- ptr = p_ac3dec->p_ts->buffer [p_ac3dec->p_ts->i_payload_start+2];
- ptr <<= 8;
- ptr |= p_ac3dec->p_ts->buffer [p_ac3dec->p_ts->i_payload_start+3];
- p_ac3dec->sync_ptr = ptr;
- p_ac3dec->p_ts->i_payload_start += 4;
-
- /* We can release the fifo's data lock */
- vlc_mutex_unlock (&p_ac3dec->fifo.data_lock);
- }
-
- /* Perhaps the next TS packet of the current PES packet contains
- * real data (ie its payload's size is greater than 0) */
- else {
- p_ac3dec->p_ts = p_ac3dec->p_ts->p_next_ts;
- }
+ input_NetlistFreePES (p_ac3dec->p_input, DECODER_FIFO_START(p_ac3dec->fifo));
+
+ DECODER_FIFO_INCSTART (p_ac3dec->fifo);
+
+ while (DECODER_FIFO_ISEMPTY(p_ac3dec->fifo)) {
+ vlc_cond_wait (&p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock);
+
+ if (p_ac3dec->p_input->b_die) {
+ vlc_mutex_unlock (&(p_ac3dec->fifo.data_lock));
+ return;
+ }
+ }
+
+ /* The next byte could be found in the next PES packet */
+ p_ac3dec->p_ts = DECODER_FIFO_START (p_ac3dec->fifo)->p_first_ts;
+
+ /* parse ac3 magic header */
+ ptr = p_ac3dec->p_ts->buffer [p_ac3dec->p_ts->i_payload_start+2];
+ ptr <<= 8;
+ ptr |= p_ac3dec->p_ts->buffer [p_ac3dec->p_ts->i_payload_start+3];
+ p_ac3dec->sync_ptr = ptr;
+ p_ac3dec->p_ts->i_payload_start += 4;
+
+ /* We can release the fifo's data lock */
+ vlc_mutex_unlock (&p_ac3dec->fifo.data_lock);
+ }
+
+ /* Perhaps the next TS packet of the current PES packet contains
+ * real data (ie its payload's size is greater than 0) */
+ else {
+ p_ac3dec->p_ts = p_ac3dec->p_ts->p_next_ts;
+ }
} while (p_ac3dec->p_ts->i_payload_start == p_ac3dec->p_ts->i_payload_end);
p_byte_stream->p_byte =
- p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_start;
+ p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_start;
p_byte_stream->p_end =
- p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_end;
+ p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_end;
}
#include <stdio.h> /* "intf_msg.h" */
-#include "int_types.h"
+#include "common.h"
+
#include "ac3_decoder.h"
#include "ac3_internal.h"
#include "ac3_bit_stream.h"
+#include "intf_msg.h"
+
#define Q0 ((-2 << 15) / 3.0)
#define Q1 (0)
#define Q2 ((2 << 15) / 3.0)
aout_thread_t *aout_CreateThread( int *pi_status )
{
aout_thread_t * p_aout; /* thread descriptor */
- char * psz_method;
+ typedef void ( aout_getplugin_t ) ( aout_thread_t * p_aout );
+ int i_index;
#if 0
int i_status; /* thread status */
#endif
return( NULL );
}
- /* Request an interface plugin */
- psz_method = main_GetPszVariable( AOUT_METHOD_VAR, AOUT_DEFAULT_METHOD );
-
- if( RequestPlugin( &p_aout->aout_plugin, psz_method ) )
+ /* Get a suitable audio plugin */
+ for( i_index = 0 ; i_index < p_main->p_bank->i_plugin_count ; i_index++ )
{
- intf_ErrMsg( "error: could not open audio plugin %s.so\n", psz_method );
- free( p_aout );
- return( NULL );
+ /* If there's a plugin in p_info ... */
+ if( p_main->p_bank->p_info[ i_index ] != NULL )
+ {
+ /* ... and if this plugin provides the functions we want ... */
+ if( p_main->p_bank->p_info[ i_index ]->aout_GetPlugin != NULL )
+ {
+ /* ... then get these functions */
+ ( (aout_getplugin_t *)
+ p_main->p_bank->p_info[ i_index ]->aout_GetPlugin )( p_aout );
+ }
+ }
}
- /* Get plugins */
- p_aout->p_sys_open = GetPluginFunction( p_aout->aout_plugin, "aout_SysOpen" );
- p_aout->p_sys_reset = GetPluginFunction( p_aout->aout_plugin, "aout_SysReset" );
- p_aout->p_sys_setformat = GetPluginFunction( p_aout->aout_plugin, "aout_SysSetFormat" );
- p_aout->p_sys_setchannels = GetPluginFunction( p_aout->aout_plugin, "aout_SysSetChannels" );
- p_aout->p_sys_setrate = GetPluginFunction( p_aout->aout_plugin, "aout_SysSetRate" );
- p_aout->p_sys_getbufinfo = GetPluginFunction( p_aout->aout_plugin, "aout_SysGetBufInfo" );
- p_aout->p_sys_playsamples = GetPluginFunction( p_aout->aout_plugin, "aout_SysPlaySamples" );
- p_aout->p_sys_close = GetPluginFunction( p_aout->aout_plugin, "aout_SysClose" );
-
/*
* Initialize audio device
*/
if ( p_aout->p_sys_open( p_aout ) )
{
- TrashPlugin( p_aout->aout_plugin );
free( p_aout );
return( NULL );
}
if ( p_aout->p_sys_reset( p_aout ) )
{
p_aout->p_sys_close( p_aout );
- TrashPlugin( p_aout->aout_plugin );
free( p_aout );
return( NULL );
}
if ( p_aout->p_sys_setformat( p_aout ) )
{
p_aout->p_sys_close( p_aout );
- TrashPlugin( p_aout->aout_plugin );
free( p_aout );
return( NULL );
}
if ( p_aout->p_sys_setchannels( p_aout ) )
{
p_aout->p_sys_close( p_aout );
- TrashPlugin( p_aout->aout_plugin );
free( p_aout );
return( NULL );
}
if ( p_aout->p_sys_setrate( p_aout ) )
{
p_aout->p_sys_close( p_aout );
- TrashPlugin( p_aout->aout_plugin );
free( p_aout );
return( NULL );
}
if( aout_SpawnThread( p_aout ) )
{
p_aout->p_sys_close( p_aout );
- TrashPlugin( p_aout->aout_plugin );
free( p_aout );
return( NULL );
}
p_aout->p_sys_close( p_aout );
intf_DbgMsg("aout debug: audio device (%s) closed\n", p_aout->psz_device);
- /* Close plugin */
- TrashPlugin( p_aout->aout_plugin );
-
/* Free structure */
free( p_aout );
}
}
}
#define SOUND 1
-#define DEBUG 0
+#define ADEBUG 0
#define COEFF 2
if ( p_aout->fifo[i_fifo].l_units > l_units )
{
*/
#endif
-#if DEBUG
+#if ADEBUG
//intf_DbgMsg( "p_aout->s32_buffer[l_buffer] 11 : %x (%d)",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1] );
intf_DbgMsg( "p_aout->fifo %ld\n",COEFF*p_aout->fifo[i_fifo].l_unit );
intf_DbgMsg( "%d - p_aout->s32b %ld\n", l_buffer, (s32) ( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) );
*/
#endif
-#if DEBUG
+#if ADEBUG
//intf_DbgMsg( "p_aout->s32_buffer[l_buffer] 21 : %x (%d)",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1] );
intf_DbgMsg( "p_aout->fifo %ld\n",COEFF*p_aout->fifo[i_fifo].l_unit );
intf_DbgMsg( "%d - p_aout->s32b %ld\n", l_buffer, (s32) ( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) );
{
case MPEG1_VIDEO_ES:
case MPEG2_VIDEO_ES:
-#ifdef OLD_DECODER
- vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) /*, NULL */ );
-#else
vpar_DestroyThread( (vpar_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) /*, NULL */ );
-#endif
break;
case MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES:
{
case MPEG1_VIDEO_ES:
case MPEG2_VIDEO_ES:
-#ifdef OLD_DECODER
- p_fifo = &(((vdec_thread_t*)(p_es_descriptor->p_dec))->fifo);
-#else
p_fifo = &(((vpar_thread_t*)(p_es_descriptor->p_dec))->fifo);
-#endif
break;
case MPEG1_AUDIO_ES:
break;
case AC3_AUDIO_ES:
- /* we skip 4 bytes at the beginning of the AC3 payload */
- //p_ts->i_payload_start += 4;
p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo);
break;
/*****************************************************************************
* input_DemuxPSI:
*****************************************************************************
- * Notice that current ES state has been locked by input_SortPacket. (No more true,
- * changed by benny - FIXME: See if it's ok, and definitely change the code ?? )
+ * Notice that current ES state has been locked by input_SortPacket.
+ * (No more true, changed by benny - FIXME: See if it's ok, and definitely
+ * change the code ?? )
*****************************************************************************/
static __inline__ void input_DemuxPSI( input_thread_t *p_input,
ts_packet_t *p_ts_packet,
{
int i_data_offset; /* Offset of the interesting data in the TS packet */
u16 i_data_length; /* Length of those data */
- //boolean_t b_first_section; /* Was there another section in the TS packet ? */
+ //boolean_t b_first_section; /* another section in the TS packet ? */
ASSERT(p_input);
ASSERT(p_ts_packet);
It will be set to a correct value if the data are not corrupted */
i_data_offset = TS_PACKET_SIZE;
- /* Has the reassembly of a section already began in a previous packet ? */
+ /* Has the reassembly of a section already begun in a previous packet ? */
if( p_psi->b_running_section )
{
/* Was data lost since the last TS packet ? */
if( b_packet_lost )
{
- /* Discard the packet and wait for the begining of a new one to resynch */
+ /* Discard the packet and wait for the begining of a new one
+ * to resynch */
p_psi->b_running_section = 0;
p_psi->i_current_position = 0;
intf_DbgMsg( "PSI section(s) discarded due to packet loss\n" );
if( b_unit_start )
{
/* Get the offset at which the data for that section can be found
- The offset is stored in the pointer_field since we are interested in
- the first section of the TS packet. Note that the +1 is to bypass
- the pointer field */
+ The offset is stored in the pointer_field since we are
+ interested in the first section of the TS packet. Note that
+ the +1 is to bypass the pointer field */
i_data_offset = p_ts_packet->i_payload_start +
p_ts_packet->buffer[p_ts_packet->i_payload_start] + 1;
//intf_DbgMsg( "New section beginning at offset %d in TS packet\n", i_data_offset );
}
else
{
- /* This may either mean that the TS is bad or that the packet contains
- the end of a section that had been discarded in a previous loop:
- trash the TS packet since we cannot do anything with those data: */
+ /* This may either mean that the TS is bad or that the packet
+ * contains the end of a section that had been discarded in a
+ * previous loop: trash the TS packet since we cannot do
+ * anything with those data: */
p_psi->b_running_section = 0;
p_psi->i_current_position = 0;
intf_DbgMsg( "PSI packet discarded due to lack of synchronisation\n" );
}
}
- /* The section we will deal with during the first iteration of the following
- loop is the first one contained in the TS packet */
+ /* The section we will deal with during the first iteration of the
+ * following loop is the first one contained in the TS packet */
// b_first_section = 1;
- /* Reassemble the pieces of sections contained in the TS packet and decode
- the sections that could have been completed.
- Stop when we reach the end of the packet or stuffing bytes */
+ /* Reassemble the pieces of sections contained in the TS packet and
+ * decode the sections that could have been completed.
+ * Stop when we reach the end of the packet or stuffing bytes */
while( i_data_offset < TS_PACKET_SIZE && p_ts_packet->buffer[i_data_offset] != 0xFF )
{
- /* If the current section is a new one, reinit the data fields of the p_psi
- struct to start its decoding */
+ /* If the current section is a new one, reinit the data fields of
+ * the p_psi struct to start its decoding */
if( !p_psi->b_running_section )
{
/* Read the length of the new section */
//intf_DbgMsg( "Section length %d\n", p_psi->i_length );
if( p_psi->i_length > PSI_SECTION_SIZE )
{
- /* The TS packet is corrupted, stop here to avoid possible a seg fault */
+ /* The TS packet is corrupted, stop here to avoid possible
+ * a seg fault */
intf_DbgMsg( "PSI Section size is too big, aborting its reception\n" );
break;
}
{
case AC3_AUDIO_ES:
- intf_Msg( "Start an AC3 decoder\n" );
/* Spawn ac3 thread */
if ( ((ac3dec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
ac3dec_CreateThread(p_input)) == NULL )
case LPCM_AUDIO_ES:
/* Spawn lpcm thread */
- intf_Msg ( "Start a LPCM decoder\n" );
- if ( ((lpcmdec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
- lpcmdec_CreateThread(p_input)) == NULL )
+ if ( ((lpcmdec_thread_t *)
+ (p_input->p_es[i_es_loop].p_dec) =
+ lpcmdec_CreateThread(p_input)) == NULL )
{
- intf_ErrMsg( "LPCM Debug: Could not start lpcm decoder\n" );
+ intf_ErrMsg( "LPCM Debug: Could not start "
+ "lpcm decoder\n" );
vlc_mutex_unlock( &p_input->es_lock );
return( -1 );
}
case DVD_SPU_ES:
/* Spawn spu thread */
- if ( ((spudec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
- spudec_CreateThread(p_input)) == NULL )
+ if ( ((spudec_thread_t *)
+ (p_input->p_es[i_es_loop].p_dec) =
+ spudec_CreateThread(p_input)) == NULL )
{
intf_ErrMsg( "Could not start spu decoder\n" );
vlc_mutex_unlock( &p_input->es_lock );
case MPEG1_VIDEO_ES:
case MPEG2_VIDEO_ES:
/* Spawn video thread. */
-#ifdef OLD_DECODER
- if( ((vdec_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
- vdec_CreateThread( p_input )) == NULL )
-#else
if( ((vpar_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
vpar_CreateThread( p_input )) == NULL )
-#endif
{
-#ifdef OLD_DECODER
- intf_ErrMsg("Could not start video decoder\n");
-#else
intf_ErrMsg("Could not start video parser\n");
-#endif
vlc_mutex_unlock( &p_input->es_lock );
return( -1 );
}
default:
/* That should never happen. */
- intf_DbgMsg("input error: unknown stream type (0x%.2x)\n",
+ intf_DbgMsg( "input error: unknown stream (0x%.2x)\n",
p_input->p_es[i_es_loop].i_type);
vlc_mutex_unlock( &p_input->es_lock );
return( -1 );
p_input->p_es[i_es_loop].b_random = 0;
/* Mark stream to be demultiplexed. */
- intf_DbgMsg("Stream %d added in %d\n", i_current_id, i_selected_es_loop);
- p_input->pp_selected_es[i_selected_es_loop] = &p_input->p_es[i_es_loop];
+ intf_DbgMsg( "Stream %d added in %d\n",
+ i_current_id, i_selected_es_loop);
+ p_input->pp_selected_es[i_selected_es_loop] =
+ &p_input->p_es[i_es_loop];
vlc_mutex_unlock( &p_input->es_lock );
return( 0 );
}
case MPEG1_VIDEO_ES:
case MPEG2_VIDEO_ES:
-#ifdef OLD_DECODER
- vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ );
-#else
vpar_DestroyThread( (vpar_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ );
-#endif
break;
}
#include "common.h"
#include "threads.h"
#include "mtime.h"
+#include "plugins.h"
+#include "playlist.h"
#include "intf_msg.h"
#include "main.h"
#define NO_SUBTITLES 255
#define PS_BUFFER_SIZE 16384
-#define NO_PES 0
-#define AUDIO_PES 1
-#define VIDEO_PES 2
-#define AC3_PES 3
-#define SUBTITLE_PES 4
-#define LPCM_PES 5
-#define PRIVATE_PES 6
-#define UNKNOWN_PES 12
+
+#define NO_PES 0x00
+#define AUDIO_PES 0x01
+#define VIDEO_PES 0x02
+#define AC3_PES 0x03
+#define SUBTITLE_PES 0x04
+#define LPCM_PES 0x05
+#define PRIVATE_PES 0x06
+#define UNKNOWN_PES 0x12
#define PCR_PID 0x20 /* 0x20 == first video stream
* 0x40 == first audio stream */
unsigned int pcr_pid;
u8 i_file_type;
int in;
- char **playlist;
- int i_list_index;
} options_t;
typedef struct s_ps
int file_next( options_t *options )
{
- /* the check for index == 0 should be done _before_ */
- options->i_list_index--;
-
+ p_playlist_t p_playlist = p_main->p_playlist;
+
+ /* the check for index == 0 has to be done _before_ */
+ p_playlist->i_index--;
+
if( options->in != -1 )
{
- close( options->in );
+ close( options->in );
}
- if( !strcmp( options->playlist[options->i_list_index], "-" ) )
+ if( !strcmp( p_playlist->p_list[ p_playlist->i_index ], "-" ) )
{
/* read stdin */
return ( options->in = 0 );
else
{
/* read the actual file */
- fprintf( stderr, "Playing file %s\n",
- options->playlist[options->i_list_index] );
- return ( options->in = open( options->playlist[options->i_list_index],
- O_RDONLY | O_NONBLOCK ) );
+ intf_Msg( "Playing file %s\n",
+ p_playlist->p_list[ p_playlist->i_index ] );
+
+ options->in =
+ open( p_playlist->p_list[ p_playlist->i_index ],
+ O_RDONLY | O_NONBLOCK );
+
+ return ( options->in );
}
}
if( ret == 0 )
{
/* zero means end of file */
- if( options->i_list_index )
+ if( p_main->p_playlist->i_index )
{
file_next( options );
}
/* read a whole UDP packet from the file */
p_ps->ts_to_write = how_many;
- if(ps_read(&p_if->options, p_ps, ts = (file_ts_packet *)(p_in_data->buf + p_in_data->end)) != how_many)
+ if( ps_read( &p_if->options, p_ps, ts = (file_ts_packet *)(p_in_data->buf + p_in_data->end) ) != how_many )
{
msleep( 50000 ); /* XXX we need an INPUT_IDLE */
intf_ErrMsg( "input error: read() error\n" );
+ return;
}
/* Scan to mark TS packets containing a PCR */
- for(i=0; i<how_many; i++, ts++)
+ for( i = 0 ; i < how_many ; i++ , ts++ )
{
- pcr_flag |= keep_pcr(p_ps->pcr_pid, ts);
+ pcr_flag |= keep_pcr( p_ps->pcr_pid, ts );
}
- vlc_mutex_lock(&p_in_data->lock);
+ vlc_mutex_lock( &p_in_data->lock );
p_in_data->end++;
- p_in_data->end %= BUF_SIZE+1;
- vlc_cond_signal(&p_in_data->notempty);
- vlc_mutex_unlock(&p_in_data->lock);
+ p_in_data->end %= BUF_SIZE + 1;
+ vlc_cond_signal( &p_in_data->notempty );
+ vlc_mutex_unlock( &p_in_data->lock );
}
}
{
vlc_cond_wait(&p_in_data->notempty, &p_in_data->lock);
}
- /*
- if( p_in_data->end == p_in_data->start )
- {
- intf_ErrMsg( "input error: init_synchro error, not enough PCR found\n" );
- return( -1 );
- }
- */
+
vlc_mutex_unlock( &p_in_data->lock );
ts = (file_ts_packet*)(p_in_data->buf + p_in_data->start);
for( i=0 ; i < howmany ; i++, ts++ )
{
- if( ts == p_own_pcr->buf[p_own_pcr->start] && !(((u8*)ts)[5] & 0x80) )
+ if( ts == p_own_pcr->buf[p_own_pcr->start] && !(((u8*)ts)[5] & 0x80) )
{
p_synchro->last_pcr = ts;
p_synchro->last_pcr_time = ConvertPCRTime( ts );
p_options->in = -1;
- p_options->playlist = (char **)p_input->p_source;
- p_options->i_list_index = p_input->i_port;
-
if( file_next( p_options ) < 0 )
{
intf_ErrMsg( "input error: cannot open the file %s", p_input->p_source );
#include "input_vlan.h"
#include "intf_msg.h"
+#include "plugins.h"
#include "main.h"
/*****************************************************************************
#include "threads.h"
#include "mtime.h"
#include "intf_msg.h"
+#include "plugins.h"
#include "debug.h"
#include "input.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
+#include "plugins.h"
#include "netutils.h"
#include "input_vlan.h"
#include "intf_msg.h"
+
#include "main.h"
/*****************************************************************************
#include "threads.h"
#include "mtime.h"
#include "plugins.h"
+#include "playlist.h"
#include "input.h"
#include "audio_output.h"
*****************************************************************************/
intf_thread_t* intf_Create( void )
{
- intf_thread_t *p_intf;
- char * psz_method;
+ intf_thread_t * p_intf;
+ typedef void ( intf_getplugin_t ) ( intf_thread_t * p_intf );
+ int i_index;
/* Allocate structure */
p_intf = malloc( sizeof( intf_thread_t ) );
return( NULL );
}
- /* Request an interface plugin */
- psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD );
-
- if( RequestPlugin( &p_intf->intf_plugin, psz_method ) < 0 )
+ /* Get a suitable interface plugin */
+ for( i_index = 0 ; i_index < p_main->p_bank->i_plugin_count ; i_index++ )
{
- intf_ErrMsg( "error: could not open interface plugin %s.so\n", psz_method );
- free( p_intf );
- return( NULL );
+ /* If there's a plugin in p_info ... */
+ if( p_main->p_bank->p_info[ i_index ] != NULL )
+ {
+ /* ... and if this plugin provides the functions we want ... */
+ if( p_main->p_bank->p_info[ i_index ]->intf_GetPlugin != NULL )
+ {
+ /* ... then get these functions */
+ ( (intf_getplugin_t *)
+ p_main->p_bank->p_info[ i_index ]->intf_GetPlugin )( p_intf );
+ }
+ }
}
- /* Get plugins */
- p_intf->p_sys_create
- = GetPluginFunction( p_intf->intf_plugin, "intf_SysCreate" );
- p_intf->p_sys_manage
- = GetPluginFunction( p_intf->intf_plugin, "intf_SysManage" );
- p_intf->p_sys_destroy
- = GetPluginFunction( p_intf->intf_plugin, "intf_SysDestroy" );
-
/* Initialize structure */
p_intf->b_die = 0;
p_intf->p_vout = NULL;
if( p_intf->p_console == NULL )
{
intf_ErrMsg("error: can't create control console\n");
- TrashPlugin( p_intf->intf_plugin );
free( p_intf );
return( NULL );
}
{
intf_ErrMsg("error: can't create interface\n");
intf_ConsoleDestroy( p_intf->p_console );
- TrashPlugin( p_intf->intf_plugin );
free( p_intf );
return( NULL );
}
*****************************************************************************/
void intf_Run( intf_thread_t *p_intf )
{
- if( p_intf->p_playlist )
+ if( p_main->p_playlist->p_list )
{
- p_intf->p_input = input_CreateThread( INPUT_METHOD_TS_FILE, (void *)p_intf->p_playlist, p_intf->i_list_index, 0, p_main->p_intf->p_vout, p_main->p_aout, NULL );
+ p_intf->p_input = input_CreateThread( INPUT_METHOD_TS_FILE, NULL, 0, 0, p_main->p_intf->p_vout, p_main->p_aout, NULL );
}
/* Execute the initialization script - if a positive number is returned,
* the script could be executed but failed */
/* Unload channels */
UnloadChannels( p_intf );
- /* XXX: Close plugin - we don't do it because it makes the Gnome
- * plugin segfaulting */
- /*TrashPlugin( p_intf->intf_plugin );*/
-
- /* Close plugin */
- TrashPlugin( p_intf->intf_plugin );
-
/* Free structure */
free( p_intf );
}
p_file = fopen( psz_filename, "r" );
if( p_file == NULL )
{
- intf_ErrMsg("warning: %s: %s\n", psz_filename, strerror(errno));
+ intf_DbgMsg("intf warning: %s: %s\n", psz_filename, strerror(errno));
return( -1 );
}
int i_port = 0; /* port parameter */
int i_vlan = 0; /* vlan parameter */
- fprintf( stderr, "spawn input\n" );
-
/* Parse parameters - see command list above */
for ( i_arg = 1; i_arg < i_argc; i_arg++ )
{
{
int i_command; /* command argument number */
- /* Do not try anything if vlans are desactivated */
+ /* Do not try anything if vlans are deactivated */
if( !p_main->b_vlans )
{
- intf_IntfMsg("vlans are desactivated");
+ intf_IntfMsg("vlans are deactivated");
return( INTF_OTHER_ERROR );
}
#include "threads.h"
#include "mtime.h"
#include "plugins.h"
+#include "playlist.h"
#include "input_vlan.h"
#include "input_ps.h"
* Local prototypes
*****************************************************************************/
static void SetDefaultConfiguration ( void );
-static int GetConfiguration ( int i_argc, char *ppsz_argv[], char *ppsz_env[] );
+static int GetConfiguration ( int i_argc, char *ppsz_argv[],
+ char *ppsz_env[] );
static void Usage ( int i_fashion );
static void Version ( void );
*****************************************************************************
* Steps during program execution are:
* -configuration parsing and messages interface initialization
- * -openning of audio output device and some global modules
+ * -opening of audio output device and some global modules
* -execution of interface, which exit on error or on user request
* -closing of audio output device and some global modules
- * On error, the spawned threads are cancelled, and the open devices closed.
+ * On error, the spawned threads are canceled, and the open devices closed.
*****************************************************************************/
int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
{
main_t main_data; /* root of all data - see main.h */
- char **p_playlist;
- int i_list_index;
p_main = &main_data; /* set up the global variable */
+#ifdef SYS_BEOS
/*
* System specific initialization code
*/
-#ifdef SYS_BEOS
- beos_Init();
+ beos_Create();
#endif
+#ifdef HAVE_MMX
/*
- * Read configuration, initialize messages interface and set up program
+ * Test if our code is likely to run on this CPU
*/
-#ifdef HAVE_MMX
if( !TestMMX() )
{
- fprintf( stderr, "Sorry, this program needs an MMX processor. Please run the non-MMX version.\n" );
+ fprintf( stderr, "Sorry, this program needs an MMX processor. "
+ "Please run the non-MMX version.\n" );
return( 1 );
}
#endif
+
+ /*
+ * Initialize messages interface
+ */
p_main->p_msg = intf_MsgCreate();
if( !p_main->p_msg ) /* start messages interface */
{
- fprintf( stderr, "critical error: can't initialize messages interface (%s)\n",
+ fprintf( stderr, "error: can't initialize messages interface (%s)\n",
strerror(errno) );
return( errno );
}
+
+ /*
+ * Read configuration
+ */
if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) ) /* parse cmd line */
{
intf_MsgDestroy();
+ fprintf( stderr, "error: can't read configuration (%s)\n",
+ strerror(errno) );
return( errno );
}
- /* get command line files */
- i_list_index = 0;
-
- if( optind < i_argc )
+ /*
+ * Initialize playlist and get commandline files
+ */
+ p_main->p_playlist = playlist_Create( );
+ if( !p_main->p_playlist )
{
- int i_index = 0;
- p_playlist = malloc( (i_list_index = i_argc - optind)
- * sizeof(int) );
-
- while( i_argc - i_index > optind )
- {
- p_playlist[ i_index ] = ppsz_argv[ i_argc - i_index - 1];
- i_index++;
- }
+ intf_Msg( "Playlist initialization failed\n" );
+ intf_MsgDestroy();
+ return( errno );
}
- else
+ playlist_Init( p_main->p_playlist, optind );
+
+ /*
+ * Initialize plugin bank
+ */
+ p_main->p_bank = bank_Create( );
+ if( !p_main->p_bank )
{
- p_playlist = NULL;
+ intf_Msg( "Plugin bank initialization failed\n" );
+ playlist_Destroy( p_main->p_playlist );
+ intf_MsgDestroy();
+ return( errno );
}
-
- intf_MsgImm( COPYRIGHT_MESSAGE "\n" ); /* print welcome message */
+ bank_Init( p_main->p_bank );
/*
* Initialize shared resources and libraries
*/
- if( main_data.b_vlans && input_VlanCreate() )
+ if( p_main->b_vlans && input_VlanCreate() )
{
- /* On error during vlans initialization, switch of vlans */
- intf_Msg( "Virtual LANs initialization failed : vlans management is deactivated\n" );
- main_data.b_vlans = 0;
+ /* On error during vlans initialization, switch off vlans */
+ intf_Msg( "Virtual LANs initialization failed : "
+ "vlans management is deactivated\n" );
+ p_main->b_vlans = 0;
}
/*
* Open audio device and start aout thread
*/
- if( main_data.b_audio )
+ if( p_main->b_audio )
{
- main_data.p_aout = aout_CreateThread( NULL );
- if( main_data.p_aout == NULL )
+ p_main->p_aout = aout_CreateThread( NULL );
+ if( p_main->p_aout == NULL )
{
- /* On error during audio initialization, switch of audio */
+ /* On error during audio initialization, switch off audio */
intf_Msg( "Audio initialization failed : audio is deactivated\n" );
- main_data.b_audio = 0;
+ p_main->b_audio = 0;
}
}
/*
* Run interface
*/
- main_data.p_intf = intf_Create();
- if( main_data.p_intf != NULL )
+ p_main->p_intf = intf_Create();
+ if( p_main->p_intf != NULL )
{
- main_data.p_intf->p_playlist = p_playlist;
- main_data.p_intf->i_list_index = i_list_index;
-
InitSignalHandler(); /* prepare signals for interception */
- intf_Run( main_data.p_intf );
- intf_Destroy( main_data.p_intf );
+ intf_Run( p_main->p_intf );
+
+ intf_Destroy( p_main->p_intf );
}
/*
* Close audio device
*/
- if( main_data.b_audio )
+ if( p_main->b_audio )
{
- aout_DestroyThread( main_data.p_aout, NULL );
+ aout_DestroyThread( p_main->p_aout, NULL );
}
/*
* Free shared resources and libraries
*/
- if( main_data.b_vlans )
+ if( p_main->b_vlans )
{
input_VlanDestroy();
}
/*
- * System specific cleaning code
+ * Free plugin bank
*/
+ bank_Destroy( p_main->p_bank );
+
+ /*
+ * Free playlist
+ */
+ playlist_Destroy( p_main->p_playlist );
+
#ifdef SYS_BEOS
- beos_Clean();
+ /*
+ * System specific cleaning code
+ */
+ beos_Destroy();
#endif
/*
*/
intf_Msg( "Program terminated.\n" );
intf_MsgDestroy();
+
return( 0 );
}
static void Usage( int i_fashion )
{
/* Usage */
- intf_Msg( "Usage: vlc [options] [parameters]\n" );
+ intf_Msg( "Usage: vlc [options] [parameters] [file]...\n" );
if( i_fashion == USAGE )
{
* TestMMX: tests if the processor has MMX support.
*****************************************************************************
* This function is called if HAVE_MMX is enabled, to check whether the
- * cpu really supports MMX.
+ * CPU really supports MMX.
*****************************************************************************/
static int TestMMX( void )
{
-/* FIXME: under beos, gcc does not support the foolowing inline assembly */
+/* FIXME: under beos, gcc does not support the following inline assembly */
#ifdef SYS_BEOS
return( 1 );
#else
int i_reg, i_dummy = 0;
- /* test for a 386 cpu */
+ /* test for a 386 CPU */
asm volatile ( "pushfl
popl %%eax
movl %%eax, %%ecx
if( !i_reg )
return( 0 );
- /* test for a 486 cpu */
+ /* test for a 486 CPU */
asm volatile ( "movl %%ecx, %%eax
xorl $0x200000, %%eax
pushl %%eax
if( !i_reg )
return( 0 );
- /* the cpu supports the CPUID instruction - get its level */
+ /* the CPU supports the CPUID instruction - get its level */
asm volatile ( "cpuid"
: "=a" ( i_reg ),
"=b" ( i_dummy ),
: "a" ( 0 ), /* level 0 */
"b" ( i_dummy ) ); /* buggy compiler shouldn't complain */
- /* this shouldn't happen on a normal cpu */
+ /* this shouldn't happen on a normal CPU */
if( !i_reg )
return( 0 );
delete BeApp;
}
-void beos_Init( void )
+void beos_Create( void )
{
int i_lenght;
BPath path;
strcpy( psz_beos_program_path, path.Path() );
}
-void beos_Clean( void )
+void beos_Destroy( void )
{
free( psz_beos_program_path ); /* XXX */
be_app->PostMessage( B_QUIT_REQUESTED );
--- /dev/null
+/*****************************************************************************
+ * playlist.c : Playlist management functions
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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.
+ *****************************************************************************/
+#include "defs.h"
+
+#include "config.h"
+
+#include <stdlib.h> /* free(), strtol() */
+#include <stdio.h> /* sprintf() */
+#include <string.h> /* strerror() */
+#include <errno.h> /* ENOMEM */
+
+#include "common.h"
+
+#include "intf_msg.h"
+#include "playlist.h"
+
+#include "main.h"
+
+/* Local prototypes */
+//int TestPlugin ( plugin_id_t *p_plugin_id, char * psz_name );
+//int AllocatePlugin ( plugin_id_t plugin_id, plugin_bank_t * p_bank );
+
+playlist_t * playlist_Create ( void )
+{
+ playlist_t *p_playlist;
+
+ /* Allocate structure */
+ p_playlist = malloc( sizeof( playlist_t ) );
+ if( !p_playlist )
+ {
+ intf_ErrMsg("playlist error: %s\n", strerror( ENOMEM ) );
+ return( NULL );
+ }
+
+ p_playlist->i_index = 0;
+ p_playlist->p_list = NULL;
+
+ intf_Msg("Playlist initialized\n");
+ return( p_playlist );
+}
+
+void playlist_Init( playlist_t * p_playlist, int i_optind )
+{
+ int i_list_index = 0;
+ int i_index = 0;
+ int i_argc = p_main->i_argc;
+
+ if( i_optind < i_argc )
+ {
+ i_list_index = i_argc - i_optind;
+
+ p_playlist->p_list = malloc( i_list_index * sizeof( int ) );
+
+ while( i_argc - i_index > i_optind )
+ {
+ p_playlist->p_list[ i_index ] =
+ p_main->ppsz_argv[ i_argc - i_index - 1];
+ i_index++;
+ }
+ }
+ else
+ {
+ /* if no file was asked, get stream from the network */
+ p_playlist->p_list = NULL;
+ }
+
+ p_main->p_playlist->i_index = i_list_index;
+}
+
+void playlist_Destroy( playlist_t * p_playlist )
+{
+ free( p_playlist );
+}
+
+/*
+ * Following functions are local
+ */
+
*****************************************************************************/
#include "defs.h"
+#include "config.h"
+
#include <stdlib.h> /* free(), strtol() */
#include <stdio.h> /* sprintf() */
+#include <string.h> /* strerror() */
+#include <errno.h> /* ENOMEM */
#if defined(HAVE_DLFCN_H) /* Linux, BSD, Hurd */
#include <dlfcn.h> /* dlopen(), dlsym(), dlclose() */
#include "beos_specific.h"
#endif
+#include "common.h"
+
+#include "intf_msg.h"
#include "plugins.h"
-#define PLUGIN_PATH_COUNT 3
+/* Local prototypes */
+char * TestPlugin ( plugin_id_t *p_plugin_id, char * psz_name );
+int AllocatePlugin ( plugin_id_t plugin_id, plugin_bank_t * p_bank,
+ char * psz_filename );
+
+plugin_bank_t * bank_Create( void )
+{
+ plugin_bank_t *p_bank;
+ int i;
+
+ /* Allocate structure */
+ p_bank = malloc( sizeof( plugin_bank_t ) );
+ if( !p_bank )
+ {
+ intf_ErrMsg("plugin bank error: %s\n", strerror( ENOMEM ) );
+ return( NULL );
+ }
+
+ /* Initialize structure */
+ for( i = 0 ; i < MAX_PLUGIN_COUNT ; i++ )
+ {
+ p_bank->p_info[ i ] = NULL;
+ }
+ p_bank->i_plugin_count = MAX_PLUGIN_COUNT;
+
+ intf_Msg("Plugin bank initialized\n");
+ return( p_bank );
+}
+
+void bank_Init( plugin_bank_t * p_bank )
+{
+ plugin_id_t tmp;
+ char * psz_filename;
+
+ /* FIXME: we should browse all directories to get plugins */
+#define SEEK_PLUGIN( name ) \
+ psz_filename = TestPlugin( &tmp, name ); \
+ if( psz_filename ) AllocatePlugin( tmp, p_bank, psz_filename );
+
+ SEEK_PLUGIN( "beos" );
+ SEEK_PLUGIN( "x11" );
+ SEEK_PLUGIN( "dsp" );
+ SEEK_PLUGIN( "gnome" );
+ SEEK_PLUGIN( "ggi" );
+ SEEK_PLUGIN( "fb" );
+ SEEK_PLUGIN( "yuvmmx" );
+ SEEK_PLUGIN( "yuv" );
+ SEEK_PLUGIN( "dummy" );
+
+#undef SEEK_PLUGIN
+}
+
+void bank_Destroy( plugin_bank_t * p_bank )
+{
+ free( p_bank );
+}
+
+/*
+ * Following functions are local
+ */
+
+int AllocatePlugin( plugin_id_t plugin_id, plugin_bank_t * p_bank,
+ char * psz_filename )
+{
+ typedef plugin_info_t * ( get_config_t ) ( void );
+ get_config_t * p_func;
+ int i;
+
+ for( i = 0 ; i < p_bank->i_plugin_count ; i++ )
+ {
+ if( p_bank->p_info[ i ] == NULL )
+ {
+ break;
+ }
+ }
+
+ /* no room to store that plugin, quit */
+ if( i == p_bank->i_plugin_count )
+ {
+ intf_ErrMsg( "plugin bank error: reached max plugin count (%i), "
+ "increase MAX_PLUGIN_COUNT\n", p_bank->i_plugin_count );
+ return( -1 );
+ }
+
+ /* system-specific dynamic symbol loading */
+ GET_PLUGIN( p_func, plugin_id, "GetConfig" );
+
+ /* if it failed, just quit */
+ if( !p_func )
+ {
+ return( -1 );
+ }
+
+ /* run the plugin function to initialize the structure */
+ p_bank->p_info[ i ] = p_func( );
+ p_bank->p_info[ i ]->plugin_id = plugin_id;
+
+ /* Tell the world we found it */
+ intf_Msg( "Found plugin: %s (version %s)\n", p_bank->p_info[ i ]->psz_name,
+ p_bank->p_info[ i ]->psz_version );
+
+ /* return nicely */
+ return( 0 );
+}
-int RequestPlugin ( plugin_id_t * p_plugin, char * psz_name )
+
+char * TestPlugin ( plugin_id_t *p_plugin_id, char * psz_name )
{
int i_count, i_length;
char * psz_plugin;
- char * psz_plugin_path[ PLUGIN_PATH_COUNT ] =
+ char * psz_plugin_path[ ] =
{
".",
"lib", /* this one should disappear */
- PLUGIN_PATH
+ PLUGIN_PATH,
+ NULL
};
i_length = strlen( psz_name );
- for ( i_count = 0 ; i_count < PLUGIN_PATH_COUNT ; i_count++ )
+ for ( i_count = 0 ; psz_plugin_path[ i_count ] ; i_count++ )
{
#ifdef SYS_BEOS
char * psz_program_path;
sprintf( psz_plugin, "%s/%s/%s.so", psz_program_path,
psz_plugin_path[i_count], psz_name );
- *p_plugin = load_add_on( psz_plugin );
+ *p_plugin_id = load_add_on( psz_plugin );
#else
psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + i_length + 5 );
sprintf( psz_plugin, "%s/%s.so", psz_plugin_path[i_count], psz_name );
- *p_plugin = dlopen( psz_plugin, RTLD_NOW | RTLD_GLOBAL );
+ *p_plugin_id = dlopen( psz_plugin, RTLD_NOW | RTLD_GLOBAL );
#endif
- free( psz_plugin );
-
-#if defined(HAVE_DLFCN_H)
- if( *p_plugin != NULL )
-#elif defined(HAVE_IMAGE_H)
- if( *p_plugin >= 0 )
+#ifdef SYS_BEOS
+ if( *p_plugin_id >= 0 )
+#else
+ if( *p_plugin_id != NULL )
#endif
{
- return( 0 );
+ /* plugin successfuly dlopened */
+ return( psz_plugin );
+ }
+#ifndef SYS_BEOS
+ else
+ {
+ intf_DbgMsg( "%s\n", dlerror() );
}
+#endif
+
+ free( psz_plugin );
}
- return( -1 );
+ return( NULL );
}
-void TrashPlugin ( plugin_id_t plugin )
+#if 0
+void TrashPlugin ( plugin_id_t plugin_id )
{
-#if defined(HAVE_DLFCN_H)
- dlclose( plugin );
-#elif defined(HAVE_IMAGE_H)
- unload_add_on( plugin );
+#ifdef SYS_BEOS
+ unload_add_on( plugin_id );
+#else
+ dlclose( plugin_id );
#endif
}
-
-void * GetPluginFunction ( plugin_id_t plugin, char *psz_name )
-{
-#if defined(HAVE_DLFCN_H)
- return( dlsym(plugin, psz_name) );
-#elif defined(HAVE_IMAGE_H)
- void * p_func;
- if( get_image_symbol( plugin, psz_name, B_SYMBOL_TYPE_TEXT, &p_func ) )
- return( NULL );
- else
- return( p_func );
#endif
-}
*****************************************************************************/
void spudec_DestroyThread( spudec_thread_t *p_spudec )
{
- intf_DbgMsg("spudec debug: requesting termination of spu decoder thread %p\n", p_spudec);
+ intf_DbgMsg( "spudec debug: requesting termination of "
+ "spu decoder thread %p\n", p_spudec);
/* Ask thread to kill itself */
p_spudec->b_die = 1;
/*****************************************************************************
* RunThread: spu decoder thread
*****************************************************************************
- * spu decoder thread. This function does only return when the thread is
+ * spu decoder thread. This function only returns when the thread is
* terminated.
*****************************************************************************/
static void RunThread( spudec_thread_t *p_spudec )
while( !DECODER_FIFO_ISEMPTY(p_spudec->fifo) )
{
/* wait for the next SPU ID.
- * XXX: We trash 0xff bytes since they come from
+ * XXX: We trash 0xff bytes since they probably come from
* an incomplete previous packet */
do
{
switch( i_cmd )
{
- case 0x00:
+ case SPU_CMD_FORCE_DISPLAY:
/* 00 (force displaying) */
break;
/* FIXME: here we have to calculate dates. It's
* around i_date * 12000 but I don't know
* how much exactly.
*/
- case 0x01:
+ case SPU_CMD_START_DISPLAY:
/* 01 (start displaying) */
p_spu->begin_date += ( i_date * 12000 );
break;
- case 0x02:
+ case SPU_CMD_STOP_DISPLAY:
/* 02 (stop displaying) */
p_spu->end_date += ( i_date * 12000 );
break;
- case 0x03:
+ case SPU_CMD_SET_PALETTE:
/* 03xxxx (palette) */
GetWord( i_word );
break;
- case 0x04:
+ case SPU_CMD_SET_ALPHACHANNEL:
/* 04xxxx (alpha channel) */
GetWord( i_word );
break;
- case 0x05:
+ case SPU_CMD_SET_COORDINATES:
/* 05xxxyyyxxxyyy (coordinates) */
i_word = GetByte( &p_spudec->bit_stream );
p_spu->i_x = (i_word << 4)
i_index += 6;
break;
- case 0x06:
+ case SPU_CMD_SET_OFFSETS:
/* 06xxxxyyyy (byte offsets) */
GetWord( i_word );
p_spu->type.spu.i_offset[0] = i_word - 4;
GetWord( i_word );
p_spu->type.spu.i_offset[1] = i_word - 4;
break;
- case 0xff:
+ case SPU_CMD_END:
/* ff (end) */
break;
default:
/* ?? (unknown command) */
+ intf_ErrMsg( "spudec: unknown command 0x%.2x\n",
+ i_cmd );
break;
}
}
- while( i_cmd != 0xff );
+ while( i_cmd != SPU_CMD_END );
}
while( !b_finished );
- /* SPU is finished - we can display it */
+ /* SPU is finished - we can tell the video output
+ * to display it */
vout_DisplaySubPicture( p_spudec->p_vout, p_spu );
}
else
} \
} \
}
+
/*****************************************************************************
* vdec_MotionComponent : last stage of motion compensation
*****************************************************************************/
}
/*****************************************************************************
- * vdec_MotionField16x8XXX?? : motion compensation for 16x8 motion type (field)
+ * vdec_MotionField16x8XXX: motion compensation for 16x8 motion type (field)
*****************************************************************************/
#define FIELD16X8( MOTION ) \
{ \
/*****************************************************************************
- * vdec_motion.c : motion compensation routines
+ * vdec_motion_inner.c : motion compensation inner routines
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
int i_method, void *p_data )
{
vout_thread_t * p_vout; /* thread descriptor */
+ typedef void ( vout_getplugin_t ) ( vout_thread_t * p_vout );
int i_status; /* thread status */
int i_index; /* index for array initialization */
- char * psz_method;
/* Allocate descriptor */
intf_DbgMsg("\n");
return( NULL );
}
- /* Request an interface plugin */
- psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD );
+ p_vout->p_set_palette = SetPalette;
- if( RequestPlugin( &p_vout->vout_plugin, psz_method ) < 0 )
+ /* Get a suitable video plugin */
+ for( i_index = 0 ; i_index < p_main->p_bank->i_plugin_count ; i_index++ )
{
- intf_ErrMsg( "error: could not open video plugin %s.so\n", psz_method );
- free( p_vout );
- return( NULL );
+ /* If there's a plugin in p_info ... */
+ if( p_main->p_bank->p_info[ i_index ] != NULL )
+ {
+ /* ... and if this plugin provides the functions we want ... */
+ if( p_main->p_bank->p_info[ i_index ]->vout_GetPlugin != NULL )
+ {
+ /* ... then get these functions */
+ ( (vout_getplugin_t *)
+ p_main->p_bank->p_info[ i_index ]->vout_GetPlugin )( p_vout );
+ }
+ }
}
- /* Get plugins */
- p_vout->p_sys_create =
- GetPluginFunction( p_vout->vout_plugin, "vout_SysCreate" );
- p_vout->p_sys_init =
- GetPluginFunction( p_vout->vout_plugin, "vout_SysInit" );
- p_vout->p_sys_end =
- GetPluginFunction( p_vout->vout_plugin, "vout_SysEnd" );
- p_vout->p_sys_destroy =
- GetPluginFunction( p_vout->vout_plugin, "vout_SysDestroy" );
- p_vout->p_sys_manage =
- GetPluginFunction( p_vout->vout_plugin, "vout_SysManage" );
- p_vout->p_sys_display =
- GetPluginFunction( p_vout->vout_plugin, "vout_SysDisplay" );
-
/* Initialize thread properties - thread id and locks will be initialized
* later */
p_vout->b_die = 0;
p_vout->pi_status = (pi_status != NULL) ? pi_status : &i_status;
*p_vout->pi_status = THREAD_CREATE;
- /* Initialize some fields used by the system-dependant method - these fields will
- * probably be modified by the method, and are only preferences */
+ /* Initialize some fields used by the system-dependant method - these
+ * fields will probably be modified by the method, and are only
+ * preferences */
p_vout->i_changes = 0;
p_vout->i_width = i_width;
p_vout->i_height = i_height;
p_vout->b_interface = 0;
p_vout->b_scale = 0;
- p_vout->p_set_palette = SetPalette;
-
intf_DbgMsg( "wished configuration: %dx%d, %d/%d bpp (%d Bpl)\n",
p_vout->i_width, p_vout->i_height, p_vout->i_screen_depth,
p_vout->i_bytes_per_pixel * 8, p_vout->i_bytes_per_line );
* own error messages */
if( p_vout->p_sys_create( p_vout, psz_display, i_root_window, p_data ) )
{
- TrashPlugin( p_vout->vout_plugin );
free( p_vout );
return( NULL );
}
- intf_DbgMsg("actual configuration: %dx%d, %d/%d bpp (%d Bpl), masks: 0x%x/0x%x/0x%x\n",
- p_vout->i_width, p_vout->i_height, p_vout->i_screen_depth,
- p_vout->i_bytes_per_pixel * 8, p_vout->i_bytes_per_line,
- p_vout->i_red_mask, p_vout->i_green_mask, p_vout->i_blue_mask );
+ intf_DbgMsg( "actual configuration: %dx%d, %d/%d bpp (%d Bpl), "
+ "masks: 0x%x/0x%x/0x%x\n",
+ p_vout->i_width, p_vout->i_height, p_vout->i_screen_depth,
+ p_vout->i_bytes_per_pixel * 8, p_vout->i_bytes_per_line,
+ p_vout->i_red_mask, p_vout->i_green_mask,
+ p_vout->i_blue_mask );
/* Calculate shifts from system-updated masks */
- MaskToShift( &p_vout->i_red_lshift, &p_vout->i_red_rshift, p_vout->i_red_mask );
- MaskToShift( &p_vout->i_green_lshift, &p_vout->i_green_rshift, p_vout->i_green_mask );
- MaskToShift( &p_vout->i_blue_lshift, &p_vout->i_blue_rshift, p_vout->i_blue_mask );
+ MaskToShift( &p_vout->i_red_lshift, &p_vout->i_red_rshift,
+ p_vout->i_red_mask );
+ MaskToShift( &p_vout->i_green_lshift, &p_vout->i_green_rshift,
+ p_vout->i_green_mask );
+ MaskToShift( &p_vout->i_blue_lshift, &p_vout->i_blue_rshift,
+ p_vout->i_blue_mask );
/* Set some useful colors */
p_vout->i_white_pixel = RGB2PIXEL( p_vout, 255, 255, 255 );
/* Load fonts - fonts must be initialized after the system method since
* they may be dependant on screen depth and other thread properties */
- p_vout->p_default_font = vout_LoadFont( DATA_PATH "/" VOUT_DEFAULT_FONT );
+ p_vout->p_default_font = vout_LoadFont( DATA_PATH "/" VOUT_DEFAULT_FONT );
if( p_vout->p_default_font == NULL )
{
- p_vout->p_default_font = vout_LoadFont( "share/" VOUT_DEFAULT_FONT );
+ p_vout->p_default_font = vout_LoadFont( "share/" VOUT_DEFAULT_FONT );
}
if( p_vout->p_default_font == NULL )
{
+ intf_ErrMsg( "vout error: could not load default font\n" );
p_vout->p_sys_destroy( p_vout );
- TrashPlugin( p_vout->vout_plugin );
free( p_vout );
return( NULL );
}
- p_vout->p_large_font = vout_LoadFont( DATA_PATH "/" VOUT_LARGE_FONT );
+ p_vout->p_large_font = vout_LoadFont( DATA_PATH "/" VOUT_LARGE_FONT );
if( p_vout->p_large_font == NULL )
{
- p_vout->p_large_font = vout_LoadFont( "share/" VOUT_LARGE_FONT );
+ p_vout->p_large_font = vout_LoadFont( "share/" VOUT_LARGE_FONT );
}
if( p_vout->p_large_font == NULL )
{
+ intf_ErrMsg( "vout error: could not load large font\n" );
vout_UnloadFont( p_vout->p_default_font );
p_vout->p_sys_destroy( p_vout );
- TrashPlugin( p_vout->vout_plugin );
free( p_vout );
return( NULL );
}
vlc_mutex_init( &p_vout->subpicture_lock );
vlc_mutex_init( &p_vout->change_lock );
vlc_mutex_lock( &p_vout->change_lock );
- if( vlc_thread_create( &p_vout->thread_id, "video output", (void *) RunThread, (void *) p_vout) )
+ if( vlc_thread_create( &p_vout->thread_id, "video output",
+ (void *) RunThread, (void *) p_vout) )
{
intf_ErrMsg("error: %s\n", strerror(ENOMEM));
vout_UnloadFont( p_vout->p_default_font );
vout_UnloadFont( p_vout->p_large_font );
p_vout->p_sys_destroy( p_vout );
- TrashPlugin( p_vout->vout_plugin );
free( p_vout );
return( NULL );
}
- intf_Msg("Video display initialized (%dx%d, %d/%d bpp)\n", p_vout->i_width,
- p_vout->i_height, p_vout->i_screen_depth, p_vout->i_bytes_per_pixel * 8 );
+ intf_Msg( "Video display initialized (%dx%d, %d/%d bpp)\n", p_vout->i_width,
+ p_vout->i_height, p_vout->i_screen_depth,
+ p_vout->i_bytes_per_pixel * 8 );
/* If status is NULL, wait until the thread is created */
if( pi_status == NULL )
}
if (i != ((u32)1 << i_log))
{
- intf_ErrMsg("internal error: binary log overflow\n");
+ intf_DbgMsg("internal error: binary log overflow\n");
}
return( i_log );
vout_UnloadFont( p_vout->p_large_font );
p_vout->p_sys_destroy( p_vout );
- /* Close plugin */
- TrashPlugin( p_vout->vout_plugin );
-
/* Free structure */
free( p_vout );
*pi_status = i_status;
i_file = open( psz_name, O_RDONLY );
if( i_file == -1 )
{
- intf_ErrMsg("error: can't open file '%s' (%s)\n", psz_name, strerror(errno));
+ intf_DbgMsg("vout: can't open file '%s' (%s)\n", psz_name, strerror(errno));
return( NULL );
}
/* Read magick number */
if( read( i_file, pi_buffer, 2 ) != 2 )
{
- intf_ErrMsg("error: unexpected end of file '%s'\n", psz_name );
+ intf_ErrMsg("vout error: unexpected end of file '%s'\n", psz_name );
close( i_file );
return( NULL );
}
p_font = malloc( sizeof( vout_font_t ) );
if( p_font == NULL )
{
- intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+ intf_ErrMsg("vout error: %s\n", strerror(ENOMEM));
close( i_file );
return( NULL );
}
case 0x3604: /* .psf file */
/*
* PSF font: simple fixed font. Only the first 256 characters are read.
- * Those fonts are always 1 byte width, and 256 or 512 characters long.
+ * Those fonts are always 1 byte wide, and 256 or 512 characters long.
*/
/* Read font header - two bytes indicate the font properties */
*****************************************************************************/
void vout_UnloadFont( vout_font_t *p_font )
{
- intf_DbgMsg( "font %p\n", p_font );
+ intf_DbgMsg( "vout: unloading font %p\n", p_font );
free( p_font->p_data );
free( p_font );
}
/*****************************************************************************
* video_yuv.c: YUV transformation functions
- * Provides functions to perform the YUV conversion. The functions provided here
- * are a complete and portable C implementation, and may be replaced in certain
- * case by optimized functions.
+ * These functions set up YUV tables for colorspace conversion
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
#include "intf_msg.h"
-/*****************************************************************************
- * Constants
- *****************************************************************************/
-
-/* Margins and offsets in conversion tables - Margins are used in case a RGB
- * RGB conversion would give a value outside the 0-255 range. Offsets have been
- * calculated to avoid using the same cache line for 2 tables. conversion tables
- * are 2*MARGIN + 256 long and stores pixels.*/
-#define RED_MARGIN 178
-#define GREEN_MARGIN 135
-#define BLUE_MARGIN 224
-#define RED_OFFSET 1501 /* 1323 to 1935 */
-#define GREEN_OFFSET 135 /* 0 to 526 */
-#define BLUE_OFFSET 818 /* 594 to 1298 */
-#define RGB_TABLE_SIZE 1935 /* total table size */
-
-#define GRAY_MARGIN 384
-#define GRAY_TABLE_SIZE 1024 /* total table size */
-
-#define PALETTE_TABLE_SIZE 2176 /* YUV -> 8bpp palette lookup table */
-
-/* macros used for YUV pixel conversions */
-#define SHIFT 20
-#define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
-#define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
-#define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
-#define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
-
-//#define NODITHER
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static void SetGammaTable ( int *pi_table, double f_gamma );
-static void SetYUV ( vout_thread_t *p_vout );
-static void SetOffset ( int i_width, int i_height, int i_pic_width, int i_pic_height,
- boolean_t *pb_h_scaling, int *pi_v_scaling, int *p_offset );
-
-static void ConvertY4Gray8 ( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertY4Gray16 ( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertY4Gray24 ( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertY4Gray32 ( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertYUV420RGB8 ( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertYUV422RGB8 ( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertYUV444RGB8 ( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients );
-
-/*****************************************************************************
- * CONVERT_YUV_PIXEL, CONVERT_Y_PIXEL: pixel conversion blocks
- *****************************************************************************
- * These conversion routines are used by YUV conversion functions.
- * conversion are made from p_y, p_u, p_v, which are modified, to p_buffer,
- * which is also modified.
- *****************************************************************************/
-#define CONVERT_Y_PIXEL( BPP ) \
- /* Only Y sample is present */ \
- p_ybase = p_yuv + *p_y++; \
- *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] | \
- p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) \
- + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-
-#define CONVERT_YUV_PIXEL( BPP ) \
- /* Y, U and V samples are present */ \
- i_uval = *p_u++; \
- i_vval = *p_v++; \
- i_red = (V_RED_COEF * i_vval) >> SHIFT; \
- i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \
- i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
- CONVERT_Y_PIXEL( BPP ) \
-
-/*****************************************************************************
- * CONVERT_4YUV_PIXELS, CONVERT_4YUV_PIXELS_SCALE: dither 4 pixels in 8 bpp
- *****************************************************************************
- * These macros dither 4 pixels in 8 bpp, with or without horiz. scaling
- *****************************************************************************/
-#define CONVERT_4YUV_PIXELS( CHROMA ) \
- *p_pic++ = p_lookup[ \
- (((*p_y++ + dither10[i_real_y]) >> 4) << 7) \
- + ((*p_u + dither20[i_real_y]) >> 5) * 9 \
- + ((*p_v + dither20[i_real_y]) >> 5) ]; \
- *p_pic++ = p_lookup[ \
- (((*p_y++ + dither11[i_real_y]) >> 4) << 7) \
- + ((*p_u++ + dither21[i_real_y]) >> 5) * 9 \
- + ((*p_v++ + dither21[i_real_y]) >> 5) ]; \
- *p_pic++ = p_lookup[ \
- (((*p_y++ + dither12[i_real_y]) >> 4) << 7) \
- + ((*p_u + dither22[i_real_y]) >> 5) * 9 \
- + ((*p_v + dither22[i_real_y]) >> 5) ]; \
- *p_pic++ = p_lookup[ \
- (((*p_y++ + dither13[i_real_y]) >> 4) << 7) \
- + ((*p_u++ + dither23[i_real_y]) >> 5) * 9 \
- + ((*p_v++ + dither23[i_real_y]) >> 5) ]; \
-
-#define CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
- *p_pic++ = p_lookup[ \
- (((*p_y + dither10[i_real_y]) >> 4) << 7) \
- + ((*p_u + dither20[i_real_y]) >> 5) * 9 \
- + ((*p_v + dither20[i_real_y]) >> 5) ]; \
- b_jump_uv = (b_jump_uv + *p_offset) & 0x1; \
- p_y += *p_offset; \
- p_u += *p_offset & b_jump_uv; \
- p_v += *p_offset++ & b_jump_uv; \
- *p_pic++ = p_lookup[ \
- (((*p_y + dither11[i_real_y]) >> 4) << 7) \
- + ((*p_u + dither21[i_real_y]) >> 5) * 9 \
- + ((*p_v + dither21[i_real_y]) >> 5) ]; \
- b_jump_uv = (b_jump_uv + *p_offset) & 0x1; \
- p_y += *p_offset; \
- p_u += *p_offset & b_jump_uv; \
- p_v += *p_offset++ & b_jump_uv; \
- *p_pic++ = p_lookup[ \
- (((*p_y + dither12[i_real_y]) >> 4) << 7) \
- + ((*p_u + dither22[i_real_y]) >> 5) * 9 \
- + ((*p_v + dither22[i_real_y]) >> 5) ]; \
- b_jump_uv = (b_jump_uv + *p_offset) & 0x1; \
- p_y += *p_offset; \
- p_u += *p_offset & b_jump_uv; \
- p_v += *p_offset++ & b_jump_uv; \
- *p_pic++ = p_lookup[ \
- (((*p_y + dither13[i_real_y]) >> 4) << 7) \
- + ((*p_u + dither23[i_real_y]) >> 5) * 9 \
- + ((*p_v + dither23[i_real_y]) >> 5) ]; \
- b_jump_uv = (b_jump_uv + *p_offset) & 0x1; \
- p_y += *p_offset; \
- p_u += *p_offset & b_jump_uv; \
- p_v += *p_offset++ & b_jump_uv; \
-
-/*****************************************************************************
- * SCALE_WIDTH: scale a line horizontally
- *****************************************************************************
- * This macro scales a line using rendering buffer and offset array. It works
- * for 1, 2 and 4 Bpp.
- *****************************************************************************/
-#define SCALE_WIDTH \
- if( b_horizontal_scaling ) \
- { \
- /* Horizontal scaling, conversion has been done to buffer. \
- * Rewind buffer and offset, then copy and scale line */ \
- p_buffer = p_buffer_start; \
- p_offset = p_offset_start; \
- for( i_x = i_pic_width / 16; i_x--; ) \
- { \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
- } \
- p_pic += i_pic_line_width; \
- } \
- else \
- { \
- /* No scaling, conversion has been done directly in picture memory. \
- * Increment of picture pointer to end of line is still needed */ \
- p_pic += i_pic_width + i_pic_line_width; \
- } \
-
-
-/*****************************************************************************
- * SCALE_WIDTH_DITHER: scale a line horizontally for dithered 8 bpp
- *****************************************************************************
- * This macro scales a line using an offset array.
- *****************************************************************************/
-#define SCALE_WIDTH_DITHER( CHROMA ) \
- if( b_horizontal_scaling ) \
- { \
- /* Horizontal scaling, but we can't use a buffer due to dither */ \
- p_offset = p_offset_start; \
- b_jump_uv = 0; \
- for( i_x = i_pic_width / 16; i_x--; ) \
- { \
- CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
- CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
- CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
- CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
- } \
- } \
- else \
- { \
- for( i_x = i_width / 16; i_x--; ) \
- { \
- CONVERT_4YUV_PIXELS( CHROMA ) \
- CONVERT_4YUV_PIXELS( CHROMA ) \
- CONVERT_4YUV_PIXELS( CHROMA ) \
- CONVERT_4YUV_PIXELS( CHROMA ) \
- } \
- } \
- /* Increment of picture pointer to end of line is still needed */ \
- p_pic += i_pic_line_width; \
- i_real_y = (i_real_y + 1) & 0x3; \
-
-/*****************************************************************************
- * SCALE_HEIGHT: handle vertical scaling
- *****************************************************************************
- * This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
- * 444 for RGB conversion, or 400 for gray conversion. It works for 1, 2, 3
- * and 4 Bpp.
- *****************************************************************************/
-#define SCALE_HEIGHT( CHROMA, BPP ) \
- /* If line is odd, rewind 4:2:0 U and V samples */ \
- if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
- { \
- p_u -= i_chroma_width; \
- p_v -= i_chroma_width; \
- } \
- \
- /* \
- * Handle vertical scaling. The current line can be copied or next one \
- * can be ignored. \
- */ \
- switch( i_vertical_scaling ) \
- { \
- case -1: /* vertical scaling factor is < 1 */ \
- while( (i_scale_count -= i_pic_height) >= 0 ) \
- { \
- /* Height reduction: skip next source line */ \
- p_y += i_width; \
- i_y++; \
- if( (CHROMA == 420) || (CHROMA == 422) ) \
- { \
- if( i_y & 0x1 ) \
- { \
- p_u += i_chroma_width; \
- p_v += i_chroma_width; \
- } \
- } \
- else if( CHROMA == 444 ) \
- { \
- p_u += i_width; \
- p_v += i_width; \
- } \
- } \
- i_scale_count += i_height; \
- break; \
- case 1: /* vertical scaling factor is > 1 */ \
- while( (i_scale_count -= i_height) > 0 ) \
- { \
- /* Height increment: copy previous picture line */ \
- for( i_x = i_pic_width / 16; i_x--; ) \
- { \
- *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
- *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
- if( BPP > 1 ) /* 2, 3, 4 Bpp */ \
- { \
- *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
- *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
- } \
- if( BPP > 2 ) /* 3, 4 Bpp */ \
- { \
- *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
- *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
- } \
- if( BPP > 3 ) /* 4 Bpp */ \
- { \
- *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
- *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
- } \
- } \
- p_pic += i_pic_line_width; \
- p_pic_start += i_pic_line_width; \
- } \
- i_scale_count += i_pic_height; \
- break; \
- } \
-
-/*****************************************************************************
- * SCALE_HEIGHT_DITHER: handle vertical scaling for dithered 8 bpp
- *****************************************************************************
- * This macro handles vertical scaling for a picture. CHROMA may be 420, 422 or
- * 444 for RGB conversion, or 400 for gray conversion.
- *****************************************************************************/
-#define SCALE_HEIGHT_DITHER( CHROMA ) \
- \
- /* If line is odd, rewind 4:2:0 U and V samples */ \
- if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
- { \
- p_u -= i_chroma_width; \
- p_v -= i_chroma_width; \
- } \
- \
- /* \
- * Handle vertical scaling. The current line can be copied or next one \
- * can be ignored. \
- */ \
- \
- switch( i_vertical_scaling ) \
- { \
- case -1: /* vertical scaling factor is < 1 */ \
- while( (i_scale_count -= i_pic_height) >= 0 ) \
- { \
- /* Height reduction: skip next source line */ \
- p_y += i_width; \
- i_y++; \
- if( (CHROMA == 420) || (CHROMA == 422) ) \
- { \
- if( i_y & 0x1 ) \
- { \
- p_u += i_chroma_width; \
- p_v += i_chroma_width; \
- } \
- } \
- else if( CHROMA == 444 ) \
- { \
- p_u += i_width; \
- p_v += i_width; \
- } \
- } \
- i_scale_count += i_height; \
- break; \
- case 1: /* vertical scaling factor is > 1 */ \
- while( (i_scale_count -= i_height) > 0 ) \
- { \
- SCALE_WIDTH_DITHER( CHROMA ); \
- p_y -= i_width; \
- p_u -= i_chroma_width; \
- p_v -= i_chroma_width; \
- p_pic += i_pic_line_width; \
- } \
- i_scale_count += i_pic_height; \
- break; \
- } \
+#include "main.h"
/*****************************************************************************
* vout_InitYUV: allocate and initialize translations tables
*****************************************************************************/
int vout_InitYUV( vout_thread_t *p_vout )
{
- size_t tables_size; /* tables size, in bytes */
+ typedef void ( yuv_getplugin_t ) ( vout_thread_t * p_vout );
+ int i_index;
- /* Computes tables size - 3 Bpp use 32 bits pixel entries in tables */
- switch( p_vout->i_bytes_per_pixel )
- {
- case 1:
- tables_size = sizeof( u8 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : PALETTE_TABLE_SIZE);
- break;
- case 2:
- tables_size = sizeof( u16 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
- break;
- case 3:
- case 4:
- default:
- tables_size = sizeof( u32 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
- break;
- }
-
- /* Allocate memory */
- p_vout->yuv.p_base = malloc( tables_size );
- if( p_vout->yuv.p_base == NULL )
- {
- intf_ErrMsg("error: %s\n", strerror(ENOMEM));
- return( 1 );
- }
-
- /* Allocate memory for conversion buffer and offset array */
- p_vout->yuv.p_buffer = malloc( VOUT_MAX_WIDTH * p_vout->i_bytes_per_pixel );
- if( p_vout->yuv.p_buffer == NULL )
- {
- intf_ErrMsg("error: %s\n", strerror(ENOMEM));
- free( p_vout->yuv.p_base );
- return( 1 );
- }
- p_vout->yuv.p_offset = malloc( p_vout->i_width * sizeof( int ) );
- if( p_vout->yuv.p_offset == NULL )
+ /* Get a suitable YUV plugin */
+ for( i_index = 0 ; i_index < p_main->p_bank->i_plugin_count ; i_index++ )
{
- intf_ErrMsg("error: %s\n", strerror(ENOMEM));
- free( p_vout->yuv.p_base );
- free( p_vout->yuv.p_buffer );
- return( 1 );
+ /* If there's a plugin in p_info ... */
+ if( p_main->p_bank->p_info[ i_index ] != NULL )
+ {
+ /* ... and if this plugin provides the functions we want ... */
+ if( p_main->p_bank->p_info[ i_index ]->yuv_GetPlugin != NULL )
+ {
+ /* ... then get these functions */
+ ( (yuv_getplugin_t *)
+ p_main->p_bank->p_info[ i_index ]->yuv_GetPlugin )( p_vout );
+ }
+ }
}
- /* Initialize tables */
- SetYUV( p_vout );
- return( 0 );
+ return p_vout->p_yuv_init( p_vout );
}
/*****************************************************************************
- * vout_ResetTables: re-initialize translations tables
+ * vout_ResetYUV: re-initialize translations tables
*****************************************************************************
- * This function will initialize the tables allocated by vout_CreateTables and
+ * This function will initialize the tables allocated by vout_InitYUV and
* set functions pointers.
*****************************************************************************/
int vout_ResetYUV( vout_thread_t *p_vout )
{
- vout_EndYUV( p_vout );
- return( vout_InitYUV( p_vout ) );
+ p_vout->p_yuv_end( p_vout );
+ return( p_vout->p_yuv_init( p_vout ) );
}
/*****************************************************************************
* vout_EndYUV: destroy translations tables
*****************************************************************************
- * Free memory allocated by vout_CreateTables.
+ * Free memory allocated by vout_InitYUV
*****************************************************************************/
void vout_EndYUV( vout_thread_t *p_vout )
{
- free( p_vout->yuv.p_base );
- free( p_vout->yuv.p_buffer );
- free( p_vout->yuv.p_offset );
+ p_vout->p_yuv_end( p_vout );
}
-/* following functions are local */
-
-/*****************************************************************************
- * SetGammaTable: return intensity table transformed by gamma curve.
- *****************************************************************************
- * pi_table is a table of 256 entries from 0 to 255.
- *****************************************************************************/
-static void SetGammaTable( int *pi_table, double f_gamma )
-{
- int i_y; /* base intensity */
-
- /* Use exp(gamma) instead of gamma */
- f_gamma = exp( f_gamma );
-
- /* Build gamma table */
- for( i_y = 0; i_y < 256; i_y++ )
- {
- pi_table[ i_y ] = pow( (double)i_y / 256, f_gamma ) * 256;
- }
- }
-
-/*****************************************************************************
- * SetYUV: compute tables and set function pointers
-+ *****************************************************************************/
-static void SetYUV( vout_thread_t *p_vout )
-{
- int pi_gamma[256]; /* gamma table */
- int i_index; /* index in tables */
-
- /* Build gamma table */
- SetGammaTable( pi_gamma, p_vout->f_gamma );
-
- /*
- * Set pointers and build YUV tables
- */
- if( p_vout->b_grayscale )
- {
- /* Grayscale: build gray table */
- switch( p_vout->i_bytes_per_pixel )
- {
- case 1:
- {
- u16 bright[256], transp[256];
-
- p_vout->yuv.yuv.p_gray8 = (u8 *)p_vout->yuv.p_base + GRAY_MARGIN;
- for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
- {
- p_vout->yuv.yuv.p_gray8[ -i_index ] = RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
- p_vout->yuv.yuv.p_gray8[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
- }
- for( i_index = 0; i_index < 256; i_index++)
- {
- p_vout->yuv.yuv.p_gray8[ i_index ] = pi_gamma[ i_index ];
- bright[ i_index ] = i_index << 8;
- transp[ i_index ] = 0;
- }
- /* the colors have been allocated, we can set the palette */
- p_vout->p_set_palette( p_vout, bright, bright, bright, transp );
- p_vout->i_white_pixel = 0xff;
- p_vout->i_black_pixel = 0x00;
- p_vout->i_gray_pixel = 0x44;
- p_vout->i_blue_pixel = 0x3b;
-
- break;
- }
- case 2:
- p_vout->yuv.yuv.p_gray16 = (u16 *)p_vout->yuv.p_base + GRAY_MARGIN;
- for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
- {
- p_vout->yuv.yuv.p_gray16[ -i_index ] = RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
- p_vout->yuv.yuv.p_gray16[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
- }
- for( i_index = 0; i_index < 256; i_index++)
- {
- p_vout->yuv.yuv.p_gray16[ i_index ] = RGB2PIXEL( p_vout, pi_gamma[i_index], pi_gamma[i_index], pi_gamma[i_index] );
- }
- break;
- case 3:
- case 4:
- p_vout->yuv.yuv.p_gray32 = (u32 *)p_vout->yuv.p_base + GRAY_MARGIN;
- for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
- {
- p_vout->yuv.yuv.p_gray32[ -i_index ] = RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
- p_vout->yuv.yuv.p_gray32[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
- }
- for( i_index = 0; i_index < 256; i_index++)
- {
- p_vout->yuv.yuv.p_gray32[ i_index ] = RGB2PIXEL( p_vout, pi_gamma[i_index], pi_gamma[i_index], pi_gamma[i_index] );
- }
- break;
- }
- }
- else
- {
- /* Color: build red, green and blue tables */
- switch( p_vout->i_bytes_per_pixel )
- {
- case 1:
- {
- #define RGB_MIN 0
- #define RGB_MAX 255
- #define CLIP( x ) ( ((x < 0) ? 0 : (x > 255) ? 255 : x) << 8 )
-
- int y,u,v;
- int r,g,b;
- int uvr, uvg, uvb;
- int i = 0, j = 0;
- u16 red[256], green[256], blue[256], transp[256];
- unsigned char lookup[PALETTE_TABLE_SIZE];
-
- p_vout->yuv.yuv.p_rgb8 = (u8 *)p_vout->yuv.p_base;
-
- /* this loop calculates the intersection of an YUV box
- * and the RGB cube. */
- for ( y = 0; y <= 256; y += 16 )
- {
- for ( u = 0; u <= 256; u += 32 )
- for ( v = 0; v <= 256; v += 32 )
- {
- uvr = (V_RED_COEF*(v-128)) >> SHIFT;
- uvg = (U_GREEN_COEF*(u-128) + V_GREEN_COEF*(v-128)) >> SHIFT;
- uvb = (U_BLUE_COEF*(u-128)) >> SHIFT;
- r = y + uvr;
- g = y + uvg;
- b = y + uvb;
-
- if( r >= RGB_MIN && g >= RGB_MIN && b >= RGB_MIN
- && r <= RGB_MAX && g <= RGB_MAX && b <= RGB_MAX )
- {
- /* this one should never happen unless someone fscked up my code */
- if(j == 256) { intf_ErrMsg( "vout error: no colors left to build palette\n" ); break; }
-
- /* clip the colors */
- red[j] = CLIP( r );
- green[j] = CLIP( g );
- blue[j] = CLIP( b );
- transp[j] = 0;
-
- /* allocate color */
- lookup[i] = 1;
- p_vout->yuv.yuv.p_rgb8[i++] = j;
- j++;
- }
- else
- {
- lookup[i] = 0;
- p_vout->yuv.yuv.p_rgb8[i++] = 0;
- }
- }
- i += 128-81;
- }
-
- /* the colors have been allocated, we can set the palette */
- /* there will eventually be a way to know which colors
- * couldn't be allocated and try to find a replacement */
- p_vout->p_set_palette( p_vout, red, green, blue, transp );
-
- p_vout->i_white_pixel = 0xff;
- p_vout->i_black_pixel = 0x00;
- p_vout->i_gray_pixel = 0x44;
- p_vout->i_blue_pixel = 0x3b;
-
- i = 0;
- /* this loop allocates colors that got outside
- * the RGB cube */
- for ( y = 0; y <= 256; y += 16 )
- {
- for ( u = 0; u <= 256; u += 32 )
- for ( v = 0; v <= 256; v += 32 )
- {
- int u2, v2;
- int dist, mindist = 100000000;
-
- if( lookup[i] || y==0)
- {
- i++;
- continue;
- }
-
- /* heavy. yeah. */
- for( u2 = 0; u2 <= 256; u2 += 32 )
- for( v2 = 0; v2 <= 256; v2 += 32 )
- {
- j = ((y>>4)<<7) + (u2>>5)*9 + (v2>>5);
- dist = (u-u2)*(u-u2) + (v-v2)*(v-v2);
- if( lookup[j] )
- /* find the nearest color */
- if( dist < mindist )
- {
- p_vout->yuv.yuv.p_rgb8[i] = p_vout->yuv.yuv.p_rgb8[j];
- mindist = dist;
- }
- j -= 128;
- if( lookup[j] )
- /* find the nearest color */
- if( dist + 128 < mindist )
- {
- p_vout->yuv.yuv.p_rgb8[i] = p_vout->yuv.yuv.p_rgb8[j];
- mindist = dist + 128;
- }
- }
- i++;
- }
- i += 128-81;
- }
-
- break;
- }
- case 2:
- p_vout->yuv.yuv.p_rgb16 = (u16 *)p_vout->yuv.p_base;
- for( i_index = 0; i_index < RED_MARGIN; i_index++ )
- {
- p_vout->yuv.yuv.p_rgb16[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
- p_vout->yuv.yuv.p_rgb16[RED_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
- }
- for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
- {
- p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
- p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
- }
- for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
- {
- p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
- p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
- }
- for( i_index = 0; i_index < 256; i_index++ )
- {
- p_vout->yuv.yuv.p_rgb16[RED_OFFSET + i_index] = RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
- p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
- p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] );
- }
- break;
- case 3:
- case 4:
- p_vout->yuv.yuv.p_rgb32 = (u32 *)p_vout->yuv.p_base;
- for( i_index = 0; i_index < RED_MARGIN; i_index++ )
- {
- p_vout->yuv.yuv.p_rgb32[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
- p_vout->yuv.yuv.p_rgb32[RED_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
- }
- for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
- {
- p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
- p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
- }
- for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
- {
- p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
- p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
- }
- for( i_index = 0; i_index < 256; i_index++ )
- {
- p_vout->yuv.yuv.p_rgb32[RED_OFFSET + i_index] = RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
- p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
- p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] );
- }
- break;
- }
- }
-
- /*
- * Set functions pointers
- */
- if( p_vout->b_grayscale )
- {
- /* Grayscale */
- switch( p_vout->i_bytes_per_pixel )
- {
- case 1:
- p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray8;
- p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray8;
- p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray8;
- break;
- case 2:
- p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
- p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray16;
- p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray16;
- break;
- case 3:
- p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
- p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray24;
- p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray24;
- break;
- case 4:
- p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
- p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray32;
- p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray32;
- break;
- }
- }
- else
- {
- /* Color */
- switch( p_vout->i_bytes_per_pixel )
- {
- case 1:
- p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB8;
- p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB8;
- p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB8;
- break;
- case 2:
- p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB16;
- p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB16;
- p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB16;
- break;
- case 3:
- p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
- p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB24;
- p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB24;
- break;
- case 4:
- p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
- p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB32;
- p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB32;
- break;
- }
- }
-}
-
-/*****************************************************************************
- * SetOffset: build offset array for conversion functions
- *****************************************************************************
- * This function will build an offset array used in later conversion functions.
- * It will also set horizontal and vertical scaling indicators.
- *****************************************************************************/
-static void SetOffset( int i_width, int i_height, int i_pic_width, int i_pic_height,
- boolean_t *pb_h_scaling, int *pi_v_scaling, int *p_offset )
-{
- int i_x; /* x position in destination */
- int i_scale_count; /* modulo counter */
-
- /*
- * Prepare horizontal offset array
- */
- if( i_pic_width - i_width > 0 )
- {
- /* Prepare scaling array for horizontal extension */
- *pb_h_scaling = 1;
- i_scale_count = i_pic_width;
- for( i_x = i_width; i_x--; )
- {
- while( (i_scale_count -= i_width) > 0 )
- {
- *p_offset++ = 0;
- }
- *p_offset++ = 1;
- i_scale_count += i_pic_width;
- }
- }
- else if( i_pic_width - i_width < 0 )
- {
- /* Prepare scaling array for horizontal reduction */
- *pb_h_scaling = 1;
- i_scale_count = i_pic_width;
- for( i_x = i_pic_width; i_x--; )
- {
- *p_offset = 1;
- while( (i_scale_count -= i_pic_width) >= 0 )
- {
- *p_offset += 1;
- }
- p_offset++;
- i_scale_count += i_width;
- }
- }
- else
- {
- /* No horizontal scaling: YUV conversion is done directly to picture */
- *pb_h_scaling = 0;
- }
-
- /*
- * Set vertical scaling indicator
- */
- if( i_pic_height - i_height > 0 )
- {
- *pi_v_scaling = 1;
- }
- else if( i_pic_height - i_height < 0 )
- {
- *pi_v_scaling = -1;
- }
- else
- {
- *pi_v_scaling = 0;
- }
-}
-
-/*****************************************************************************
- * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
- *****************************************************************************/
-static void ConvertY4Gray8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y,
- yuv_data_t *p_u, yuv_data_t *p_v, int i_width,
- int i_height, int i_pic_width, int i_pic_height,
- int i_pic_line_width, int i_matrix_coefficients )
-{
- boolean_t b_horizontal_scaling; /* horizontal scaling type */
- int i_vertical_scaling; /* vertical scaling type */
- int i_x, i_y; /* horizontal and vertical indexes */
- int i_scale_count; /* scale modulo counter */
- int i_chroma_width; /* chroma width, not used */
- u8 * p_gray; /* base conversion table */
- u8 * p_pic_start; /* beginning of the current line for copy */
- u8 * p_buffer_start; /* conversion buffer start */
- u8 * p_buffer; /* conversion buffer pointer */
- int * p_offset_start; /* offset array start */
- int * p_offset; /* offset array pointer */
-
- /*
- * Initialize some values - i_pic_line_width will store the line skip
- */
- i_pic_line_width -= i_pic_width;
- p_gray = p_vout->yuv.yuv.p_gray8;
- p_buffer_start = p_vout->yuv.p_buffer;
- p_offset_start = p_vout->yuv.p_offset;
- SetOffset( i_width, i_height, i_pic_width, i_pic_height,
- &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
-
- /*
- * Perform conversion
- */
- i_scale_count = i_pic_height;
- for( i_y = 0; i_y < i_height; i_y++ )
- {
- /* Mark beginnning of line for possible later line copy, and initialize
- * buffer */
- p_pic_start = p_pic;
- p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
-
- /* Do YUV conversion to buffer - YUV picture is always formed of 16
- * pixels wide blocks */
- for( i_x = i_width / 16; i_x--; )
- {
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- }
-
- /* Do horizontal and vertical scaling */
- SCALE_WIDTH;
- SCALE_HEIGHT(400, 1);
- }
-}
-
-/*****************************************************************************
- * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 2 Bpp
- *****************************************************************************/
-static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- boolean_t b_horizontal_scaling; /* horizontal scaling type */
- int i_vertical_scaling; /* vertical scaling type */
- int i_x, i_y; /* horizontal and vertical indexes */
- int i_scale_count; /* scale modulo counter */
- int i_chroma_width; /* chroma width, not used */
- u16 * p_gray; /* base conversion table */
- u16 * p_pic_start; /* beginning of the current line for copy */
- u16 * p_buffer_start; /* conversion buffer start */
- u16 * p_buffer; /* conversion buffer pointer */
- int * p_offset_start; /* offset array start */
- int * p_offset; /* offset array pointer */
-
- /*
- * Initialize some values - i_pic_line_width will store the line skip
- */
- i_pic_line_width -= i_pic_width;
- p_gray = p_vout->yuv.yuv.p_gray16;
- p_buffer_start = p_vout->yuv.p_buffer;
- p_offset_start = p_vout->yuv.p_offset;
- SetOffset( i_width, i_height, i_pic_width, i_pic_height,
- &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
-
- /*
- * Perform conversion
- */
- i_scale_count = i_pic_height;
- for( i_y = 0; i_y < i_height; i_y++ )
- {
- /* Mark beginnning of line for possible later line copy, and initialize
- * buffer */
- p_pic_start = p_pic;
- p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
-
- /* Do YUV conversion to buffer - YUV picture is always formed of 16
- * pixels wide blocks */
- for( i_x = i_width / 16; i_x--; )
- {
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- }
-
- /* Do horizontal and vertical scaling */
- SCALE_WIDTH;
- SCALE_HEIGHT(400, 2);
- }
-}
-
-/*****************************************************************************
- * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 3 Bpp
- *****************************************************************************/
-static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- /* XXX?? */
-}
-
-/*****************************************************************************
- * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
- *****************************************************************************/
-static void ConvertY4Gray32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- boolean_t b_horizontal_scaling; /* horizontal scaling type */
- int i_vertical_scaling; /* vertical scaling type */
- int i_x, i_y; /* horizontal and vertical indexes */
- int i_scale_count; /* scale modulo counter */
- int i_chroma_width; /* chroma width, not used */
- u32 * p_gray; /* base conversion table */
- u32 * p_pic_start; /* beginning of the current line for copy */
- u32 * p_buffer_start; /* conversion buffer start */
- u32 * p_buffer; /* conversion buffer pointer */
- int * p_offset_start; /* offset array start */
- int * p_offset; /* offset array pointer */
-
- /*
- * Initialize some values - i_pic_line_width will store the line skip
- */
- i_pic_line_width -= i_pic_width;
- p_gray = p_vout->yuv.yuv.p_gray32;
- p_buffer_start = p_vout->yuv.p_buffer;
- p_offset_start = p_vout->yuv.p_offset;
- SetOffset( i_width, i_height, i_pic_width, i_pic_height,
- &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
-
- /*
- * Perform conversion
- */
- i_scale_count = i_pic_height;
- for( i_y = 0; i_y < i_height; i_y++ )
- {
- /* Mark beginnning of line for possible later line copy, and initialize
- * buffer */
- p_pic_start = p_pic;
- p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
-
- /* Do YUV conversion to buffer - YUV picture is always formed of 16
- * pixels wide blocks */
- for( i_x = i_width / 16; i_x--; )
- {
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
- }
-
- /* Do horizontal and vertical scaling */
- SCALE_WIDTH;
- SCALE_HEIGHT(400, 4);
- }
-}
-
-/*****************************************************************************
- * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
- *****************************************************************************/
-static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- boolean_t b_horizontal_scaling; /* horizontal scaling type */
- int i_vertical_scaling; /* vertical scaling type */
- int i_x, i_y; /* horizontal and vertical indexes */
- int i_scale_count; /* scale modulo counter */
- int b_jump_uv; /* should we jump u and v ? */
- int i_real_y; /* y % 4 */
- u8 * p_lookup; /* lookup table */
- int i_chroma_width; /* chroma width */
- int * p_offset_start; /* offset array start */
- int * p_offset; /* offset array pointer */
-
-#ifdef NODITHER
- int dither10[4] = { 0x7, 0x8, 0x7, 0x8 };
- int dither11[4] = { 0x8, 0x7, 0x8, 0x7 };
- int dither12[4] = { 0x7, 0x8, 0x7, 0x8 };
- int dither13[4] = { 0x8, 0x7, 0x8, 0x7 };
-
- int dither20[4] = { 0xf, 0x10, 0xf, 0x10 };
- int dither21[4] = { 0x10, 0xf, 0x10, 0xf };
- int dither22[4] = { 0xf, 0x10, 0xf, 0x10 };
- int dither23[4] = { 0x10, 0xf, 0x10, 0xf };
-#else
- int dither10[4] = { 0x0, 0x8, 0x2, 0xa };
- int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
- int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
- int dither13[4] = { 0xf, 0x7, 0xd, 0x5 };
-
- int dither20[4] = { 0x0, 0x10, 0x4, 0x14 };
- int dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
- int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
- int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
-#endif
-
- /* some other matrices that can be interesting, either for debugging
- * or for effects :
- *
- * { { 0, 8, 2, 10 }, { 12, 4, 14, 16 }, { 3, 11, 1, 9}, {15, 7, 13, 5} }
- * { { 7, 8, 0, 15 }, { 0, 15, 8, 7 }, { 7, 0, 15, 8 }, { 15, 7, 8, 0 } }
- * { { 0, 15, 0, 15 }, { 15, 0, 15, 0 }, { 0, 15, 0, 15 }, { 15, 0, 15, 0 } }
- * { { 15, 15, 0, 0 }, { 15, 15, 0, 0 }, { 0, 0, 15, 15 }, { 0, 0, 15, 15 } }
- * { { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 } }
- * { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } }
- */
-
- /*
- * Initialize some values - i_pic_line_width will store the line skip
- */
- i_pic_line_width -= i_pic_width;
- i_chroma_width = i_width / 2;
- p_offset_start = p_vout->yuv.p_offset;
- p_lookup = p_vout->yuv.p_base;
- SetOffset( i_width, i_height, i_pic_width, i_pic_height,
- &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
-
- /*
- * Perform conversion
- */
- i_scale_count = i_pic_height;
- i_real_y = 0;
- for( i_y = 0; i_y < i_height; i_y++ )
- {
- /* Do horizontal and vertical scaling */
- SCALE_WIDTH_DITHER( 420 );
- SCALE_HEIGHT_DITHER( 420 );
- }
-}
-
-/*****************************************************************************
- * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
- *****************************************************************************/
-static void ConvertYUV422RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- boolean_t b_horizontal_scaling; /* horizontal scaling type */
- int i_vertical_scaling; /* vertical scaling type */
- int i_x, i_y; /* horizontal and vertical indexes */
- int i_scale_count; /* scale modulo counter */
- int i_uval, i_vval; /* U and V samples */
- int i_red, i_green, i_blue; /* U and V modified samples */
- int i_chroma_width; /* chroma width */
- u8 * p_yuv; /* base conversion table */
- u8 * p_ybase; /* Y dependant conversion table */
- u8 * p_pic_start; /* beginning of the current line for copy */
- u8 * p_buffer_start; /* conversion buffer start */
- u8 * p_buffer; /* conversion buffer pointer */
- int * p_offset_start; /* offset array start */
- int * p_offset; /* offset array pointer */
-
- /*
- * Initialize some values - i_pic_line_width will store the line skip
- */
- i_pic_line_width -= i_pic_width;
- i_chroma_width = i_width / 2;
- p_yuv = p_vout->yuv.yuv.p_rgb8;
- p_buffer_start = p_vout->yuv.p_buffer;
- p_offset_start = p_vout->yuv.p_offset;
- SetOffset( i_width, i_height, i_pic_width, i_pic_height,
- &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
-
- /*
- * Perform conversion
- */
- i_scale_count = i_pic_height;
- for( i_y = 0; i_y < i_height; i_y++ )
- {
- /* Mark beginnning of line for possible later line copy, and initialize
- * buffer */
- p_pic_start = p_pic;
- p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
-
- /* Do YUV conversion to buffer - YUV picture is always formed of 16
- * pixels wide blocks */
- for( i_x = i_width / 16; i_x--; )
- {
- CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
- }
-
- /* Do horizontal and vertical scaling */
- SCALE_WIDTH;
- SCALE_HEIGHT(422, 1);
- }
-}
-
-/*****************************************************************************
- * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
- *****************************************************************************/
-static void ConvertYUV444RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- boolean_t b_horizontal_scaling; /* horizontal scaling type */
- int i_vertical_scaling; /* vertical scaling type */
- int i_x, i_y; /* horizontal and vertical indexes */
- int i_scale_count; /* scale modulo counter */
- int i_uval, i_vval; /* U and V samples */
- int i_red, i_green, i_blue; /* U and V modified samples */
- int i_chroma_width; /* chroma width, not used */
- u8 * p_yuv; /* base conversion table */
- u8 * p_ybase; /* Y dependant conversion table */
- u8 * p_pic_start; /* beginning of the current line for copy */
- u8 * p_buffer_start; /* conversion buffer start */
- u8 * p_buffer; /* conversion buffer pointer */
- int * p_offset_start; /* offset array start */
- int * p_offset; /* offset array pointer */
-
- /*
- * Initialize some values - i_pic_line_width will store the line skip
- */
- i_pic_line_width -= i_pic_width;
- p_yuv = p_vout->yuv.yuv.p_rgb8;
- p_buffer_start = p_vout->yuv.p_buffer;
- p_offset_start = p_vout->yuv.p_offset;
- SetOffset( i_width, i_height, i_pic_width, i_pic_height,
- &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
-
- /*
- * Perform conversion
- */
- i_scale_count = i_pic_height;
- for( i_y = 0; i_y < i_height; i_y++ )
- {
- /* Mark beginnning of line for possible later line copy, and initialize
- * buffer */
- p_pic_start = p_pic;
- p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
-
- /* Do YUV conversion to buffer - YUV picture is always formed of 16
- * pixels wide blocks */
- for( i_x = i_width / 16; i_x--; )
- {
- CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
- CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
- }
-
- /* Do horizontal and vertical scaling */
- SCALE_WIDTH;
- SCALE_HEIGHT(444, 1);
- }
-}
-
-/*****************************************************************************
- * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
- *****************************************************************************/
-static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
-#if 0
- /* MMX version */
- int i_chroma_width, i_chroma_skip; /* width and eol for chroma */
-
- i_chroma_width = i_width / 2;
- i_chroma_skip = i_skip / 2;
- ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height,
- (i_width + i_skip) * sizeof( yuv_data_t ),
- (i_chroma_width + i_chroma_skip) * sizeof( yuv_data_t),
- i_scale, (u8 *)p_pic, 0, 0, (i_width + i_pic_eol) * sizeof( u16 ),
- p_vout->i_screen_depth == 15 );
-#endif
- boolean_t b_horizontal_scaling; /* horizontal scaling type */
- int i_vertical_scaling; /* vertical scaling type */
- int i_x, i_y; /* horizontal and vertical indexes */
- int i_scale_count; /* scale modulo counter */
- int i_uval, i_vval; /* U and V samples */
- int i_red, i_green, i_blue; /* U and V modified samples */
- int i_chroma_width; /* chroma width */
- u16 * p_yuv; /* base conversion table */
- u16 * p_ybase; /* Y dependant conversion table */
- u16 * p_pic_start; /* beginning of the current line for copy */
- u16 * p_buffer_start; /* conversion buffer start */
- u16 * p_buffer; /* conversion buffer pointer */
- int * p_offset_start; /* offset array start */
- int * p_offset; /* offset array pointer */
-
- /*
- * Initialize some values - i_pic_line_width will store the line skip
- */
- i_pic_line_width -= i_pic_width;
- i_chroma_width = i_width / 2;
- p_yuv = p_vout->yuv.yuv.p_rgb16;
- p_buffer_start = p_vout->yuv.p_buffer;
- p_offset_start = p_vout->yuv.p_offset;
- SetOffset( i_width, i_height, i_pic_width, i_pic_height,
- &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
-
- /*
- * Perform conversion
- */
- i_scale_count = i_pic_height;
- for( i_y = 0; i_y < i_height; i_y++ )
- {
- /* Mark beginnning of line for possible later line copy, and initialize
- * buffer */
- p_pic_start = p_pic;
- p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
-
- /* Do YUV conversion to buffer - YUV picture is always formed of 16
- * pixels wide blocks */
- for( i_x = i_width / 16; i_x--; )
- {
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- }
-
- /* Do horizontal and vertical scaling */
- SCALE_WIDTH;
- SCALE_HEIGHT(420, 2);
- }
-}
-
-/*****************************************************************************
- * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
- *****************************************************************************/
-static void ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- boolean_t b_horizontal_scaling; /* horizontal scaling type */
- int i_vertical_scaling; /* vertical scaling type */
- int i_x, i_y; /* horizontal and vertical indexes */
- int i_scale_count; /* scale modulo counter */
- int i_uval, i_vval; /* U and V samples */
- int i_red, i_green, i_blue; /* U and V modified samples */
- int i_chroma_width; /* chroma width */
- u16 * p_yuv; /* base conversion table */
- u16 * p_ybase; /* Y dependant conversion table */
- u16 * p_pic_start; /* beginning of the current line for copy */
- u16 * p_buffer_start; /* conversion buffer start */
- u16 * p_buffer; /* conversion buffer pointer */
- int * p_offset_start; /* offset array start */
- int * p_offset; /* offset array pointer */
-
- /*
- * Initialize some values - i_pic_line_width will store the line skip
- */
- i_pic_line_width -= i_pic_width;
- i_chroma_width = i_width / 2;
- p_yuv = p_vout->yuv.yuv.p_rgb16;
- p_buffer_start = p_vout->yuv.p_buffer;
- p_offset_start = p_vout->yuv.p_offset;
- SetOffset( i_width, i_height, i_pic_width, i_pic_height,
- &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
-
- /*
- * Perform conversion
- */
- i_scale_count = i_pic_height;
- for( i_y = 0; i_y < i_height; i_y++ )
- {
- /* Mark beginnning of line for possible later line copy, and initialize
- * buffer */
- p_pic_start = p_pic;
- p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
-
- /* Do YUV conversion to buffer - YUV picture is always formed of 16
- * pixels wide blocks */
- for( i_x = i_width / 16; i_x--; )
- {
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
- }
-
- /* Do horizontal and vertical scaling */
- SCALE_WIDTH;
- SCALE_HEIGHT(422, 2);
- }
-}
-
-/*****************************************************************************
- * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
- *****************************************************************************/
-static void ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- boolean_t b_horizontal_scaling; /* horizontal scaling type */
- int i_vertical_scaling; /* vertical scaling type */
- int i_x, i_y; /* horizontal and vertical indexes */
- int i_scale_count; /* scale modulo counter */
- int i_uval, i_vval; /* U and V samples */
- int i_red, i_green, i_blue; /* U and V modified samples */
- int i_chroma_width; /* chroma width, not used */
- u16 * p_yuv; /* base conversion table */
- u16 * p_ybase; /* Y dependant conversion table */
- u16 * p_pic_start; /* beginning of the current line for copy */
- u16 * p_buffer_start; /* conversion buffer start */
- u16 * p_buffer; /* conversion buffer pointer */
- int * p_offset_start; /* offset array start */
- int * p_offset; /* offset array pointer */
-
- /*
- * Initialize some values - i_pic_line_width will store the line skip
- */
- i_pic_line_width -= i_pic_width;
- p_yuv = p_vout->yuv.yuv.p_rgb16;
- p_buffer_start = p_vout->yuv.p_buffer;
- p_offset_start = p_vout->yuv.p_offset;
- SetOffset( i_width, i_height, i_pic_width, i_pic_height,
- &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
-
- /*
- * Perform conversion
- */
- i_scale_count = i_pic_height;
- for( i_y = 0; i_y < i_height; i_y++ )
- {
- /* Mark beginnning of line for possible later line copy, and initialize
- * buffer */
- p_pic_start = p_pic;
- p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
-
- /* Do YUV conversion to buffer - YUV picture is always formed of 16
- * pixels wide blocks */
- for( i_x = i_width / 16; i_x--; )
- {
- CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
- CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
- }
-
- /* Do horizontal and vertical scaling */
- SCALE_WIDTH;
- SCALE_HEIGHT(444, 2);
- }
-}
-
-/*****************************************************************************
- * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 3 Bpp
- *****************************************************************************/
-static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- /* XXX?? */
-}
-
-/*****************************************************************************
- * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 3 Bpp
- *****************************************************************************/
-static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- /* XXX?? */
-}
-
-/*****************************************************************************
- * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 3 Bpp
- *****************************************************************************/
-static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- /* XXX?? */
-}
-
-/*****************************************************************************
- * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
- *****************************************************************************/
-static void ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- boolean_t b_horizontal_scaling; /* horizontal scaling type */
- int i_vertical_scaling; /* vertical scaling type */
- int i_x, i_y; /* horizontal and vertical indexes */
- int i_scale_count; /* scale modulo counter */
- int i_uval, i_vval; /* U and V samples */
- int i_red, i_green, i_blue; /* U and V modified samples */
- int i_chroma_width; /* chroma width */
- u32 * p_yuv; /* base conversion table */
- u32 * p_ybase; /* Y dependant conversion table */
- u32 * p_pic_start; /* beginning of the current line for copy */
- u32 * p_buffer_start; /* conversion buffer start */
- u32 * p_buffer; /* conversion buffer pointer */
- int * p_offset_start; /* offset array start */
- int * p_offset; /* offset array pointer */
-
- /*
- * Initialize some values - i_pic_line_width will store the line skip
- */
- i_pic_line_width -= i_pic_width;
- i_chroma_width = i_width / 2;
- p_yuv = p_vout->yuv.yuv.p_rgb32;
- p_buffer_start = p_vout->yuv.p_buffer;
- p_offset_start = p_vout->yuv.p_offset;
- SetOffset( i_width, i_height, i_pic_width, i_pic_height,
- &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
-
- /*
- * Perform conversion
- */
- i_scale_count = i_pic_height;
- for( i_y = 0; i_y < i_height; i_y++ )
- {
- /* Mark beginnning of line for possible later line copy, and initialize
- * buffer */
- p_pic_start = p_pic;
- p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
-
- /* Do YUV conversion to buffer - YUV picture is always formed of 16
- * pixels wide blocks */
- for( i_x = i_width / 16; i_x--; )
- {
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- }
-
- /* Do horizontal and vertical scaling */
- SCALE_WIDTH;
- SCALE_HEIGHT(420, 4);
- }
-}
-
-/*****************************************************************************
- * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
- *****************************************************************************/
-static void ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- boolean_t b_horizontal_scaling; /* horizontal scaling type */
- int i_vertical_scaling; /* vertical scaling type */
- int i_x, i_y; /* horizontal and vertical indexes */
- int i_scale_count; /* scale modulo counter */
- int i_uval, i_vval; /* U and V samples */
- int i_red, i_green, i_blue; /* U and V modified samples */
- int i_chroma_width; /* chroma width */
- u32 * p_yuv; /* base conversion table */
- u32 * p_ybase; /* Y dependant conversion table */
- u32 * p_pic_start; /* beginning of the current line for copy */
- u32 * p_buffer_start; /* conversion buffer start */
- u32 * p_buffer; /* conversion buffer pointer */
- int * p_offset_start; /* offset array start */
- int * p_offset; /* offset array pointer */
-
- /*
- * Initialize some values - i_pic_line_width will store the line skip
- */
- i_pic_line_width -= i_pic_width;
- i_chroma_width = i_width / 2;
- p_yuv = p_vout->yuv.yuv.p_rgb32;
- p_buffer_start = p_vout->yuv.p_buffer;
- p_offset_start = p_vout->yuv.p_offset;
- SetOffset( i_width, i_height, i_pic_width, i_pic_height,
- &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
-
- /*
- * Perform conversion
- */
- i_scale_count = i_pic_height;
- for( i_y = 0; i_y < i_height; i_y++ )
- {
- /* Mark beginnning of line for possible later line copy, and initialize
- * buffer */
- p_pic_start = p_pic;
- p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
-
- /* Do YUV conversion to buffer - YUV picture is always formed of 16
- * pixels wide blocks */
- for( i_x = i_width / 16; i_x--; )
- {
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
- }
-
- /* Do horizontal and vertical scaling */
- SCALE_WIDTH;
- SCALE_HEIGHT(422, 4);
- }
-}
-
-/*****************************************************************************
- * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
- *****************************************************************************/
-static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
- int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
- int i_matrix_coefficients )
-{
- boolean_t b_horizontal_scaling; /* horizontal scaling type */
- int i_vertical_scaling; /* vertical scaling type */
- int i_x, i_y; /* horizontal and vertical indexes */
- int i_scale_count; /* scale modulo counter */
- int i_uval, i_vval; /* U and V samples */
- int i_red, i_green, i_blue; /* U and V modified samples */
- int i_chroma_width; /* chroma width, not used */
- u32 * p_yuv; /* base conversion table */
- u32 * p_ybase; /* Y dependant conversion table */
- u32 * p_pic_start; /* beginning of the current line for copy */
- u32 * p_buffer_start; /* conversion buffer start */
- u32 * p_buffer; /* conversion buffer pointer */
- int * p_offset_start; /* offset array start */
- int * p_offset; /* offset array pointer */
-
- /*
- * Initialize some values - i_pic_line_width will store the line skip
- */
- i_pic_line_width -= i_pic_width;
- p_yuv = p_vout->yuv.yuv.p_rgb32;
- p_buffer_start = p_vout->yuv.p_buffer;
- p_offset_start = p_vout->yuv.p_offset;
- SetOffset( i_width, i_height, i_pic_width, i_pic_height,
- &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
-
- /*
- * Perform conversion
- */
- i_scale_count = i_pic_height;
- for( i_y = 0; i_y < i_height; i_y++ )
- {
- /* Mark beginnning of line for possible later line copy, and initialize
- * buffer */
- p_pic_start = p_pic;
- p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
-
- /* Do YUV conversion to buffer - YUV picture is always formed of 16
- * pixels wide blocks */
- for( i_x = i_width / 16; i_x--; )
- {
- CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
- CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
- }
-
- /* Do horizontal and vertical scaling */
- SCALE_WIDTH;
- SCALE_HEIGHT(444, 4);
- }
-}
-
-/*-------------------- walken code follows ----------------------------------*/
-
-/*
- * YUV to RGB routines.
- *
- * these routines calculate r, g and b values from each pixel's y, u and v.
- * these r, g an b values are then passed thru a table lookup to take the
- * gamma curve into account and find the corresponding pixel value.
- *
- * the table must store more than 3*256 values because of the possibility
- * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
- * values are in the following intervals :
- * -176 to 255+176 for red
- * -133 to 255+133 for green
- * -222 to 255+222 for blue
- *
- * If the input y,u,v values are right, the r,g,b results are not expected
- * to move out of the 0 to 255 interval but who knows what will happen in
- * real use...
- *
- * the red, green and blue conversion tables are stored in a single 1935-entry
- * array. The respective positions of each component in the array have been
- * calculated to minimize the cache interactions of the 3 tables.
- */
-
-#if 0
-/* XXX?? */
-static void yuvToRgb24 (unsigned char * Y,
- unsigned char * U, unsigned char * V,
- char * dest, int table[1935], int width)
-{
- int i;
- int u;
- int v;
- int uvRed;
- int uvGreen;
- int uvBlue;
- int * tableY;
- int tmp24;
-
- i = width >> 3;
- while (i--) {
- u = *(U++);
- v = *(V++);
- uvRed = (V_RED_COEF*v) >> SHIFT;
- uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
- uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
- tableY = table + *(Y++);
- tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
- tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
- uvGreen] |
- tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
- *(dest++) = tmp24;
- *(dest++) = tmp24 >> 8;
- *(dest++) = tmp24 >> 16;
-
- tableY = table + *(Y++);
- tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
- tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
- uvGreen] |
- tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
- *(dest++) = tmp24;
- *(dest++) = tmp24 >> 8;
- *(dest++) = tmp24 >> 16;
-
- u = *(U++);
- v = *(V++);
- uvRed = (V_RED_COEF*v) >> SHIFT;
- uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
- uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
- tableY = table + *(Y++);
- tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
- tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
- uvGreen] |
- tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
- *(dest++) = tmp24;
- *(dest++) = tmp24 >> 8;
- *(dest++) = tmp24 >> 16;
-
- tableY = table + *(Y++);
- tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
- tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
- uvGreen] |
- tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
- *(dest++) = tmp24;
- *(dest++) = tmp24 >> 8;
- *(dest++) = tmp24 >> 16;
-
- u = *(U++);
- v = *(V++);
- uvRed = (V_RED_COEF*v) >> SHIFT;
- uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
- uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
- tableY = table + *(Y++);
- tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
- tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
- uvGreen] |
- tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
- *(dest++) = tmp24;
- *(dest++) = tmp24 >> 8;
- *(dest++) = tmp24 >> 16;
-
- tableY = table + *(Y++);
- tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
- tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
- uvGreen] |
- tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
- *(dest++) = tmp24;
- *(dest++) = tmp24 >> 8;
- *(dest++) = tmp24 >> 16;
-
- u = *(U++);
- v = *(V++);
- uvRed = (V_RED_COEF*v) >> SHIFT;
- uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
- uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
- tableY = table + *(Y++);
- tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
- tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
- uvGreen] |
- tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
- *(dest++) = tmp24;
- *(dest++) = tmp24 >> 8;
- *(dest++) = tmp24 >> 16;
-
- tableY = table + *(Y++);
- tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
- tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
- uvGreen] |
- tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
- *(dest++) = tmp24;
- *(dest++) = tmp24 >> 8;
- *(dest++) = tmp24 >> 16;
- }
-
- i = (width & 7) >> 1;
- while (i--) {
- u = *(U++);
- v = *(V++);
- uvRed = (V_RED_COEF*v) >> SHIFT;
- uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
- uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
- tableY = table + *(Y++);
- tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
- tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
- uvGreen] |
- tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
- *(dest++) = tmp24;
- *(dest++) = tmp24 >> 8;
- *(dest++) = tmp24 >> 16;
-
- tableY = table + *(Y++);
- tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
- tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
- uvGreen] |
- tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
- *(dest++) = tmp24;
- *(dest++) = tmp24 >> 8;
- *(dest++) = tmp24 >> 16;
- }
-
- if (width & 1) {
- u = *(U++);
- v = *(V++);
- uvRed = (V_RED_COEF*v) >> SHIFT;
- uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
- uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
- tableY = table + *(Y++);
- tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
- tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
- uvGreen] |
- tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
- *(dest++) = tmp24;
- *(dest++) = tmp24 >> 8;
- *(dest++) = tmp24 >> 16;
- }
-}
-#endif
/*****************************************************************************
* video_yuv.h: YUV transformation functions
- * Provides functions prototypes to perform the YUV conversion. The functions
- * may be implemented in one of the video_yuv_* files.
+ * These functions set up YUV tables for colorspace conversion
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
int vout_ResetYUV ( vout_thread_t *p_vout );
void vout_EndYUV ( vout_thread_t *p_vout );
-/*****************************************************************************
- * External prototypes
- *****************************************************************************/
-#ifdef HAVE_MMX
-
-/* YUV transformations for MMX - in video_yuv_mmx.S
- * p_y, p_u, p_v: Y U and V planes
- * i_width, i_height: frames dimensions (pixels)
- * i_ypitch, i_vpitch: Y and V lines sizes (bytes)
- * i_aspect: vertical aspect factor
- * p_pic: RGB frame
- * i_dci_offset: XXX?? x offset for left image border
- * i_offset_to_line_0: XXX?? x offset for left image border
- * i_pitch: RGB line size (bytes)
- * i_colortype: 0 for 565, 1 for 555 */
-void ConvertYUV420RGB16MMX( u8* p_y, u8* p_u, u8 *p_v,
- unsigned int i_width, unsigned int i_height,
- unsigned int i_ypitch, unsigned int i_vpitch,
- unsigned int i_aspect, u8 *p_pic,
- u32 i_dci_offset, u32 i_offset_to_line_0,
- int i_pitch, int i_colortype );
-#endif
{
vpar_thread_t * p_vpar;
- intf_DbgMsg("vpar debug: creating video parser thread\n");
+ intf_DbgMsg( "vpar debug: creating video parser thread\n" );
/* Allocate the memory needed to store the thread's structure */
if ( (p_vpar = (vpar_thread_t *)malloc( sizeof(vpar_thread_t) )) == NULL )
{
- intf_ErrMsg("vpar error: not enough memory for vpar_CreateThread() to create the new thread\n");
+ intf_ErrMsg( "vpar error: not enough memory "
+ "for vpar_CreateThread() to create the new thread\n");
return( NULL );
}
/*
* Initialize the input properties
*/
- /* Initialize the decoder fifo's data lock and conditional variable and set
- * its buffer as empty */
+ /* Initialize the decoder fifo's data lock and conditional variable
+ * and set its buffer as empty */
vlc_mutex_init( &p_vpar->fifo.data_lock );
vlc_cond_init( &p_vpar->fifo.data_wait );
p_vpar->fifo.i_start = 0;
p_vpar->bit_stream.fifo.buffer = 0;
p_vpar->bit_stream.fifo.i_available = 0;
-/* FIXME !!!!?? */
-p_vpar->p_vout = p_main->p_intf->p_vout;
+ /* FIXME !!!!?? */
+ p_vpar->p_vout = p_main->p_intf->p_vout;
/* Spawn the video parser thread */
- if ( vlc_thread_create(&p_vpar->thread_id, "video parser", (vlc_thread_func_t)RunThread, (void *)p_vpar) )
+ 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\n");
free( p_vpar );
*****************************************************************************/
void vpar_DestroyThread( vpar_thread_t *p_vpar /*, int *pi_status */ )
{
- intf_DbgMsg("vpar debug: requesting termination of video parser thread %p\n", p_vpar);
+ intf_DbgMsg( "vpar debug: requesting termination of "
+ "video parser thread %p\n", p_vpar);
/* Ask thread to kill itself */
p_vpar->b_die = 1;
int i_dummy;
#endif
-#ifdef SAM_SYNCHRO
- int i_dummy;
-#endif
-
intf_DbgMsg("vpar debug: initializing video parser thread %p\n", p_vpar);
/* Our first job is to initialize the bit stream structure with the
vlc_cond_wait( &p_vpar->fifo.data_wait, &p_vpar->fifo.data_lock );
}
p_vpar->bit_stream.p_ts = DECODER_FIFO_START( p_vpar->fifo )->p_first_ts;
- p_vpar->bit_stream.p_byte = p_vpar->bit_stream.p_ts->buffer + p_vpar->bit_stream.p_ts->i_payload_start;
- p_vpar->bit_stream.p_end = p_vpar->bit_stream.p_ts->buffer + p_vpar->bit_stream.p_ts->i_payload_end;
+ p_vpar->bit_stream.p_byte = p_vpar->bit_stream.p_ts->buffer
+ + p_vpar->bit_stream.p_ts->i_payload_start;
+ p_vpar->bit_stream.p_end = p_vpar->bit_stream.p_ts->buffer
+ + p_vpar->bit_stream.p_ts->i_payload_end;
vlc_mutex_unlock( &p_vpar->fifo.data_lock );
/* Initialize parsing data */
}
#else
/* Fake a video_decoder thread */
- if( (p_vpar->pp_vdec[0] = (vdec_thread_t *)malloc(sizeof( vdec_thread_t ))) == NULL
- || vdec_InitThread( p_vpar->pp_vdec[0] ) )
+ if( (p_vpar->pp_vdec[0] = (vdec_thread_t *)malloc(sizeof( vdec_thread_t )))
+ == NULL || vdec_InitThread( p_vpar->pp_vdec[0] ) )
{
return( 1 );
}
* Initialize the synchro properties
*/
#ifdef SAM_SYNCHRO
- p_vpar->synchro.i_last_decode_pts = 0;
- p_vpar->synchro.i_last_display_pts = 0;
- p_vpar->synchro.i_images_since_pts = 0;
+ p_vpar->synchro.i_last_pts = 0;
+
/* for i frames */
- p_vpar->synchro.i_last_i_pts = 0;
- p_vpar->synchro.theorical_fps = 25;
- p_vpar->synchro.i_last_nondropped_i_pts = 0;
- p_vpar->synchro.actual_fps = 20;
+ p_vpar->synchro.i_last_seen_I_pts = 0;
+ p_vpar->synchro.i_last_kept_I_pts = 0;
+
/* the fifo */
- p_vpar->synchro.i_fifo_start = 0;
- p_vpar->synchro.i_fifo_stop = 0;
- /* the counter */
- p_vpar->synchro.modulo = 0;
+ p_vpar->synchro.i_start = 0;
+ p_vpar->synchro.i_stop = 0;
+
/* mean decoding time - at least 200 ms for a slow machine */
- p_vpar->synchro.i_mean_decode_time = 200000;
+ p_vpar->synchro.i_delay = 200000;
+ p_vpar->synchro.i_theorical_delay = 40000; /* 25 fps */
/* assume we can display all Is and 2 Ps */
- p_vpar->synchro.can_display_i = 1;
- p_vpar->synchro.can_display_p = 0;
+ p_vpar->synchro.b_all_I = 1;
+ p_vpar->synchro.b_all_P = 0;
p_vpar->synchro.displayable_p = 2;
- p_vpar->synchro.can_display_b = 0;
+ p_vpar->synchro.b_all_B = 0;
p_vpar->synchro.displayable_b = 0;
/* assume there were about 3 P and 6 B images between I's */
- p_vpar->synchro.current_p_count = 1;
- p_vpar->synchro.nondropped_p_count = 1;
- p_vpar->synchro.p_count_predict = 3;
- p_vpar->synchro.current_b_count = 1;
- p_vpar->synchro.nondropped_b_count = 1;
- p_vpar->synchro.b_count_predict = 6;
- for( i_dummy = 0; i_dummy < 6; i_dummy++)
- {
- p_vpar->synchro.tab_p[i_dummy].mean = 3;
- p_vpar->synchro.tab_p[i_dummy].deviation = .5;
- p_vpar->synchro.tab_b[i_dummy].mean = 6;
- p_vpar->synchro.tab_b[i_dummy].deviation = .5;
- }
+ p_vpar->synchro.i_P_seen = p_vpar->synchro.i_P_kept = 1;
+ p_vpar->synchro.i_B_seen = p_vpar->synchro.i_B_kept = 1;
#endif
#ifdef MEUUH_SYNCHRO
/* Trash all received PES packets */
while( !DECODER_FIFO_ISEMPTY(p_vpar->fifo) )
{
- input_NetlistFreePES( p_vpar->bit_stream.p_input, DECODER_FIFO_START(p_vpar->fifo) );
+ input_NetlistFreePES( p_vpar->bit_stream.p_input,
+ DECODER_FIFO_START(p_vpar->fifo) );
DECODER_FIFO_INCSTART( p_vpar->fifo );
}
*/
#ifdef SAM_SYNCHRO
-/*****************************************************************************
- * vpar_SynchroUpdateTab : Update a mean table in the synchro structure
- *****************************************************************************/
-float vpar_SynchroUpdateTab( video_synchro_tab_t * tab, int count )
-{
-
- tab->mean = ( tab->mean + MAX_COUNT * count ) / ( MAX_COUNT + 1 );
- tab->deviation = ( tab->deviation + MAX_COUNT * abs (tab->mean - count) )
- / ( MAX_COUNT + 1 );
-
- return tab->deviation;
-}
/*****************************************************************************
* vpar_SynchroUpdateStructures : Update the synchro structures
*****************************************************************************/
void vpar_SynchroUpdateStructures( vpar_thread_t * p_vpar,
- int i_coding_type, int dropped )
+ int i_coding_type, boolean_t b_kept )
{
- float candidate_deviation;
- float optimal_deviation;
- float predict;
- mtime_t i_current_pts;
- mtime_t i_delay;
- mtime_t i_displaydate;
- decoder_fifo_t * decoder_fifo = p_vpar->bit_stream.p_decoder_fifo;
-
- /* interpolate the current _decode_ PTS */
- i_current_pts = decoder_fifo->buffer[decoder_fifo->i_start]->b_has_pts ?
- decoder_fifo->buffer[decoder_fifo->i_start]->i_pts :
- 0;
- if( !i_current_pts )
+ mtime_t i_delay;
+ mtime_t i_pts;
+ pes_packet_t * p_pes = p_vpar->bit_stream.p_decoder_fifo->buffer[
+ p_vpar->bit_stream.p_decoder_fifo->i_start ];
+
+ /* try to guess the current DTS and PTS */
+ if( p_pes->b_has_pts )
{
- i_current_pts = p_vpar->synchro.i_last_decode_pts
- + 1000000.0 / (1 + p_vpar->synchro.actual_fps);
- }
- p_vpar->synchro.i_last_decode_pts = i_current_pts;
+ i_pts = p_pes->i_pts;
- /* see if the current image has a pts - if not, set to 0 */
- p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_stop].i_pts
- = i_current_pts;
+ /* if the image is I type, then the presentation timestamp is
+ * the PTS of the PES. Otherwise, we calculate it with the
+ * theorical framerate value */
+ if( i_coding_type == I_CODING_TYPE )
+ {
+ p_vpar->synchro.i_last_pts = p_pes->i_pts;
+ }
+ else
+ {
+ p_vpar->synchro.i_last_pts += p_vpar->synchro.i_theorical_delay;
+ }
- /* update display time */
- i_displaydate = decoder_fifo->buffer[decoder_fifo->i_start]->b_has_pts ?
- decoder_fifo->buffer[decoder_fifo->i_start]->i_pts :
- 0;
- if( !i_displaydate || i_coding_type != I_CODING_TYPE )
+ p_pes->b_has_pts = 0;
+ }
+ else
{
- if (!p_vpar->synchro.i_images_since_pts )
- p_vpar->synchro.i_images_since_pts = 10;
-
- i_displaydate = p_vpar->synchro.i_last_display_pts
- + 1000000.0 / (p_vpar->synchro.theorical_fps);
+ p_vpar->synchro.i_last_pts += p_vpar->synchro.i_theorical_delay;
+ i_pts = p_vpar->synchro.i_last_pts;
}
- decoder_fifo->buffer[decoder_fifo->i_start]->b_has_pts = 0;
-
- p_vpar->synchro.i_images_since_pts--;
- p_vpar->synchro.i_last_display_pts = i_displaydate;
-
-
-
/* update structures */
switch(i_coding_type)
{
case P_CODING_TYPE:
- p_vpar->synchro.current_p_count++;
- if( !dropped ) p_vpar->synchro.nondropped_p_count++;
+ p_vpar->synchro.i_P_seen++;
+ if( b_kept ) p_vpar->synchro.i_P_kept++;
break;
case B_CODING_TYPE:
- p_vpar->synchro.current_b_count++;
- if( !dropped ) p_vpar->synchro.nondropped_b_count++;
+ p_vpar->synchro.i_B_seen++;
+ if( b_kept ) p_vpar->synchro.i_B_kept++;
break;
case I_CODING_TYPE:
- /* update information about images we can decode */
- if (i_current_pts != p_vpar->synchro.i_last_i_pts)
- {
- if ( p_vpar->synchro.i_last_i_pts && i_current_pts != p_vpar->synchro.i_last_i_pts)
- {
- p_vpar->synchro.theorical_fps = (p_vpar->synchro.theorical_fps + 1000000.0 * (1 + p_vpar->synchro.current_b_count + p_vpar->synchro.current_p_count) / (i_current_pts - p_vpar->synchro.i_last_i_pts)) / 2;
- }
- p_vpar->synchro.i_last_i_pts = i_current_pts;
- }
-
- if( !dropped )
+ /* update the last I PTS we have, we need it to
+ * calculate the theorical framerate */
+ if (i_pts != p_vpar->synchro.i_last_seen_I_pts)
{
- if ( p_vpar->synchro.i_last_nondropped_i_pts && i_current_pts != p_vpar->synchro.i_last_nondropped_i_pts)
+ if ( p_vpar->synchro.i_last_seen_I_pts )
{
- p_vpar->synchro.actual_fps = (p_vpar->synchro.actual_fps + 1000000.0 * (1 + p_vpar->synchro.nondropped_b_count + p_vpar->synchro.nondropped_p_count) / (i_current_pts - p_vpar->synchro.i_last_nondropped_i_pts)) / 2;
+ p_vpar->synchro.i_theorical_delay =
+ ( i_pts - p_vpar->synchro.i_last_seen_I_pts )
+ / ( 1 + p_vpar->synchro.i_B_seen
+ + p_vpar->synchro.i_P_seen);
}
-
- }
-
-
- /* update all the structures for P images */
-
- /* period == 1 */
- optimal_deviation = vpar_SynchroUpdateTab(
- &p_vpar->synchro.tab_p[0],
- p_vpar->synchro.current_p_count);
- predict = p_vpar->synchro.tab_p[0].mean;
-
- /* period == 2 */
- candidate_deviation = vpar_SynchroUpdateTab(
- &p_vpar->synchro.tab_p[1 + (p_vpar->synchro.modulo & 0x1)],
- p_vpar->synchro.current_p_count);
- if (candidate_deviation < optimal_deviation)
- {
- optimal_deviation = candidate_deviation;
- predict = p_vpar->synchro.tab_p[1 + (p_vpar->synchro.modulo & 0x1)].mean;
- }
-
- /* period == 3 */
- candidate_deviation = vpar_SynchroUpdateTab(
- &p_vpar->synchro.tab_p[3 + (p_vpar->synchro.modulo % 3)],
- p_vpar->synchro.current_p_count);
- if (candidate_deviation < optimal_deviation)
- {
- optimal_deviation = candidate_deviation;
- predict = p_vpar->synchro.tab_p[1 + (p_vpar->synchro.modulo % 3)].mean;
+ p_vpar->synchro.i_last_seen_I_pts = i_pts;
}
- p_vpar->synchro.p_count_predict = predict;
- p_vpar->synchro.current_p_count = 0;
-
-
- /* update all the structures for B images */
-
- /* period == 1 */
- optimal_deviation = vpar_SynchroUpdateTab(
- &p_vpar->synchro.tab_b[0],
- p_vpar->synchro.current_b_count);
- predict = p_vpar->synchro.tab_b[0].mean;
-
- /* period == 2 */
- candidate_deviation = vpar_SynchroUpdateTab(
- &p_vpar->synchro.tab_b[1 + (p_vpar->synchro.modulo & 0x1)],
- p_vpar->synchro.current_b_count);
- if (candidate_deviation < optimal_deviation)
- {
- optimal_deviation = candidate_deviation;
- predict = p_vpar->synchro.tab_b[1 + (p_vpar->synchro.modulo & 0x1)].mean;
- }
-
- /* period == 3 */
- candidate_deviation = vpar_SynchroUpdateTab(
- &p_vpar->synchro.tab_b[3 + (p_vpar->synchro.modulo % 3)],
- p_vpar->synchro.current_b_count);
- if (candidate_deviation < optimal_deviation)
- {
- optimal_deviation = candidate_deviation;
- predict = p_vpar->synchro.tab_b[1 + (p_vpar->synchro.modulo % 3)].mean;
- }
-
- p_vpar->synchro.b_count_predict = predict;
- p_vpar->synchro.current_b_count = 0;
-
/* now we calculated all statistics, it's time to
* decide what we have the time to display
*/
- i_delay = i_current_pts - p_vpar->synchro.i_last_nondropped_i_pts;
+ i_delay = i_pts - p_vpar->synchro.i_last_kept_I_pts;
- p_vpar->synchro.can_display_i
- = ( p_vpar->synchro.i_mean_decode_time < i_delay );
+ p_vpar->synchro.b_all_I
+ = ( p_vpar->synchro.i_delay < i_delay );
- p_vpar->synchro.can_display_p
- = ( p_vpar->synchro.i_mean_decode_time
- * (1 + p_vpar->synchro.p_count_predict) < i_delay );
+ p_vpar->synchro.b_all_P
+ = ( p_vpar->synchro.i_delay
+ * (1 + p_vpar->synchro.i_P_seen) < i_delay );
- if( !p_vpar->synchro.can_display_p )
+ if( !p_vpar->synchro.b_all_P )
{
p_vpar->synchro.displayable_p
- = -1 + i_delay / p_vpar->synchro.i_mean_decode_time;
+ //= -1.0 + (float)i_delay / (float)p_vpar->synchro.i_delay;
+ = (-1.0 + (float)p_vpar->synchro.displayable_p + (float)i_delay / (float)p_vpar->synchro.i_delay) / 2.0;
if( p_vpar->synchro.displayable_p < 0 )
p_vpar->synchro.displayable_p = 0;
+
+ p_vpar->synchro.b_all_B = 0;
+ p_vpar->synchro.displayable_b = 0;
}
else
- p_vpar->synchro.displayable_p = 0;
-
- if( p_vpar->synchro.can_display_p
- && !(p_vpar->synchro.can_display_b
- = ( p_vpar->synchro.i_mean_decode_time
- * (1 + p_vpar->synchro.b_count_predict
- + p_vpar->synchro.p_count_predict)) < i_delay) )
{
- p_vpar->synchro.displayable_b
- = -2.0 + i_delay / p_vpar->synchro.i_mean_decode_time
- - p_vpar->synchro.can_display_p;
+ p_vpar->synchro.displayable_p = p_vpar->synchro.i_P_seen;
+
+ if( !(p_vpar->synchro.b_all_B
+ = ( p_vpar->synchro.i_delay
+ * (1 + p_vpar->synchro.i_B_seen
+ + p_vpar->synchro.i_P_seen)) < i_delay) )
+ {
+ p_vpar->synchro.displayable_b
+ //= -2.0 + i_delay / p_vpar->synchro.i_delay - p_vpar->synchro.b_all_P;
+ = ( -2.0 + (float)p_vpar->synchro.displayable_b + (float)i_delay / (float)p_vpar->synchro.i_delay - (float)p_vpar->synchro.b_all_P) / 2.0;
+ }
+ else
+ {
+ p_vpar->synchro.displayable_b = p_vpar->synchro.i_B_seen;
+ }
}
- else
- p_vpar->synchro.displayable_b = 0;
-#if 0
- intf_DbgMsg( "I %i P %i (%f) B %i (%f)\n",
- p_vpar->synchro.can_display_i,
- p_vpar->synchro.can_display_p,
- p_vpar->synchro.displayable_p,
- p_vpar->synchro.can_display_b,
- p_vpar->synchro.displayable_b );
+#if 1
+ if( p_vpar->synchro.b_all_I )
+ intf_ErrMsg( "I: all " );
+ if( p_vpar->synchro.b_all_P )
+ intf_ErrMsg( "P: all " );
+ else if( p_vpar->synchro.displayable_p > 0 )
+ intf_ErrMsg( "P: %f ", p_vpar->synchro.displayable_p );
+ if( p_vpar->synchro.b_all_B )
+ intf_ErrMsg( "B: all" );
+ else if( p_vpar->synchro.displayable_b > 0 )
+ intf_ErrMsg( "B: %f", p_vpar->synchro.displayable_b );
+ intf_ErrMsg( "\n" );
#endif
+ p_vpar->synchro.i_P_seen = 0;
+ p_vpar->synchro.i_B_seen = 0;
/* update some values */
- if( !dropped )
+ if( b_kept )
{
- p_vpar->synchro.i_last_nondropped_i_pts = i_current_pts;
- p_vpar->synchro.nondropped_p_count = 0;
- p_vpar->synchro.nondropped_b_count = 0;
+ p_vpar->synchro.i_last_kept_I_pts = i_pts;
+ p_vpar->synchro.i_P_kept = 0;
+ p_vpar->synchro.i_B_kept = 0;
}
break;
-
}
-
- p_vpar->synchro.modulo++;
-
}
/*****************************************************************************
boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
int i_structure )
{
- mtime_t i_delay = p_vpar->synchro.i_last_decode_pts - mdate();
+ mtime_t i_delay = p_vpar->synchro.i_last_pts - mdate();
switch( i_coding_type )
{
case I_CODING_TYPE:
- return( p_vpar->synchro.can_display_i );
+ //intf_ErrMsg( " I %f %f\nI ", 1000000.0 / p_vpar->synchro.i_theorical_delay, 1000000.0 / p_vpar->synchro.i_delay );
+ return( p_vpar->synchro.b_all_I );
case P_CODING_TYPE:
- if( p_vpar->synchro.can_display_p )
+ if( p_vpar->synchro.b_all_P )
+ {
+ //intf_ErrMsg( " p " );
return( 1 );
+ }
if( p_vpar->synchro.displayable_p * i_delay
- < p_vpar->synchro.i_mean_decode_time )
+ < p_vpar->synchro.i_delay )
{
- //intf_ErrMsg( "trashed a P\n" );
+ //intf_ErrMsg( " - " );
return( 0 );
}
p_vpar->synchro.displayable_p--;
+ //intf_ErrMsg( " p> " );
return( 1 );
case B_CODING_TYPE:
- if( p_vpar->synchro.can_display_b )
+ if( p_vpar->synchro.b_all_B )
+ {
+ //intf_ErrMsg( "b " );
return( 1 );
+ }
- /* modulo & 0x3 is here to add some randomness */
- if( i_delay < (1 + (p_vpar->synchro.modulo & 0x3))
- * p_vpar->synchro.i_mean_decode_time )
+ if( p_vpar->synchro.displayable_b <= 0 )
{
- //intf_ErrMsg( "trashed a B\n" );
+ //intf_ErrMsg( " " );
return( 0 );
}
- if( p_vpar->synchro.displayable_b <= 0 )
+ if( i_delay < 0 )
+ {
+ //intf_ErrMsg( "· " );
+ p_vpar->synchro.displayable_b -= 0.5;
return( 0 );
+ }
+ //intf_ErrMsg( "b " );
p_vpar->synchro.displayable_b--;
return( 1 );
}
void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
int i_structure )
{
- vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 1);
+ vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 0);
}
void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
int i_structure )
{
- vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 0);
+ vpar_SynchroUpdateStructures (p_vpar, i_coding_type, 1);
- p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_stop].i_decode_date = mdate();
- p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_stop].i_image_type
- = i_coding_type;
+ p_vpar->synchro.i_date_fifo[p_vpar->synchro.i_stop] = mdate();
- p_vpar->synchro.i_fifo_stop = (p_vpar->synchro.i_fifo_stop + 1) & 0xf;
+ FIFO_INCREMENT( i_stop );
}
*****************************************************************************/
void vpar_SynchroEnd( vpar_thread_t * p_vpar )
{
- mtime_t i_decode_time;
-
- i_decode_time = (mdate() -
- p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_start].i_decode_date)
- / ( (p_vpar->synchro.i_fifo_stop - p_vpar->synchro.i_fifo_start) & 0x0f);
+ if( p_vpar->synchro.i_stop != p_vpar->synchro.i_start )
+ {
+ mtime_t i_delay;
- p_vpar->synchro.i_mean_decode_time =
- ( 7 * p_vpar->synchro.i_mean_decode_time + i_decode_time ) / 8;
+ i_delay = ( mdate() -
+ p_vpar->synchro.i_date_fifo[p_vpar->synchro.i_start] )
+ / ( (p_vpar->synchro.i_stop - p_vpar->synchro.i_start) & 0x0f );
- /* intf_ErrMsg( "decoding time was %lli\n",
- p_vpar->synchro.i_mean_decode_time ); */
+ p_vpar->synchro.i_delay =
+ ( 7 * p_vpar->synchro.i_delay + i_delay ) >> 3;
- p_vpar->synchro.i_fifo_start = (p_vpar->synchro.i_fifo_start + 1) & 0xf;
+#if 0
+ intf_ErrMsg( "decode %lli (mean %lli, theorical %lli)\n",
+ i_delay, p_vpar->synchro.i_delay,
+ p_vpar->synchro.i_theorical_delay );
+#endif
+ }
+ else
+ {
+ intf_ErrMsg( "vpar error: critical ! fifo full\n" );
+ }
+ FIFO_INCREMENT( i_start );
}
/*****************************************************************************
*****************************************************************************/
mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
{
- mtime_t i_displaydate = p_vpar->synchro.i_last_display_pts;
-
#if 0
+
+ mtime_t i_displaydate = p_vpar->synchro.i_last_pts;
+
static mtime_t i_delta = 0;
- intf_ErrMsg( "displaying type %i with delay %lli and delta %lli\n",
- p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_start].i_image_type,
+ intf_ErrMsg( "displaying image with delay %lli and delta %lli\n",
i_displaydate - mdate(),
i_displaydate - i_delta );
intf_ErrMsg ( "theorical fps: %f - actual fps: %f \n",
- p_vpar->synchro.theorical_fps, p_vpar->synchro.actual_fps );
+ 1000000.0 / p_vpar->synchro.i_theorical_delay, 1000000.0 / p_vpar->synchro.i_delay );
i_delta = i_displaydate;
-#endif
return i_displaydate;
+#else
+
+ return p_vpar->synchro.i_last_pts;
+
+#endif
}
#endif
Copyright: GPL
Url: http://www.videolan.org/
Group: X11/Applications/Graphics
-Source0: http://www.videolan.org/packages/0.1.99c/vlc-0.1.99c.tar.gz
-Packager: Eric Doutreleau <Eric.doutreleau@int-evry.fr>
+Source0: http://www.videolan.org/packages/0.1.99d/vlc-0.1.99d.tar.gz
+Packager: Samuel Hocevar <sam@via.ecp.fr>
Buildroot: /tmp/vlc-build
Summary: VideoLAN Client.
%changelog
-* Thu Jun 15 2000 Eric Doutreleau < Eric.Doutreleau@int-evry.fr>
+* Sun Jun 18 2000 Samuel Hocevar <sam@via.ecp.fr>
+Took over the package
+
+* Thu Jun 15 2000 Eric Doutreleau <Eric.Doutreleau@int-evry.fr>
Initial package
%description
%setup
%build
-./configure --prefix=/usr --enable-ppro --enable-mmx --enable-gnome
+./configure --prefix=/usr --enable-mmx --enable-gnome
make
%install
mkdir -p $RPM_BUILD_ROOT/usr/lib