summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Salt <linux@youmustbejoking.demon.co.uk>2008-04-11 20:13:44 +0100
committerDarren Salt <linux@youmustbejoking.demon.co.uk>2008-04-11 20:13:44 +0100
commit494b949523221dc1f2ad65ac6827340235bbeb00 (patch)
tree7085117b5d482c39c072d6aa7c25254f214695b5
parent628c4cbd9d023e74a7c6805d7ec0f163f2c172d1 (diff)
parent5c29923095c53ae9788bf77b7b6d416a689434e6 (diff)
downloadxine-lib-494b949523221dc1f2ad65ac6827340235bbeb00.tar.gz
xine-lib-494b949523221dc1f2ad65ac6827340235bbeb00.tar.bz2
Merge from 1.1.
--HG-- rename : include/xine.h.in => include/xine.h
-rw-r--r--ChangeLog1
-rw-r--r--debian/changelog4
-rw-r--r--debian/control17
-rwxr-xr-xdebian/rules25
-rw-r--r--include/xine.h73
-rw-r--r--m4/audio_out.m410
-rw-r--r--src/audio_out/audio_pulse_out.c18
-rw-r--r--src/video_out/Makefile.am7
-rw-r--r--src/video_out/video_out_raw.c592
-rw-r--r--src/xine-engine/load_plugins.c30
10 files changed, 758 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 5a4583d71..f8a82747e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -73,6 +73,7 @@ xine-lib (1.1.12) 2008-??-??
* Various Real codec improvements, including:
- RV20 no longer causes segfaults (observed on amd64);
- Cook is now handled by ffmpeg.
+ * Added a video output plugin intended for passing raw data to the front end.
xine-lib (1.1.11.1) 2008-03-30
* Security fixes:
diff --git a/debian/changelog b/debian/changelog
index b015c2afa..29f4db045 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,7 +5,7 @@ xine-lib-1.2 (1.2.0~hg-0) experimental; urgency=low
-- Darren Salt <linux@youmustbejoking.demon.co.uk> Tue, 17 Apr 2007 16:50:37 +0100
-xine-lib (1.1.10.1+hg-0) unstable; urgency=low
+xine-lib (1.1.12~hg-0) unstable; urgency=low
[ Darren Salt ]
* Hg snapshot.
@@ -14,7 +14,7 @@ xine-lib (1.1.10.1+hg-0) unstable; urgency=low
* remove gs from build-dependencies
* change the maintainer field to xine-devel@lists.sourceforge.net.
- -- Darren Salt <linux@youmustbejoking.demon.co.uk> Thu, 07 Feb 2008 17:52:34 +0000
+ -- Darren Salt <linux@youmustbejoking.demon.co.uk> Tue, 08 Apr 2008 15:29:17 +0100
xine-lib (1.1.5~cvs-0) unstable; urgency=low
diff --git a/debian/control b/debian/control
index d3a1b1bde..e6b61a18c 100644
--- a/debian/control
+++ b/debian/control
@@ -7,23 +7,22 @@ Build-Depends: debhelper (>= 5.0.1), binutils (>= 2.12.90.0.9), pkg-config,
libavcodec-dev (>= 0.cvs20070307-3) | libavcodeccvs-dev,
libavformat-dev (>= 0.cvs20070307-3) | libavformatcvs-dev,
libpostproc-dev (>= 0.cvs20070307-3) | libpostproccvs-dev,
- libxcb-xinerama0-dev | libxv-dev (<< 1:1.0.3), libxcb-xv0-dev | libxv-dev (<< 1:1.0.3),
- libxcb-xvmc0-dev | libxv-dev (<< 1:1.0.3), libxcb-shm0-dev | libxv-dev (<< 1:1.0.3),
+ libxcb-xv0-dev | libxv-dev (<< 1:1.0.3),
+ libxcb-shm0-dev | libxv-dev (<< 1:1.0.3),
libxcb-shape0-dev | libxv-dev (<< 1:1.0.3),
- libxinerama-dev, libxv-dev, libxvmc-dev, libxt-dev,
+ libxinerama-dev, libxv-dev, libxvmc-dev, libxt-dev,
libasound2-dev [!kfreebsd-i386 !kfreebsd-amd64 !hurd-i386],
libaa1-dev, libcaca-dev, libmodplug-dev,
- libmagick9-dev, libpng12-dev, libfreetype6-dev,
+ libjack-dev, libpulse-dev, libartsc0-dev,
+ libmagick9-dev | libmagick-dev, libpng12-dev, libfreetype6-dev,
libogg-dev, libvorbis-dev, libtheora-dev,
libesd0-dev, libgnomevfs2-dev,
- zlib1g-dev, libartsc0-dev,
- liblircclient-dev, libjack0.100.0-dev | libjack-dev,
+ liblircclient-dev,
libdirectfb-dev (>= 0.9.22), libgtk2.0-dev,
- libflac-dev, libpulse-dev, libsdl1.2-dev, libwavpack-dev,
+ libflac-dev, libsdl1.2-dev, libwavpack-dev,
libsmbclient-dev, libspeex-dev, libmng-dev,
libmad0-dev, libmpcdec-dev, libcdio-dev (>= 0.76-1), libvcdinfo-dev,
- w3m, xmlto, librsvg2-bin
-Build-Conflicts: libdvdnav-dev
+ zlib1g-dev, w3m, xmlto, librsvg2-bin
Standards-Version: 3.7.2
Package: libxine-dev
diff --git a/debian/rules b/debian/rules
index 96dce1aa0..b2894e584 100755
--- a/debian/rules
+++ b/debian/rules
@@ -34,6 +34,18 @@ ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
BUILD_TARGET := debug
endif
+ifneq (,$(findstring mips,$(DEB_HOST_GNU_TYPE)))
+ DEB_BUILD_CONFIG_OPTIONS += PTHREAD_LIBS="-lpthread"
+endif
+
+# taken from the qemu package
+# Support multiple makes at once
+ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+NJOBS := $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+else
+NJOBS := 1
+endif
+
# note also "noauto" to inhibit running of autogen.sh
# the "optimize" flag disables compatibility hacks
@@ -67,6 +79,7 @@ CONFIGURE_FLAGS := --prefix=/usr \
--with-external-ffmpeg=soft \
--with-freetype \
--with-wavpack \
+ --enable-ipv6 \
$(DEB_BUILD_CONFIG_OPTIONS) \
CFLAGS="$(CFLAGS)"
@@ -87,7 +100,7 @@ endif
build: configure-stamp build-stamp
build-stamp:
dh_testdir
- $(MAKE)
+ $(MAKE) -j $(NJOBS)
touch build-stamp
update-config-sub-guess:
@@ -100,11 +113,11 @@ clean:
dh_testdir
dh_testroot
rm -f build-stamp configure-stamp po/*.gmo po/stamp-po
- -$(MAKE) distclean
- # remove more cruft leftover by autohell
- rm -f doc/faq/faq.html doc/faq/faq.txt doc/hackersguide/hackersguide.html m4/caca.m4
- -test -f .noauto || find . -name Makefile.in -print | xargs -r rm
- test -f .noauto || rm -rf compile config.guess configure depcomp install-sh ltmain.sh missing aclocal.m4 include/configure.h.in
+ if test -f .noauto; then \
+ [ ! -f Makefile ] || $(MAKE) distclean; \
+ else \
+ [ ! -f Makefile ] || $(MAKE) maintainer-clean; \
+ fi
dh_clean
install: build
diff --git a/include/xine.h b/include/xine.h
index 035f4ef7f..b96fdcf84 100644
--- a/include/xine.h
+++ b/include/xine.h
@@ -158,6 +158,7 @@ void xine_close_video_driver (xine_t *self, xine_video_port_t *driver) XINE_PRO
#define XINE_VISUAL_TYPE_CACA 8
#define XINE_VISUAL_TYPE_MACOSX 9
#define XINE_VISUAL_TYPE_XCB 11
+#define XINE_VISUAL_TYPE_RAW 12
/*
* free all resources, close all plugins, close engine.
@@ -1053,6 +1054,8 @@ const char *xine_get_post_plugin_description (xine_t *self,
/* get lists of available audio and video output plugins */
const char *const *xine_list_audio_output_plugins (xine_t *self) XINE_PROTECTED;
const char *const *xine_list_video_output_plugins (xine_t *self) XINE_PROTECTED;
+/* typemask is (1ULL << XINE_VISUAL_TYPE_FOO) | ... */
+const char *const *xine_list_video_output_plugins_typed (xine_t *self, uint64_t typemask) XINE_PROTECTED;
/* get list of available demultiplexor plugins */
const char *const *xine_list_demuxer_plugins(xine_t *self) XINE_PROTECTED;
@@ -1262,6 +1265,76 @@ typedef struct {
} xcb_visual_t;
+/**************************************************
+ * XINE_VO_RAW struct definitions
+ *************************************************/
+/* frame_format definitions */
+#define XINE_VORAW_YV12 1
+#define XINE_VORAW_YUY2 2
+#define XINE_VORAW_RGB 4
+
+/* maximum number of overlays the raw driver can handle */
+#define XINE_VORAW_MAX_OVL 16
+
+/* raw_overlay_t struct used in raw_overlay_cb callback */
+typedef struct {
+ uint8_t *ovl_rgba;
+ int ovl_w, ovl_h; /* overlay's width and height */
+ int ovl_x, ovl_y; /* overlay's top-left display position */
+} raw_overlay_t;
+
+/* this is the visual data struct any raw gui
+ * must supply to the xine_open_video_driver call
+ * ("data" parameter)
+ */
+typedef struct {
+ void *user_data;
+
+ /* OR'ed frame_format
+ * a frontend must at least support rgb
+ * a frontend supporting yuv must support both yv12 and yuy2
+ * then possible combinations are:
+ * XINE_VORAW_RGB ( rgb )
+ * XINE_VORAW_YV12|XINE_VORAW_YUY2|XINE_VORAW_RGB ( yv12, yuy2 and rgb )
+ *
+ * Be aware that rgb requires more cpu than yuv,
+ * so avoid its usage for video playback.
+ * However, it's usefull for single frame capture (e.g. thumbs)
+ */
+ int supported_formats;
+
+ /* raw output callback
+ * this will be called by the video driver for every frame
+ *
+ * If frame_format==XINE_VORAW_YV12, data0 points to frame_width*frame_height Y values
+ * data1 points to (frame_width/2)*(frame_height/2) U values
+ * data2 points to (frame_width/2)*(frame_height/2) V values
+ *
+ * If frame_format==XINE_VORAW_YUY2, data0 points to frame_width*frame_height*2 YU/Y²V values
+ * data1 is NULL
+ * data2 is NULL
+ *
+ * If frame_format==XINE_VORAW_RGB, data0 points to frame_width*frame_height*3 RGB values
+ * data1 is NULL
+ * data2 is NULL
+ */
+ void (*raw_output_cb) (void *user_data, int frame_format,
+ int frame_width, int frame_height,
+ double frame_aspect,
+ void *data0, void *data1, void *data2);
+
+ /* raw overlay callback
+ * this will be called by the video driver for every new overlay state
+ * overlays_array points to an array of num_ovl raw_overlay_t
+ * Note that num_ovl can be 0, meaning "end of overlay display"
+ * num_ovl is at most XINE_VORAW_MAX_OVL */
+ void (*raw_overlay_cb) (void *user_data, int num_ovl,
+ raw_overlay_t *overlays_array);
+} raw_visual_t;
+/**********************************************
+ * end of vo_raw defs
+ *********************************************/
+
/*
* this is the visual data struct any fb gui
* may supply to the xine_open_video_driver call
diff --git a/m4/audio_out.m4 b/m4/audio_out.m4
index 4288c32d5..d43aa38e1 100644
--- a/m4/audio_out.m4
+++ b/m4/audio_out.m4
@@ -192,6 +192,16 @@ AC_DEFUN([XINE_AUDIO_OUT_PLUGINS], [
if test x"$with_pulseaudio" = x"yes" && test x"$have_pulseaudio" != x"yes"; then
AC_MSG_ERROR([PulseAudio support requested, but PulseAudio not found])
fi
+ if test x"$have_pulseaudio" = xyes; then
+ AC_MSG_CHECKING([for pulseaudio >= 0.9.7])
+ PKG_CHECK_EXISTS([libpulse >= 0.9.7],
+ [have_pulseaudio_0_9_7="yes"],
+ [have_pulseaudio_0_9_7="no"])
+ AC_MSG_RESULT([$have_pulseaudio_0_9_7])
+ if test x"$have_pulseaudio_0_9_7" = xyes; then
+ AC_DEFINE([HAVE_PULSEAUDIO_0_9_7], 1, [define this if you have pulseaudio >= 0.9.7])
+ fi
+ fi
fi
AM_CONDITIONAL([ENABLE_PULSEAUDIO], [test x"$have_pulseaudio" = x"yes"])
diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c
index 9b811aaaf..9a1620e45 100644
--- a/src/audio_out/audio_pulse_out.c
+++ b/src/audio_out/audio_pulse_out.c
@@ -217,8 +217,12 @@ static void __xine_pa_sink_info_callback(pa_context *c, const pa_sink_input_info
return;
this->cvolume = info->volume;
- this->swvolume = pa_sw_volume_to_linear(pa_cvolume_avg(&info->volume));
+ this->swvolume = pa_cvolume_avg(&info->volume);
+#ifdef HAVE_PULSEAUDIO_0_9_7
this->muted = info->mute;
+#else
+ this->muted = pa_cvolume_is_muted (&this->cvolume);
+#endif
}
static int connect_context(pulse_driver_t *this) {
@@ -661,9 +665,21 @@ static int ao_pulse_set_property (ao_driver_t *this_gen, int property, int value
this->muted = value;
+#ifdef HAVE_PULSEAUDIO_0_9_7
o = pa_context_set_sink_input_mute(this->context, pa_stream_get_index(this->stream),
value, __xine_pa_context_success_callback, this);
+#else
+ /* FIXME: breaks (volume=0 after unmuting) unless the volume is
+ * adjusted first (due to swvolume not being initialised properly)
+ */
+ if ( value )
+ pa_cvolume_mute(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels);
+ else
+ pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume);
+ o = pa_context_set_sink_input_volume(this->context, pa_stream_get_index(this->stream),
+ &this->cvolume, __xine_pa_context_success_callback, this);
+#endif
result = value;
}
diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am
index 763c9c90b..ac89ea5db 100644
--- a/src/video_out/Makefile.am
+++ b/src/video_out/Makefile.am
@@ -102,6 +102,7 @@ xineplug_LTLIBRARIES = $(xshm_module) $(xv_module) $(xvmc_module) \
$(xxmc_module) \
$(xcbshm_module) \
$(xcbxv_module) \
+ xineplug_vo_out_raw.la \
xineplug_vo_out_none.la
xineplug_vo_out_xcbshm_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c video_out_xcbshm.c $(XCBOSD)
@@ -180,7 +181,7 @@ xineplug_vo_out_sdl_la_SOURCES = video_out_sdl.c
xineplug_vo_out_sdl_la_LIBADD = $(XINE_LIB) $(SDL_LIBS) $(X_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL)
xineplug_vo_out_sdl_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) $(SDL_CFLAGS)
-xineplug_vo_out_stk_la_SOURCES = video_out_stk.c
+xineplug_vo_out_stk_la_SOURCES = video_out_stk.c
xineplug_vo_out_stk_la_LIBADD = $(XINE_LIB) $(LIBSTK_LIBS) $(PTHREAD_LIBS)
xineplug_vo_out_stk_la_CFLAGS = $(AM_CFLAGS) $(LIBSTK_CFLAGS)
@@ -191,6 +192,10 @@ xineplug_vo_out_directx_la_CPPFLAGS = $(AM_CPPFLAGS) $(DIRECTX_CPPFLAGS)
xineplug_vo_out_none_la_SOURCES = video_out_none.c
xineplug_vo_out_none_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL)
+xineplug_vo_out_raw_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c video_out_raw.c
+xineplug_vo_out_raw_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL)
+xineplug_vo_out_raw_la_CFLAGS = $(VISIBILITY_FLAG)
+
xineplug_vo_out_macosx_la_SOURCES = video_out_macosx.m
xineplug_vo_out_macosx_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS)
xineplug_vo_out_macosx_la_LDFLAGS = $(AM_LDFLAGS) -framework Cocoa -framework OpenGL
diff --git a/src/video_out/video_out_raw.c b/src/video_out/video_out_raw.c
new file mode 100644
index 000000000..87d1afb4f
--- /dev/null
+++ b/src/video_out/video_out_raw.c
@@ -0,0 +1,592 @@
+/*
+ * Copyright (C) 2007 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine 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.
+ *
+ * xine 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
+ *
+ *
+ * video_out_raw.c, a video output plugin to pass raw data to frontend
+ *
+ * Written by Christophe Thommeret <hftom@free.fr>,
+ * based on others' video output plugins.
+ *
+ */
+
+/* #define LOG */
+#define LOG_MODULE "video_out_raw"
+
+/* Allow frontend some time to render frames
+* However, frontends are strongly advised to render synchronously */
+#define NUM_FRAMES_BACKLOG 4
+#define BYTES_PER_PIXEL 3
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+#include <ctype.h>
+#include <pthread.h>
+
+#include <xine.h>
+#include <xine/video_out.h>
+
+#include <xine/xine_internal.h>
+#include "yuv2rgb.h"
+#include <xine/xineutils.h>
+
+
+
+typedef struct {
+ vo_frame_t vo_frame;
+
+ int width, height, format, flags;
+ double ratio;
+ uint8_t *chunk[4]; /* mem alloc by xmalloc_aligned */
+ uint8_t *rgb, *rgb_dst;
+ yuv2rgb_t *yuv2rgb; /* yuv2rgb converter set up for this frame */
+
+} raw_frame_t;
+
+typedef struct {
+ vo_driver_t vo_driver;
+
+ void *user_data;
+
+ void (*raw_output_cb) (void *user_data, int format,
+ int frame_width, int frame_height, double frame_aspect,
+ void *data0, void *data1, void *data2);
+
+ void (*raw_overlay_cb) (void *user_data, int num_ovl,
+ raw_overlay_t *overlays_p);
+
+ int ovl_changed;
+ raw_overlay_t overlays[XINE_VORAW_MAX_OVL];
+ yuv2rgb_t *ovl_yuv2rgb;
+
+ int doYV12;
+ int doYUY2;
+ yuv2rgb_factory_t *yuv2rgb_factory;
+ /* Frame state */
+ raw_frame_t *frame[NUM_FRAMES_BACKLOG];
+ xine_t *xine;
+} raw_driver_t;
+
+
+typedef struct {
+ video_driver_class_t driver_class;
+ xine_t *xine;
+} raw_class_t;
+
+
+
+static void raw_overlay_clut_yuv2rgb(raw_driver_t *this, vo_overlay_t *overlay, raw_frame_t *frame)
+{
+ int i;
+ clut_t* clut = (clut_t*) overlay->color;
+
+ if (!overlay->rgb_clut) {
+ for ( i=0; i<sizeof(overlay->color)/sizeof(overlay->color[0]); i++ ) {
+ *((uint32_t *)&clut[i]) = this->ovl_yuv2rgb->yuv2rgb_single_pixel_fun(frame->yuv2rgb, clut[i].y, clut[i].cb, clut[i].cr);
+ }
+ overlay->rgb_clut++;
+ }
+ if (!overlay->hili_rgb_clut) {
+ clut = (clut_t*) overlay->hili_color;
+ for ( i=0; i<sizeof(overlay->color)/sizeof(overlay->color[0]); i++) {
+ *((uint32_t *)&clut[i]) = this->ovl_yuv2rgb->yuv2rgb_single_pixel_fun(frame->yuv2rgb, clut[i].y, clut[i].cb, clut[i].cr);
+ }
+ overlay->hili_rgb_clut++;
+ }
+}
+
+
+static int raw_process_ovl( raw_driver_t *this_gen, vo_overlay_t *overlay )
+{
+ raw_overlay_t *ovl = &this_gen->overlays[this_gen->ovl_changed-1];
+
+ if ( overlay->width<=0 || overlay->height<=0 )
+ return 0;
+
+ if ( (overlay->width*overlay->height)!=(ovl->ovl_w*ovl->ovl_h) )
+ ovl->ovl_rgba = (uint8_t*)realloc( ovl->ovl_rgba, overlay->width*overlay->height*4 );
+ ovl->ovl_w = overlay->width;
+ ovl->ovl_h = overlay->height;
+ ovl->ovl_x = overlay->x;
+ ovl->ovl_y = overlay->y;
+
+ int num_rle = overlay->num_rle;
+ rle_elem_t *rle = overlay->rle;
+ uint8_t *rgba = ovl->ovl_rgba;
+ clut_t *low_colors = (clut_t*)overlay->color;
+ clut_t *hili_colors = (clut_t*)overlay->hili_color;
+ uint8_t *low_trans = overlay->trans;
+ uint8_t *hili_trans = overlay->hili_trans;
+ clut_t *colors;
+ uint8_t *trans;
+ uint8_t alpha;
+ int rlelen = 0;
+ uint8_t clr = 0;
+ int i, pos=0, x, y;
+
+ while ( num_rle>0 ) {
+ x = pos%ovl->ovl_w;
+ y = pos/ovl->ovl_w;
+ if ( (x>=overlay->hili_left && x<=overlay->hili_right) && (y>=overlay->hili_top && y<=overlay->hili_bottom) ) {
+ colors = hili_colors;
+ trans = hili_trans;
+ }
+ else {
+ colors = low_colors;
+ trans = low_trans;
+ }
+ rlelen = rle->len;
+ clr = rle->color;
+ alpha = trans[clr];
+ for ( i=0; i<rlelen; ++i ) {
+ rgba[0] = colors[clr].y;
+ rgba[1] = colors[clr].cr;
+ rgba[2] = colors[clr].cb;
+ rgba[3] = alpha*255/15;
+ rgba+= 4;
+ ++pos;
+ }
+ ++rle;
+ --num_rle;
+ }
+ return 1;
+}
+
+
+static void raw_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed)
+{
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+
+ if ( !changed )
+ return;
+
+ ++this->ovl_changed;
+}
+
+
+static void raw_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay)
+{
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+ raw_frame_t *frame = (raw_frame_t *) frame_gen;
+
+ if ( !this->ovl_changed || this->ovl_changed>XINE_VORAW_MAX_OVL )
+ return;
+
+ if (overlay->rle) {
+ if (!overlay->rgb_clut || !overlay->hili_rgb_clut)
+ raw_overlay_clut_yuv2rgb (this, overlay, frame);
+ if ( raw_process_ovl( this, overlay ) )
+ ++this->ovl_changed;
+ }
+}
+
+
+static void raw_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img)
+{
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+ int i;
+
+ if ( !this->ovl_changed )
+ return;
+
+ this->raw_overlay_cb( this->user_data, this->ovl_changed-1, &this->overlays );
+
+ this->ovl_changed = 0;
+}
+
+
+static void raw_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src)
+{
+ raw_frame_t *frame = (raw_frame_t *) vo_img ;
+
+ vo_img->proc_called = 1;
+ if (! frame->rgb_dst)
+ return;
+
+ if( frame->vo_frame.crop_left || frame->vo_frame.crop_top ||
+ frame->vo_frame.crop_right || frame->vo_frame.crop_bottom )
+ {
+ /* TODO: ?!? */
+ return;
+ }
+
+ if (frame->format == XINE_IMGFMT_YV12)
+ frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->rgb_dst, src[0], src[1], src[2]);
+ else
+ frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->rgb_dst, src[0]);
+}
+
+
+
+static void raw_frame_field (vo_frame_t *vo_img, int which_field)
+{
+ raw_frame_t *frame = (raw_frame_t *) vo_img ;
+ raw_driver_t *this = (raw_driver_t *) vo_img->driver;
+
+ if ( frame->format==XINE_IMGFMT_YV12 && this->doYV12 ) {
+ frame->rgb_dst = 0;
+ return;
+ }
+ else if ( frame->format==XINE_IMGFMT_YUY2 && this->doYUY2 ) {
+ frame->rgb_dst = 0;
+ return;
+ }
+
+ switch (which_field) {
+ case VO_TOP_FIELD:
+ frame->rgb_dst = (uint8_t *)frame->rgb;
+ break;
+ case VO_BOTTOM_FIELD:
+ frame->rgb_dst = (uint8_t *)frame->rgb + frame->width * BYTES_PER_PIXEL;
+ break;
+ case VO_BOTH_FIELDS:
+ frame->rgb_dst = (uint8_t *)frame->rgb;
+ break;
+ }
+
+ frame->yuv2rgb->next_slice (frame->yuv2rgb, NULL);
+}
+
+
+
+static void raw_frame_dispose (vo_frame_t *vo_img)
+{
+ raw_frame_t *frame = (raw_frame_t *) vo_img ;
+
+ frame->yuv2rgb->dispose (frame->yuv2rgb);
+
+ free (frame->chunk[0]);
+ free (frame->chunk[1]);
+ free (frame->chunk[2]);
+ free (frame->chunk[3]);
+ free (frame);
+}
+
+
+
+static vo_frame_t *raw_alloc_frame (vo_driver_t *this_gen)
+{
+ raw_frame_t *frame;
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+
+ frame = (raw_frame_t *) xine_xmalloc (sizeof (raw_frame_t));
+
+ if (!frame)
+ return NULL;
+
+ pthread_mutex_init (&frame->vo_frame.mutex, NULL);
+
+ /*
+ * supply required functions/fields
+ */
+ frame->vo_frame.proc_slice = raw_frame_proc_slice;
+ frame->vo_frame.proc_frame = NULL;
+ frame->vo_frame.field = raw_frame_field;
+ frame->vo_frame.dispose = raw_frame_dispose;
+ frame->vo_frame.driver = this_gen;
+
+ /*
+ * colorspace converter for this frame
+ */
+ frame->yuv2rgb = this->yuv2rgb_factory->create_converter (this->yuv2rgb_factory);
+
+ return (vo_frame_t *) frame;
+}
+
+
+
+static void raw_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen,
+ uint32_t width, uint32_t height, double ratio, int format, int flags)
+{
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+ raw_frame_t *frame = (raw_frame_t *) frame_gen;
+
+ /* Check frame size and format and reallocate if necessary */
+ if ((frame->width != width)
+ || (frame->height != height)
+ || (frame->format != format)
+ || (frame->flags != flags)) {
+/* lprintf ("updating frame to %d x %d (ratio=%g, format=%08x)\n", width, height, ratio, format); */
+
+ flags &= VO_BOTH_FIELDS;
+
+ /* (re-) allocate render space */
+ free (frame->chunk[0]);
+ free (frame->chunk[1]);
+ free (frame->chunk[2]);
+ free (frame->chunk[3]);
+
+ if (format == XINE_IMGFMT_YV12) {
+ frame->vo_frame.pitches[0] = 8*((width + 7) / 8);
+ frame->vo_frame.pitches[1] = 8*((width + 15) / 16);
+ frame->vo_frame.pitches[2] = 8*((width + 15) / 16);
+ frame->vo_frame.base[0] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[0] * height, (void **) &frame->chunk[0]);
+ frame->vo_frame.base[1] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[1] * ((height+1)/2), (void **) &frame->chunk[1]);
+ frame->vo_frame.base[2] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[2] * ((height+1)/2), (void **) &frame->chunk[2]);
+ } else {
+ frame->vo_frame.pitches[0] = 8*((width + 3) / 4);
+ frame->vo_frame.base[0] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[0] * height, (void **) &frame->chunk[0]);
+ frame->chunk[1] = NULL;
+ frame->chunk[2] = NULL;
+ }
+ frame->rgb = xine_xmalloc_aligned (16, BYTES_PER_PIXEL*width*height,
+ (void **) &frame->chunk[3]);
+
+ /* set up colorspace converter */
+ switch (flags) {
+ case VO_TOP_FIELD:
+ case VO_BOTTOM_FIELD:
+ frame->yuv2rgb->configure (frame->yuv2rgb,
+ width,
+ height,
+ 2*frame->vo_frame.pitches[0],
+ 2*frame->vo_frame.pitches[1],
+ width,
+ height,
+ BYTES_PER_PIXEL*width * 2);
+ break;
+ case VO_BOTH_FIELDS:
+ frame->yuv2rgb->configure (frame->yuv2rgb,
+ width,
+ height,
+ frame->vo_frame.pitches[0],
+ frame->vo_frame.pitches[1],
+ width,
+ height,
+ BYTES_PER_PIXEL*width);
+ break;
+ }
+
+ frame->width = width;
+ frame->height = height;
+ frame->format = format;
+
+ raw_frame_field ((vo_frame_t *)frame, flags);
+ }
+
+ frame->ratio = ratio;
+}
+
+
+
+static int raw_redraw_needed (vo_driver_t *this_gen)
+{
+ return 0;
+}
+
+
+
+static void raw_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
+{
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+ raw_frame_t *frame = (raw_frame_t *) frame_gen;
+ int i;
+
+ if (this->frame[NUM_FRAMES_BACKLOG-1]) {
+ this->frame[NUM_FRAMES_BACKLOG-1]->vo_frame.free (&this->frame[NUM_FRAMES_BACKLOG-1]->vo_frame);
+ }
+ for (i = NUM_FRAMES_BACKLOG-1; i > 0; i--)
+ this->frame[i] = this->frame[i-1];
+ this->frame[0] = frame;
+
+ if ( frame->rgb_dst ) {
+ this->raw_output_cb( this->user_data, XINE_VORAW_RGB, frame->width, frame->height, frame->ratio, frame->rgb, 0, 0 );
+ }
+ else if ( frame->format==XINE_IMGFMT_YV12 ) {
+ this->raw_output_cb( this->user_data, XINE_VORAW_YV12, frame->width, frame->height, frame->ratio, frame->vo_frame.base[0],
+ frame->vo_frame.base[1], frame->vo_frame.base[2] );
+ }
+ else {
+ this->raw_output_cb( this->user_data, XINE_VORAW_YUY2, frame->width, frame->height, frame->ratio, frame->vo_frame.base[0], 0, 0 );
+ }
+}
+
+
+
+static int raw_get_property (vo_driver_t *this_gen, int property)
+{
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+
+ switch (property) {
+ case VO_PROP_ASPECT_RATIO:
+ return XINE_VO_ASPECT_AUTO;
+ case VO_PROP_MAX_NUM_FRAMES:
+ return 15;
+ case VO_PROP_BRIGHTNESS:
+ return 0;
+ case VO_PROP_CONTRAST:
+ return 128;
+ case VO_PROP_SATURATION:
+ return 128;
+ case VO_PROP_WINDOW_WIDTH:
+ return 0;
+ case VO_PROP_WINDOW_HEIGHT:
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+
+
+static int raw_set_property (vo_driver_t *this_gen, int property, int value)
+{
+ return value;
+}
+
+
+
+static void raw_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max)
+{
+ *min = 0;
+ *max = 0;
+}
+
+
+
+static int raw_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data)
+{
+ return 0;
+}
+
+
+
+static uint32_t raw_get_capabilities (vo_driver_t *this_gen)
+{
+ uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2;
+ return capabilities;
+}
+
+
+
+static void raw_dispose (vo_driver_t *this_gen)
+{
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+ int i;
+
+ for (i = 0; i < NUM_FRAMES_BACKLOG; i++)
+ if (this->frame[i])
+ this->frame[i]->vo_frame.dispose (&this->frame[i]->vo_frame);
+
+ this->yuv2rgb_factory->dispose (this->yuv2rgb_factory);
+
+ for ( i=0; i<XINE_VORAW_MAX_OVL; ++i )
+ free( this->overlays[i].ovl_rgba );
+
+ free (this);
+}
+
+
+
+static vo_driver_t *raw_open_plugin (video_driver_class_t *class_gen, const void *visual_gen)
+{
+ raw_class_t *class = (raw_class_t *) class_gen;
+ raw_visual_t *visual = (raw_visual_t *) visual_gen;
+ raw_driver_t *this;
+ int i;
+
+ this = (raw_driver_t *) xine_xmalloc (sizeof (raw_driver_t));
+
+ if (!this)
+ return NULL;
+
+ this->raw_output_cb = visual->raw_output_cb;
+ this->user_data = visual->user_data;
+ this->xine = class->xine;
+ this->raw_overlay_cb = visual->raw_overlay_cb;
+ this->doYV12 = visual->supported_formats&XINE_VORAW_YV12;
+ this->doYUY2 = visual->supported_formats&XINE_VORAW_YUY2;
+
+ this->vo_driver.get_capabilities = raw_get_capabilities;
+ this->vo_driver.alloc_frame = raw_alloc_frame;
+ this->vo_driver.update_frame_format = raw_update_frame_format;
+ this->vo_driver.overlay_begin = raw_overlay_begin;
+ this->vo_driver.overlay_blend = raw_overlay_blend;
+ this->vo_driver.overlay_end = raw_overlay_end;
+ this->vo_driver.display_frame = raw_display_frame;
+ this->vo_driver.get_property = raw_get_property;
+ this->vo_driver.set_property = raw_set_property;
+ this->vo_driver.get_property_min_max = raw_get_property_min_max;
+ this->vo_driver.gui_data_exchange = raw_gui_data_exchange;
+ this->vo_driver.dispose = raw_dispose;
+ this->vo_driver.redraw_needed = raw_redraw_needed;
+
+ this->yuv2rgb_factory = yuv2rgb_factory_init (MODE_24_BGR, 1, NULL); /* converts to rgb */
+
+ for (i = 0; i < NUM_FRAMES_BACKLOG; i++)
+ this->frame[i] = 0;
+
+ for ( i=0; i<XINE_VORAW_MAX_OVL; ++i ) {
+ this->overlays[i].ovl_w = this->overlays[i].ovl_h = 2;
+ this->overlays[i].ovl_rgba = (uint8_t*)malloc(2*2*4);
+ this->overlays[i].ovl_x = this->overlays[i].ovl_y = 0;
+ }
+ this->ovl_changed = 0;
+
+ /* we have to use a second converter for overlays
+ * because "MODE_24_BGR, 1 (swap)" breaks overlays conversion */
+ yuv2rgb_factory_t *factory = yuv2rgb_factory_init (MODE_24_BGR, 0, NULL);
+ this->ovl_yuv2rgb = factory->create_converter( factory );
+ factory->dispose( factory );
+
+ return &this->vo_driver;
+}
+
+/*
+ * class functions
+ */
+
+static void *raw_init_class (xine_t *xine, void *visual_gen)
+{
+ raw_class_t *this = (raw_class_t *) xine_xmalloc (sizeof (raw_class_t));
+
+ this->driver_class.open_plugin = raw_open_plugin;
+ this->driver_class.identifier = "raw";
+ this->driver_class.description = _("xine video output plugin passing raw data to supplied callback");
+ this->driver_class.dispose = default_video_driver_class_dispose;
+ this->xine = xine;
+
+ return this;
+}
+
+
+
+static const vo_info_t vo_info_raw = {
+ 7, /* priority */
+ XINE_VISUAL_TYPE_RAW /* visual type */
+};
+
+
+/*
+ * exported plugin catalog entry
+ */
+
+const plugin_info_t xine_plugin_info[] EXPORTED = {
+ /* type, API, "name", version, special_info, init_function */
+ { PLUGIN_VIDEO_OUT, 22, "raw", XINE_VERSION_CODE, &vo_info_raw, raw_init_class },
+ { PLUGIN_NONE, 0, "", 0, NULL, NULL }
+};
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index 710e6dfbf..77025d03f 100644
--- a/src/xine-engine/load_plugins.c
+++ b/src/xine-engine/load_plugins.c
@@ -1802,6 +1802,36 @@ const char *const *xine_list_video_output_plugins (xine_t *xine) {
return catalog->ids;
}
+const char *const *xine_list_video_output_plugins_typed(xine_t *xine, uint64_t typemask)
+{
+ plugin_catalog_t *catalog = xine->plugin_catalog;
+ plugin_node_t *node;
+ int list_id, list_size, i;
+
+ pthread_mutex_lock (&catalog->lock);
+
+ list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1]);
+
+ for (list_id = i = 0; list_id < list_size; list_id++)
+ {
+ node = xine_sarray_get (catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1], list_id);
+ if (typemask & (1ULL << ((vo_info_t *)node->info->special_info)->visual_type))
+ {
+ const char *id = node->info->id;
+ int j = i;
+ while (--j >= 0)
+ if (!strcmp (catalog->ids[j], id))
+ goto ignore; /* already listed */
+ catalog->ids[i++] = id;
+ }
+ ignore: ;
+ }
+ catalog->ids[i] = NULL;
+
+ pthread_mutex_unlock (&catalog->lock);
+ return catalog->ids;
+}
+
static ao_driver_t *_load_audio_driver (xine_t *this, plugin_node_t *node,
void *data) {