summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2002-10-14 15:46:48 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2002-10-14 15:46:48 +0000
commitbcaee71a3a763a545e1f8457aca26dc679462677 (patch)
tree191c500351cb4073c6d998e6112a6b68f19790f4 /src
parentde10300bdc6457c36598f4287d42c4a5b2e82d71 (diff)
downloadxine-lib-bcaee71a3a763a545e1f8457aca26dc679462677.tar.gz
xine-lib-bcaee71a3a763a545e1f8457aca26dc679462677.tar.bz2
introduction of xine_stream_t and async xine events - all still in developement
CVS patchset: 2828 CVS date: 2002/10/14 15:46:48
Diffstat (limited to 'src')
-rw-r--r--src/demuxers/Makefile.am166
-rw-r--r--src/demuxers/demux.h114
-rw-r--r--src/demuxers/demux_avi.c292
-rw-r--r--src/input/Makefile.am104
-rw-r--r--src/input/input_dvd.c11
-rw-r--r--src/input/input_file.c641
-rw-r--r--src/input/input_plugin.h320
-rw-r--r--src/input/net_buf_ctrl.c8
-rw-r--r--src/libspudec/spu_decoder_api.h1
-rw-r--r--src/xine-engine/Makefile.am2
-rw-r--r--src/xine-engine/audio_decoder.c232
-rw-r--r--src/xine-engine/audio_decoder.h80
-rw-r--r--src/xine-engine/audio_out.c28
-rw-r--r--src/xine-engine/audio_out.h27
-rw-r--r--src/xine-engine/demux.c70
-rw-r--r--src/xine-engine/events.c239
-rw-r--r--src/xine-engine/events.h177
-rw-r--r--src/xine-engine/load_plugins.c486
-rw-r--r--src/xine-engine/metronom.c8
-rw-r--r--src/xine-engine/metronom.h15
-rw-r--r--src/xine-engine/plugin_catalog.h32
-rw-r--r--src/xine-engine/video_decoder.c244
-rw-r--r--src/xine-engine/video_decoder.h86
-rw-r--r--src/xine-engine/video_out.c27
-rw-r--r--src/xine-engine/video_out.h7
-rw-r--r--src/xine-engine/video_overlay.h7
-rw-r--r--src/xine-engine/xine.c991
-rw-r--r--src/xine-engine/xine_interface.c59
-rw-r--r--src/xine-engine/xine_internal.h270
-rw-r--r--src/xine-engine/xine_plugin.h7
30 files changed, 2344 insertions, 2407 deletions
diff --git a/src/demuxers/Makefile.am b/src/demuxers/Makefile.am
index b2e972e4c..18e90d74c 100644
--- a/src/demuxers/Makefile.am
+++ b/src/demuxers/Makefile.am
@@ -6,59 +6,61 @@ libdir = $(XINE_PLUGINDIR)
# Sensing of OGG/VORBIS, ZLIB and ASF is broken in cvscompile.sh.
-if HAVE_VORBIS
-ogg_module = xineplug_dmx_ogg.la
-endif
+#if HAVE_VORBIS
+#ogg_module = xineplug_dmx_ogg.la
+#endif
-if HAVE_ZLIB
-qt_modules = xineplug_dmx_qt.la
-endif
+#if HAVE_ZLIB
+#qt_modules = xineplug_dmx_qt.la
+#endif
-if BUILD_ASF
-asf_module = xineplug_dmx_asf.la
-endif
+#if BUILD_ASF
+#asf_module = xineplug_dmx_asf.la
+#endif
##
# IMPORTANT:
# ---------
# All of xine demuxer plugins should be named like the scheme "xineplug_dmx_"
-lib_LTLIBRARIES = $(ogg_module) $(asf_module) $(qt_modules) xineplug_dmx_avi.la\
- xineplug_dmx_mpeg_block.la xineplug_dmx_mpeg.la \
- xineplug_dmx_mpeg_elem.la xineplug_dmx_mpeg_audio.la \
- xineplug_dmx_cda.la xineplug_dmx_film.la \
- xineplug_dmx_roq.la xineplug_dmx_fli.la \
- xineplug_dmx_smjpeg.la xineplug_dmx_wav.la \
- xineplug_dmx_idcin.la xineplug_dmx_wc3movie.la \
- xineplug_dmx_vqa.la xineplug_dmx_voc.la \
- xineplug_dmx_aiff.la xineplug_dmx_snd.la \
- xineplug_dmx_yuv4mpeg2.la xineplug_dmx_real.la
+#lib_LTLIBRARIES = $(ogg_module) $(asf_module) $(qt_modules) xineplug_dmx_avi.la\
+# xineplug_dmx_mpeg_block.la xineplug_dmx_mpeg.la \
+# xineplug_dmx_mpeg_elem.la xineplug_dmx_mpeg_audio.la \
+# xineplug_dmx_cda.la xineplug_dmx_film.la \
+# xineplug_dmx_roq.la xineplug_dmx_fli.la \
+# xineplug_dmx_smjpeg.la xineplug_dmx_wav.la \
+# xineplug_dmx_idcin.la xineplug_dmx_wc3movie.la \
+# xineplug_dmx_vqa.la xineplug_dmx_voc.la \
+# xineplug_dmx_aiff.la xineplug_dmx_snd.la \
+# xineplug_dmx_yuv4mpeg2.la xineplug_dmx_real.la
# xineplug_dmx_mpeg_pes.la xineplug_dmx_mpeg_ts.la
-xineplug_dmx_ogg_la_SOURCES = demux_ogg.c
-xineplug_dmx_ogg_la_LIBADD = $(OGG_LIBS) $(VORBIS_LIBS)\
- $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_ogg_la_LDFLAGS = -avoid-version -module
+lib_LTLIBRARIES = xineplug_dmx_avi.la
+
+#xineplug_dmx_ogg_la_SOURCES = demux_ogg.c
+#xineplug_dmx_ogg_la_LIBADD = $(OGG_LIBS) $(VORBIS_LIBS)\
+# $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_ogg_la_LDFLAGS = -avoid-version -module
xineplug_dmx_avi_la_SOURCES = demux_avi.c
xineplug_dmx_avi_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
xineplug_dmx_avi_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_mpeg_block_la_SOURCES = demux_mpeg_block.c
-xineplug_dmx_mpeg_block_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_mpeg_block_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_mpeg_block_la_SOURCES = demux_mpeg_block.c
+#xineplug_dmx_mpeg_block_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_mpeg_block_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_mpeg_la_SOURCES = demux_mpeg.c
-xineplug_dmx_mpeg_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_mpeg_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_mpeg_la_SOURCES = demux_mpeg.c
+#xineplug_dmx_mpeg_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_mpeg_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_mpeg_audio_la_SOURCES = demux_mpgaudio.c
-xineplug_dmx_mpeg_audio_la_LIBADD = -lm $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_mpeg_audio_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_mpeg_audio_la_SOURCES = demux_mpgaudio.c
+#xineplug_dmx_mpeg_audio_la_LIBADD = -lm $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_mpeg_audio_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_mpeg_elem_la_SOURCES = demux_elem.c
-xineplug_dmx_mpeg_elem_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_mpeg_elem_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_mpeg_elem_la_SOURCES = demux_elem.c
+#xineplug_dmx_mpeg_elem_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_mpeg_elem_la_LDFLAGS = -avoid-version -module
#xineplug_dmx_mpeg_pes_la_SOURCES = demux_pes.c
#xineplug_dmx_mpeg_pes_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
@@ -68,68 +70,68 @@ xineplug_dmx_mpeg_elem_la_LDFLAGS = -avoid-version -module
#xineplug_dmx_mpeg_ts_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
#xineplug_dmx_mpeg_ts_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_qt_la_SOURCES = demux_qt.c qtpalette.h
-xineplug_dmx_qt_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_qt_la_SOURCES = demux_qt.c qtpalette.h
+#xineplug_dmx_qt_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_asf_la_SOURCES = demux_asf.c
-xineplug_dmx_asf_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_asf_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_asf_la_SOURCES = demux_asf.c
+#xineplug_dmx_asf_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_asf_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_cda_la_SOURCES = demux_cda.c
-xineplug_dmx_cda_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_cda_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_cda_la_SOURCES = demux_cda.c
+#xineplug_dmx_cda_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_cda_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_film_la_SOURCES = demux_film.c
-xineplug_dmx_film_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_film_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_film_la_SOURCES = demux_film.c
+#xineplug_dmx_film_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_film_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_roq_la_SOURCES = demux_roq.c
-xineplug_dmx_roq_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_roq_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_roq_la_SOURCES = demux_roq.c
+#xineplug_dmx_roq_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_roq_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_fli_la_SOURCES = demux_fli.c
-xineplug_dmx_fli_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_fli_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_fli_la_SOURCES = demux_fli.c
+#xineplug_dmx_fli_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_fli_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_smjpeg_la_SOURCES = demux_smjpeg.c
-xineplug_dmx_smjpeg_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_smjpeg_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_smjpeg_la_SOURCES = demux_smjpeg.c
+#xineplug_dmx_smjpeg_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_smjpeg_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_wav_la_SOURCES = demux_wav.c
-xineplug_dmx_wav_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_wav_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_wav_la_SOURCES = demux_wav.c
+#xineplug_dmx_wav_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_wav_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_idcin_la_SOURCES = demux_idcin.c
-xineplug_dmx_idcin_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_idcin_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_idcin_la_SOURCES = demux_idcin.c
+#xineplug_dmx_idcin_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_idcin_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_wc3movie_la_SOURCES = demux_wc3movie.c
-xineplug_dmx_wc3movie_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_wc3movie_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_wc3movie_la_SOURCES = demux_wc3movie.c
+#xineplug_dmx_wc3movie_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_wc3movie_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_vqa_la_SOURCES = demux_vqa.c
-xineplug_dmx_vqa_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_vqa_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_vqa_la_SOURCES = demux_vqa.c
+#xineplug_dmx_vqa_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_vqa_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_voc_la_SOURCES = demux_voc.c
-xineplug_dmx_voc_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_voc_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_voc_la_SOURCES = demux_voc.c
+#xineplug_dmx_voc_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_voc_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_aiff_la_SOURCES = demux_aiff.c
-xineplug_dmx_aiff_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_aiff_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_aiff_la_SOURCES = demux_aiff.c
+#xineplug_dmx_aiff_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_aiff_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_snd_la_SOURCES = demux_snd.c
-xineplug_dmx_snd_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_snd_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_snd_la_SOURCES = demux_snd.c
+#xineplug_dmx_snd_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_snd_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_yuv4mpeg2_la_SOURCES = demux_yuv4mpeg2.c
-xineplug_dmx_yuv4mpeg2_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_yuv4mpeg2_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_yuv4mpeg2_la_SOURCES = demux_yuv4mpeg2.c
+#xineplug_dmx_yuv4mpeg2_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_yuv4mpeg2_la_LDFLAGS = -avoid-version -module
-xineplug_dmx_real_la_SOURCES = demux_real.c
-xineplug_dmx_real_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_dmx_real_la_LDFLAGS = -avoid-version -module
+#xineplug_dmx_real_la_SOURCES = demux_real.c
+#xineplug_dmx_real_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_dmx_real_la_LDFLAGS = -avoid-version -module
include_HEADERS = demux.h qtpalette.h
diff --git a/src/demuxers/demux.h b/src/demuxers/demux.h
index 41e23d211..7234a64fd 100644
--- a/src/demuxers/demux.h
+++ b/src/demuxers/demux.h
@@ -17,16 +17,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: demux.h,v 1.19 2002/09/18 00:51:33 guenter Exp $
+ * $Id: demux.h,v 1.20 2002/10/14 15:47:12 guenter Exp $
*/
#ifndef HAVE_DEMUX_H
#define HAVE_DEMUX_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include "buffer.h"
#include "xine_internal.h"
#if defined(XINE_COMPILE)
@@ -35,43 +31,68 @@ extern "C" {
#include "input_plugin.h"
#endif
-#define DEMUXER_PLUGIN_IFACE_VERSION 11
+#define DEMUXER_PLUGIN_IFACE_VERSION 14
+
+#define DEMUX_OK 0
+#define DEMUX_FINISHED 1
+
+#define DEMUX_CANNOT_HANDLE 0
+#define DEMUX_CAN_HANDLE 1
+
+#define METHOD_BY_CONTENT 1
+#define METHOD_BY_EXTENSION 2
+
+typedef struct demux_class_s demux_class_t ;
-#define DEMUX_OK 0
-#define DEMUX_FINISHED 1
+struct demux_class_s {
-#define DEMUX_CANNOT_HANDLE 0
-#define DEMUX_CAN_HANDLE 1
+ /*
+ * return human readable (verbose = 1 line) description for this plugin
+ */
+ char* (*get_description) (demux_class_t *this);
-#define DEMUX_DEFAULT_STRATEGY 0
-#define DEMUX_REVERT_STRATEGY 1
-#define DEMUX_CONTENT_STRATEGY 2
-#define DEMUX_EXTENSION_STRATEGY 3
+ /*
+ * return human readable identifier for this plugin
+ */
+
+ char* (*get_identifier) (demux_class_t *this);
+
+ /*
+ * return MIME types supported for this plugin
+ */
+
+ char* (*get_mimetypes) (demux_class_t *this);
+
+ /*
+ * return ' ' seperated list of file extensions this
+ * demuxer is likely to handle
+ * (will be used to filter media files in
+ * file selection dialogs)
+ */
+
+ char* (*get_extensions) (demux_class_t *this);
+
+ /*
+ * close down, free all resources
+ */
+ void (*dispose) (demux_class_t *this);
+};
-#define STAGE_BY_CONTENT 1
-#define STAGE_BY_EXTENSION 2
/*
- * a demux plugin must implement these functions
+ * any demux plugin must implement these functions
*/
typedef struct demux_plugin_s demux_plugin_t;
-struct demux_plugin_s
-{
+struct demux_plugin_s {
+
/*
- * ask demuxer to open the given stream (input-plugin)
- * using the content-detection method specified in <stage>
- *
- * demuxer should send header/preview packages in this stage
- *
- * return values:
- * DEMUX_CAN_HANDLE on success
- * DEMUX_CANNOT_HANDLE on failure
+ * send headers, followed by BUF_CONTROL_HEADERS_DONE down the
+ * fifos, then return. do not start demux thread (yet)
*/
- int (*open) (demux_plugin_t *this, input_plugin_t *ip,
- int stage);
+ void (*send_headers) (demux_plugin_t *this);
/*
* start demux thread
@@ -106,17 +127,18 @@ struct demux_plugin_s
*/
int (*seek) (demux_plugin_t *this,
- off_t start_pos, int start_time);
+ off_t start_pos, int start_time);
/*
- * stop & kill demux thread, free resources associated with current
- * input stream
+ * stop & kill demux thread
+ *
+ * keep plugin ready for restart
*/
void (*stop) (demux_plugin_t *this) ;
/*
- * close demuxer, free all resources
+ * stop & kill demux thread, free resources
*/
void (*dispose) (demux_plugin_t *this) ;
@@ -128,32 +150,18 @@ struct demux_plugin_s
int (*get_status) (demux_plugin_t *this) ;
/*
- * return human readable identifier for this plugin
+ * estimate stream length in seconds
+ * may return 0 for non-seekable streams
*/
- char* (*get_identifier) (void);
-
- /*
- * return MIME types supported for this plugin
- */
+ int (*get_stream_length) (demux_plugin_t *this);
+
- char* (*get_mimetypes) (void);
/*
- * estimate stream length in seconds
- * may return 0 for non-seekable streams
+ * "backwards" link to plugin class
*/
- int (*get_stream_length) (demux_plugin_t *this);
+ demux_class_t *demux_class;
} ;
-/*
- * demuxer plugins should provide this (and only this!) function call:
- *
- * demux_plugin_t *init_demux_plugin (int iface_version, xine_t *xine);
- */
-
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c
index b4ccec6ae..a277ebb2f 100644
--- a/src/demuxers/demux_avi.c
+++ b/src/demuxers/demux_avi.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: demux_avi.c,v 1.113 2002/10/12 17:14:41 jkeil Exp $
+ * $Id: demux_avi.c,v 1.114 2002/10/14 15:47:13 guenter Exp $
*
* demultiplexer for avi streams
*
@@ -71,8 +71,6 @@
#define MAX_AUDIO_STREAMS 8
-#define VALID_ENDS "avi"
-
/* The following variable indicates the kind of error */
typedef struct
@@ -168,9 +166,7 @@ typedef struct
typedef struct demux_avi_s {
demux_plugin_t demux_plugin;
- xine_t *xine;
-
- config_values_t *config;
+ xine_stream_t *stream;
fifo_buffer_t *audio_fifo;
fifo_buffer_t *video_fifo;
@@ -198,6 +194,16 @@ typedef struct demux_avi_s {
idx_grow_t idx_grow;
} demux_avi_t ;
+typedef struct {
+
+ demux_class_t demux_class;
+
+ /* class-wide, global variables here */
+
+ xine_t *xine;
+ config_values_t *config;
+} demux_avi_class_t;
+
#define AVI_ERR_SIZELIM 1 /* The write of the data would exceed
the maximum size of the AVI file.
This is more a warning than an error
@@ -393,16 +399,16 @@ static void demux_avi_stop (demux_plugin_t *this_gen);
* notify the user. Returns -1 if EOF was reached, the non-negative
* return value of stopper otherwise. */
static long idx_grow(demux_avi_t *this, long (*stopper)(demux_avi_t *, void *),
- void *stopdata)
-{
+ void *stopdata) {
+
unsigned long n;
- long i;
- long retval = -1;
- long num_read = 0;
- off_t ioff = 8;
- char data[256];
- int did_osd = 0;
- off_t savepos = this->input->seek(this->input, 0, SEEK_CUR);
+ long i;
+ long retval = -1;
+ long num_read = 0;
+ off_t ioff = 8;
+ char data[256];
+ off_t savepos = this->input->seek(this->input, 0, SEEK_CUR);
+
this->input->seek(this->input, this->idx_grow.nexttagoffset, SEEK_SET);
while ((retval = stopper(this, stopdata)) < 0) {
@@ -410,22 +416,24 @@ static long idx_grow(demux_avi_t *this, long (*stopper)(demux_avi_t *, void *),
num_read += 1;
if (num_read % 1000 == 0) {
- /* Update the user using the OSD */
- off_t file_len = this->input->get_length (this->input);
- char str[60];
-
- sprintf(str, "Building index (%3lld%%)",
- 100 * this->idx_grow.nexttagoffset / file_len);
-
- this->xine->osd_renderer->filled_rect (this->xine->osd,
- 0, 0, 299, 99, 0);
- this->xine->osd_renderer->render_text (this->xine->osd,
- 5, 30, str, OSD_TEXT1);
- this->xine->osd_renderer->show (this->xine->osd, 0);
- did_osd = 1;
+ /* send event to frontend about index generation progress */
+
+ xine_event_t event;
+ xine_idx_progress_data_t idx;
+ off_t file_len;
+
+ file_len = this->input->get_length (this->input);
+
+ idx.percent = 100 * this->idx_grow.nexttagoffset / file_len;
+
+ event.type = XINE_EVENT_BUILDING_INDEX;
+ event.data = &idx;
+ event.data_length = sizeof (xine_idx_progress_data_t);
+
+ xine_event_send (this->stream, &event);
}
- if( this->input->read(this->input, data,8) != 8 )
+ if (this->input->read(this->input, data,8) != 8)
break;
n = str2ulong(data+4);
@@ -466,12 +474,7 @@ static long idx_grow(demux_avi_t *this, long (*stopper)(demux_avi_t *, void *),
}
- /* Clear the OSD */
- if (did_osd) {
- this->xine->osd_renderer->hide (this->xine->osd, 0);
- }
-
- this->input->seek(this->input, savepos, SEEK_SET);
+ this->input->seek (this->input, savepos, SEEK_SET);
if (retval < 0) retval = -1;
return retval;
@@ -649,7 +652,8 @@ static avi_t *AVI_init(demux_avi_t *this) {
ERR_EXIT(AVI_ERR_NO_MEM);
if (this->input->read(this->input, (char *)AVI->idx, n) != n ) {
- xine_log (this->xine, XINE_LOG_MSG, _("demux_avi: avi index is broken\n"));
+ xine_log (this->stream->xine, XINE_LOG_MSG,
+ _("demux_avi: avi index is broken\n"));
free (AVI->idx); /* Index is broken, reconstruct */
AVI->idx = NULL;
AVI->n_idx = AVI->max_idx = 0;
@@ -1162,13 +1166,13 @@ static void *demux_avi_loop (void *this_gen) {
} while( this->status == DEMUX_OK );
if (this->send_end_buffers) {
- xine_demux_control_end(this->xine, BUF_FLAG_END_STREAM);
+ xine_demux_control_end (this->stream, BUF_FLAG_END_STREAM);
}
printf ("demux_avi: demux loop finished.\n");
this->thread_running = 0;
- pthread_mutex_unlock( &this->mutex );
+ pthread_mutex_unlock (&this->mutex);
pthread_exit(NULL);
@@ -1180,27 +1184,27 @@ static void demux_avi_stop (demux_plugin_t *this_gen) {
demux_avi_t *this = (demux_avi_t *) this_gen;
void *p;
- pthread_mutex_lock( &this->mutex );
+ pthread_mutex_lock (&this->mutex);
if (!this->thread_running) {
printf ("demux_avi: stop...ignored\n");
- pthread_mutex_unlock( &this->mutex );
+ pthread_mutex_unlock (&this->mutex);
return;
}
this->send_end_buffers = 0;
this->status = DEMUX_FINISHED;
- pthread_mutex_unlock( &this->mutex );
+ pthread_mutex_unlock (&this->mutex);
pthread_join (this->thread, &p);
- xine_demux_flush_engine(this->xine);
+ xine_demux_flush_engine (this->stream);
/*
AVI_close (this->avi);
this->avi = NULL;
*/
- xine_demux_control_end(this->xine, BUF_FLAG_END_USER);
+ xine_demux_control_end (this->stream, BUF_FLAG_END_USER);
}
static void demux_avi_dispose (demux_plugin_t *this_gen) {
@@ -1218,19 +1222,20 @@ static int demux_avi_get_status (demux_plugin_t *this_gen) {
return (this->thread_running?DEMUX_OK:DEMUX_FINISHED);
}
-static int demux_avi_send_headers (demux_avi_t *this) {
+static void demux_avi_send_headers (demux_plugin_t *this_gen) {
+ demux_avi_t *this = (demux_avi_t *) this_gen;
int i;
pthread_mutex_lock (&this->mutex);
- this->video_fifo = this->xine->video_fifo;
- this->audio_fifo = this->xine->audio_fifo;
+ this->video_fifo = this->stream->video_fifo;
+ this->audio_fifo = this->stream->audio_fifo;
this->status = DEMUX_OK;
- this->xine->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = this->avi->width;
- this->xine->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = this->avi->height;
+ this->stream->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = this->avi->width;
+ this->stream->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = this->avi->height;
for (i=0; i < this->avi->n_audio; i++)
printf ("demux_avi: audio format[%d] = 0x%x\n",
@@ -1243,7 +1248,6 @@ static int demux_avi_send_headers (demux_avi_t *this) {
if( !this->avi->audio[i]->audio_type ) {
printf ("demux_avi: unknown audio type 0x%x\n",
this->avi->audio[i]->wavex->wFormatTag);
- xine_report_codec( this->xine, XINE_CODEC_AUDIO, this->avi->audio[i]->wavex->wFormatTag, 0, 0);
this->no_audio = 1;
this->avi->audio[i]->audio_type = BUF_CONTROL_NOP;
} else
@@ -1252,11 +1256,12 @@ static int demux_avi_send_headers (demux_avi_t *this) {
(int)this->avi->audio[i]->wavex->wFormatTag);
}
- xine_demux_control_headers_done (this->xine);
+ this->stream->stream_info[XINE_STREAM_INFO_HAS_VIDEO] = 1;
+ this->stream->stream_info[XINE_STREAM_INFO_HAS_AUDIO] = !this->no_audio;
- pthread_mutex_unlock (&this->mutex);
+ xine_demux_control_headers_done (this->stream);
- return DEMUX_CAN_HANDLE;
+ pthread_mutex_unlock (&this->mutex);
}
static int demux_avi_start (demux_plugin_t *this_gen,
@@ -1380,15 +1385,13 @@ static int demux_avi_start (demux_plugin_t *this_gen,
* send start buffers
*/
if( !this->thread_running && (this->status == DEMUX_OK) ) {
- xine_demux_control_start(this->xine);
+ xine_demux_control_start (this->stream);
} else {
- xine_demux_flush_engine(this->xine);
+ xine_demux_flush_engine (this->stream);
}
if( this->status == DEMUX_OK )
- {
- xine_demux_control_newpts(this->xine, video_pts, BUF_FLAG_SEEK);
- }
+ xine_demux_control_newpts (this->stream, video_pts, BUF_FLAG_SEEK);
if( !this->thread_running && (this->status == DEMUX_OK) ) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
@@ -1407,8 +1410,6 @@ static int demux_avi_start (demux_plugin_t *this_gen,
(char*)&this->avi->bih.biCompression);
buf->free_buffer (buf);
- xine_report_codec( this->xine, XINE_CODEC_VIDEO, this->avi->bih.biCompression, 0, 0);
-
this->status = DEMUX_FINISHED;
} else {
buf->type = this->avi->video_type;
@@ -1496,143 +1497,142 @@ static int demux_avi_seek (demux_plugin_t *this_gen,
return demux_avi_start (this_gen, start_pos, start_time);
}
-static int demux_avi_open(demux_plugin_t *this_gen,
- input_plugin_t *input, int stage) {
+static int demux_avi_get_stream_length (demux_plugin_t *this_gen) {
demux_avi_t *this = (demux_avi_t *) this_gen;
- if (! (input->get_capabilities(input) & INPUT_CAP_SEEKABLE)) {
- printf("demux_avi.c: not seekable, can't handle!\n");
- return DEMUX_CANNOT_HANDLE;
+
+ if (this->avi) {
+ return get_video_pts(this, this->avi->video_idx.video_frames) / 90000 ;
}
- switch(stage) {
+ return 0;
+}
- case STAGE_BY_CONTENT: {
- if (input->get_blocksize(input))
- return DEMUX_CANNOT_HANDLE;
+static void* open_plugin (void *class_gen, xine_stream_t *stream,
+ const void *input_gen) {
+
+ input_plugin_t *input = (input_plugin_t *) input_gen;
+ demux_avi_t *this;
- if (!(input->get_capabilities(input) & INPUT_CAP_SEEKABLE))
- return DEMUX_CANNOT_HANDLE;
+ if (! (input->get_capabilities(input) & INPUT_CAP_SEEKABLE)) {
+ printf("demux_avi.c: not seekable, can't handle!\n");
+ return NULL;
+ }
- input->seek(input, 0, SEEK_SET);
+ this = xine_xmalloc (sizeof (demux_avi_t));
+ this->stream = stream;
+ this->input = input;
- this->input = input;
+ this->demux_plugin.send_headers = demux_avi_send_headers;
+ this->demux_plugin.start = demux_avi_start;
+ this->demux_plugin.seek = demux_avi_seek;
+ this->demux_plugin.stop = demux_avi_stop;
+ this->demux_plugin.dispose = demux_avi_dispose;
+ this->demux_plugin.get_status = demux_avi_get_status;
+ this->demux_plugin.get_stream_length = demux_avi_get_stream_length;
- if (this->avi)
- AVI_close (this->avi);
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_init (&this->mutex, NULL);
- this->avi = AVI_init (this);
+ switch (stream->content_detection_method) {
+
+ case XINE_DEMUX_CONTENT_STRATEGY:
- if (this->avi) {
+ if (input->get_capabilities(input) & INPUT_CAP_BLOCK) {
+ printf ("demux_avi: AVI_init failed (AVI_errno: %d)\n",
+ this->AVI_errno);
+ free (this);
+ return NULL;
+ }
- printf ("demux_avi: %ld frames\n", this->avi->video_idx.video_frames);
+ input->seek(input, 0, SEEK_SET);
- strncpy(this->last_mrl, input->get_mrl (input), 1024);
+ this->avi = AVI_init (this);
- return demux_avi_send_headers (this);
+ if (!this->avi) {
+ free (this);
+ return NULL;
}
- /* printf ("demux_avi: AVI_init failed (AVI_errno: %d)\n", this->AVI_errno); */
-
- return DEMUX_CANNOT_HANDLE;
- }
break;
- case STAGE_BY_EXTENSION: {
+ case XINE_DEMUX_EXTENSION_STRATEGY: {
char *ending, *mrl;
- char *m, *valid_ends;
mrl = input->get_mrl (input);
ending = strrchr(mrl, '.');
- if(ending) {
- xine_strdupa(valid_ends,
- this->config->register_string(this->config,
- "mrl.ends_avi", VALID_ENDS,
- _("valid mrls ending for avi demuxer"),
- NULL, 20, NULL, NULL));
- while((m = xine_strsep(&valid_ends, ",")) != NULL) {
-
- while(*m == ' ' || *m == '\t') m++;
-
- if(!strcasecmp((ending + 1), m)) {
-
- this->input = input;
+ if (!ending) {
+ free (this);
+ return NULL;
+ }
- if (this->avi)
- AVI_close (this->avi);
+ if (strncasecmp (ending, ".AVI", 4)) {
+ free (this);
+ return NULL;
+ }
- this->avi = AVI_init (this);
+ this->avi = AVI_init (this);
- if (this->avi) {
- strncpy(this->last_mrl, input->get_mrl (input), 1024);
- return demux_avi_send_headers (this);
- } else {
- printf ("demux_avi: AVI_init failed (AVI_errno: %d)\n",
- this->AVI_errno);
- return DEMUX_CANNOT_HANDLE;
- }
- }
- }
+ if (!this->avi) {
+ printf ("demux_avi: AVI_init failed (AVI_errno: %d)\n",
+ this->AVI_errno);
+ free (this);
+ return NULL;
}
- return DEMUX_CANNOT_HANDLE;
}
break;
default:
- return DEMUX_CANNOT_HANDLE;
- break;
+ free (this);
+ return NULL;
}
- return DEMUX_CANNOT_HANDLE;
+ strncpy (this->last_mrl, input->get_mrl (input), 1024);
+
+ printf ("demux_avi: %ld frames\n", this->avi->video_idx.video_frames);
+
+ return this;
+}
+
+static char *get_description (demux_class_t *this_gen) {
+ return "AVI/RIFF demux plugin";
}
-static char *demux_avi_get_id(void) {
+static char *get_identifier (demux_class_t *this_gen) {
return "AVI";
}
-static char *demux_avi_get_mimetypes(void) {
+static char *get_extensions (demux_class_t *this_gen) {
+ return "avi";
+}
+
+static char *get_mimetypes (demux_class_t *this_gen) {
return "video/msvideo: avi: AVI animation;"
"video/x-msvideo: avi: AVI animation;";
}
-static int demux_avi_get_stream_length (demux_plugin_t *this_gen) {
-
- demux_avi_t *this = (demux_avi_t *) this_gen;
+static void class_dispose (demux_class_t *this_gen) {
- if (this->avi) {
- return get_video_pts(this, this->avi->video_idx.video_frames) / 90000 ;
- }
+ demux_avi_class_t *this = (demux_avi_class_t *) this_gen;
- return 0;
+ free (this);
}
-static void *init_demuxer_plugin(xine_t *xine, void *data) {
+static void *init_plugin (xine_t *xine, void *data) {
- demux_avi_t *this;
+ demux_avi_class_t *this;
- this = xine_xmalloc (sizeof (demux_avi_t));
+ this = xine_xmalloc (sizeof (demux_avi_class_t));
this->config = xine->config;
this->xine = xine;
- (void*) this->config->register_string(this->config,
- "mrl.ends_avi", VALID_ENDS,
- _("valid mrls ending for avi demuxer"),
- NULL, 20, NULL, NULL);
-
- this->demux_plugin.open = demux_avi_open;
- this->demux_plugin.start = demux_avi_start;
- this->demux_plugin.seek = demux_avi_seek;
- this->demux_plugin.stop = demux_avi_stop;
- this->demux_plugin.dispose = demux_avi_dispose;
- this->demux_plugin.get_status = demux_avi_get_status;
- this->demux_plugin.get_identifier = demux_avi_get_id;
- this->demux_plugin.get_stream_length = demux_avi_get_stream_length;
- this->demux_plugin.get_mimetypes = demux_avi_get_mimetypes;
-
- this->status = DEMUX_FINISHED;
- pthread_mutex_init( &this->mutex, NULL );
+ this->demux_class.get_description = get_description;
+ this->demux_class.get_identifier = get_identifier;
+ this->demux_class.get_mimetypes = get_mimetypes;
+ this->demux_class.get_extensions = get_extensions;
+ this->demux_class.dispose = class_dispose;
return this;
}
@@ -1643,6 +1643,6 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_DEMUX, 11, "avi", XINE_VERSION_CODE, NULL, init_demuxer_plugin },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
+ { PLUGIN_DEMUX, 12, "avi", XINE_VERSION_CODE, NULL, init_plugin, open_plugin },
+ { PLUGIN_NONE, 0, "", 0, NULL, NULL, NULL }
};
diff --git a/src/input/Makefile.am b/src/input/Makefile.am
index 1cd0900fd..c4bfc1ed4 100644
--- a/src/input/Makefile.am
+++ b/src/input/Makefile.am
@@ -18,74 +18,78 @@ libdir = $(XINE_PLUGINDIR)
# All of xine input plugins should be named like the scheme "xineplug_inp_"
#
-if HAVE_CDROM_IOCTLS
-in_dvd = xineplug_inp_dvd.la
-in_vcd = xineplug_inp_vcd.la
-in_cda = xineplug_inp_cda.la
-endif
+#if HAVE_CDROM_IOCTLS
+#in_dvd = xineplug_inp_dvd.la
+#in_vcd = xineplug_inp_vcd.la
+#in_cda = xineplug_inp_cda.la
+#endif
# For DVD
-if HAVE_DVDNAV
-DVD_CFLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE \
- $(DVDNAV_CFLAGS) \
- -I$(top_srcdir)/src/input/libdvdread/
-link_dvdnav = $(DVDNAV_LIBS)
-else
-DVD_CFLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE \
- -I$(top_srcdir)/src/input/libdvdnav/ \
- -I$(top_srcdir)/src/input/libdvdread/
-link_dvdnav = libdvdnav/libdvdnav.la libdvdread/libdvdread.la
-endif
+#if HAVE_DVDNAV
+#DVD_CFLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE \
+# $(DVDNAV_CFLAGS) \
+# -I$(top_srcdir)/src/input/libdvdread/
+#link_dvdnav = $(DVDNAV_LIBS)
+#else
+#DVD_CFLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE \
+# -I$(top_srcdir)/src/input/libdvdnav/ \
+# -I$(top_srcdir)/src/input/libdvdread/
+#link_dvdnav = libdvdnav/libdvdnav.la libdvdread/libdvdread.la
+#endif
AM_CFLAGS = $(DVD_CFLAGS)
DEBUG_CFLAGS = @DEBUG_CFLAGS@ $(DVD_CFLAGS)
lib_LTLIBRARIES = \
- $(in_cda) \
- $(in_dvd) \
- $(in_vcd) \
- xineplug_inp_file.la \
- xineplug_inp_http.la \
- xineplug_inp_mms.la \
- xineplug_inp_net.la \
- xineplug_inp_rtp.la \
- xineplug_inp_stdin_fifo.la
-
+ xineplug_inp_file.la
+
+#lib_LTLIBRARIES = \
+# $(in_cda) \
+# $(in_dvd) \
+# $(in_vcd) \
+# xineplug_inp_file.la \
+# xineplug_inp_http.la \
+# xineplug_inp_mms.la \
+# xineplug_inp_net.la \
+# xineplug_inp_rtp.la \
+# xineplug_inp_stdin_fifo.la
+
+
xineplug_inp_file_la_SOURCES = input_file.c
xineplug_inp_file_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
xineplug_inp_file_la_LDFLAGS = -avoid-version -module
-xineplug_inp_dvd_la_SOURCES = input_dvd.c
-xineplug_inp_dvd_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la $(link_dvdnav)
-xineplug_inp_dvd_la_LDFLAGS = -avoid-version -module
+#xineplug_inp_dvd_la_SOURCES = input_dvd.c
+#xineplug_inp_dvd_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la $(link_dvdnav)
+#xineplug_inp_dvd_la_LDFLAGS = -avoid-version -module
-xineplug_inp_net_la_SOURCES = input_net.c net_buf_ctrl.c
-xineplug_inp_net_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_inp_net_la_LDFLAGS = -avoid-version -module
+#xineplug_inp_net_la_SOURCES = input_net.c net_buf_ctrl.c
+#xineplug_inp_net_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_inp_net_la_LDFLAGS = -avoid-version -module
-xineplug_inp_mms_la_SOURCES = input_mms.c net_buf_ctrl.c mms.c
-xineplug_inp_mms_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_inp_mms_la_LDFLAGS = -avoid-version -module
+#xineplug_inp_mms_la_SOURCES = input_mms.c net_buf_ctrl.c mms.c
+#xineplug_inp_mms_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_inp_mms_la_LDFLAGS = -avoid-version -module
-xineplug_inp_vcd_la_SOURCES = input_vcd.c
-xineplug_inp_vcd_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_inp_vcd_la_LDFLAGS = -avoid-version -module
+#xineplug_inp_vcd_la_SOURCES = input_vcd.c
+#xineplug_inp_vcd_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_inp_vcd_la_LDFLAGS = -avoid-version -module
-xineplug_inp_stdin_fifo_la_SOURCES = input_stdin_fifo.c net_buf_ctrl.c
-xineplug_inp_stdin_fifo_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_inp_stdin_fifo_la_LDFLAGS = -avoid-version -module
+#xineplug_inp_stdin_fifo_la_SOURCES = input_stdin_fifo.c net_buf_ctrl.c
+#xineplug_inp_stdin_fifo_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_inp_stdin_fifo_la_LDFLAGS = -avoid-version -module
-xineplug_inp_rtp_la_SOURCES = input_rtp.c
-xineplug_inp_rtp_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_inp_rtp_la_LDFLAGS = -avoid-version -module
+#xineplug_inp_rtp_la_SOURCES = input_rtp.c
+#xineplug_inp_rtp_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_inp_rtp_la_LDFLAGS = -avoid-version -module
-xineplug_inp_http_la_SOURCES = input_http.c net_buf_ctrl.c
-xineplug_inp_http_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_inp_http_la_LDFLAGS = -avoid-version -module
+#xineplug_inp_http_la_SOURCES = input_http.c net_buf_ctrl.c
+#xineplug_inp_http_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_inp_http_la_LDFLAGS = -avoid-version -module
-xineplug_inp_cda_la_SOURCES = input_cda.c
-xineplug_inp_cda_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-xineplug_inp_cda_la_LDFLAGS = -avoid-version -module
+#xineplug_inp_cda_la_SOURCES = input_cda.c
+#xineplug_inp_cda_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+#xineplug_inp_cda_la_LDFLAGS = -avoid-version -module
include_HEADERS = input_plugin.h
noinst_HEADERS = net_buf_ctrl.h mms.h
diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c
index 390b1949b..33077fb59 100644
--- a/src/input/input_dvd.c
+++ b/src/input/input_dvd.c
@@ -1,8 +1,8 @@
/*
- * Copyright (C) 2000, 2001 the xine project,
- * Rich Wareham <richwareham@users.sourceforge.net>
+ * Copyright (C) 2000-2002 the xine project,
+ * Rich Wareham <richwareham@users.sourceforge.net>
*
- * This file is part of xine, a unix video player.
+ * 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
@@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: input_dvd.c,v 1.92 2002/10/06 15:48:02 jkeil Exp $
+ * $Id: input_dvd.c,v 1.93 2002/10/14 15:47:16 guenter Exp $
*
*/
@@ -1564,6 +1564,9 @@ static void *init_input_plugin (xine_t *xine, void *data) {
/*
* $Log: input_dvd.c,v $
+ * Revision 1.93 2002/10/14 15:47:16 guenter
+ * introduction of xine_stream_t and async xine events - all still in developement
+ *
* Revision 1.92 2002/10/06 15:48:02 jkeil
* Proper alignment is needed for the array of "xine_mrl_t" structures on SPARC.
*
diff --git a/src/input/input_file.c b/src/input/input_file.c
index 2550cd2ca..4aeb23796 100644
--- a/src/input/input_file.c
+++ b/src/input/input_file.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: input_file.c,v 1.60 2002/09/22 14:29:40 mroi Exp $
+ * $Id: input_file.c,v 1.61 2002/10/14 15:47:17 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -43,25 +43,258 @@ extern int errno;
#define MAXFILES 65535
-#ifdef __GNUC__
-#define LOG_MSG_STDERR(xine, message, args...) { \
- xine_log(xine, XINE_LOG_MSG, message, ##args); \
- fprintf(stderr, message, ##args); \
- }
-#define LOG_MSG(xine, message, args...) { \
- xine_log(xine, XINE_LOG_MSG, message, ##args); \
- printf(message, ##args); \
+typedef struct {
+
+ input_class_t input_class;
+
+ xine_t *xine;
+ config_values_t *config;
+
+ int show_hidden_files;
+ char *origin_path;
+
+ int mrls_allocated_entries;
+ xine_mrl_t **mrls;
+
+} file_input_class_t;
+
+typedef struct {
+ input_plugin_t input_plugin;
+
+ xine_stream_t *stream;
+
+ int fh;
+ char *mrl;
+
+ FILE *sub;
+
+} file_input_plugin_t;
+
+
+static uint32_t file_plugin_get_capabilities (input_plugin_t *this_gen) {
+
+ return INPUT_CAP_SEEKABLE | INPUT_CAP_SPULANG;
+}
+
+
+static off_t file_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) {
+ file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
+
+ return read (this->fh, buf, len);
+}
+
+/*
+ * helper function to release buffer
+ * in case demux thread is cancelled
+ */
+static void pool_release_buffer (void *arg) {
+ buf_element_t *buf = (buf_element_t *) arg;
+ if( buf != NULL )
+ buf->free_buffer(buf);
+}
+
+static buf_element_t *file_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) {
+
+ off_t num_bytes, total_bytes;
+ file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
+ buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
+ pthread_cleanup_push( pool_release_buffer, buf );
+
+ buf->content = buf->mem;
+ buf->type = BUF_DEMUX_BLOCK;
+ total_bytes = 0;
+
+ while (total_bytes < todo) {
+ pthread_testcancel();
+ num_bytes = read (this->fh, buf->mem + total_bytes, todo-total_bytes);
+ if (num_bytes <= 0) {
+ if (num_bytes < 0)
+ xine_log (this->stream->xine, XINE_LOG_MSG,
+ _("input_file: read error (%s)\n"), strerror(errno));
+ buf->free_buffer (buf);
+ buf = NULL;
+ break;
+ }
+ total_bytes += num_bytes;
}
-#else
-#define LOG_MSG_STDERR(xine, ...) { \
- xine_log(xine, XINE_LOG_MSG, __VA_ARGS__); \
- fprintf(stderr, __VA_ARGS__); \
+
+ if( buf != NULL )
+ buf->size = total_bytes;
+
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
+ pthread_cleanup_pop(0);
+
+ return buf;
+}
+
+static off_t file_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) {
+ file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
+
+ return lseek (this->fh, offset, origin);
+}
+
+static off_t file_plugin_get_current_pos (input_plugin_t *this_gen){
+ file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
+
+ if (this->fh <0)
+ return 0;
+
+ return lseek (this->fh, 0, SEEK_CUR);
+}
+
+static off_t file_plugin_get_length (input_plugin_t *this_gen) {
+
+ struct stat buf ;
+ file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
+
+ if (this->fh <0)
+ return 0;
+
+ if (fstat (this->fh, &buf) == 0) {
+ return buf.st_size;
+ } else
+ perror ("system call fstat");
+ return 0;
+}
+
+static uint32_t file_plugin_get_blocksize (input_plugin_t *this_gen) {
+ return 0;
+}
+
+/*
+ * Return 1 is filepathname is a directory, otherwise 0
+ */
+static int is_a_dir(char *filepathname) {
+ struct stat pstat;
+
+ stat(filepathname, &pstat);
+
+ return (S_ISDIR(pstat.st_mode));
+}
+
+static int file_plugin_eject_media (input_plugin_t *this_gen) {
+ return 1; /* doesn't make sense */
+}
+
+static char* file_plugin_get_mrl (input_plugin_t *this_gen) {
+ file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
+
+ return this->mrl;
+}
+
+static int file_plugin_get_optional_data (input_plugin_t *this_gen,
+ void *data, int data_type) {
+
+ file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
+
+#ifdef LOG
+ printf ("input_file: get optional data, type %08x, sub %p\n",
+ data_type, this->sub);
+#endif
+
+ switch(data_type) {
+ case INPUT_OPTIONAL_DATA_TEXTSPU0:
+ if(this->sub) {
+ FILE **tmp;
+
+ /* dirty hacks... */
+ tmp = data;
+ *tmp = this->sub;
+
+ return INPUT_OPTIONAL_SUCCESS;
+ }
+ break;
+
+ case INPUT_OPTIONAL_DATA_SPULANG:
+ sprintf(data, "%3s", (this->sub) ? "sub" : "none");
+ return INPUT_OPTIONAL_SUCCESS;
+ break;
+
+ default:
+ return INPUT_OPTIONAL_UNSUPPORTED;
+ break;
+
}
-#define LOG_MSG(xine, ...) { \
- xine_log(xine, XINE_LOG_MSG, __VA_ARGS__); \
- printf(__VA_ARGS__); \
+
+ return INPUT_OPTIONAL_UNSUPPORTED;
+}
+
+static void file_plugin_dispose (input_plugin_t *this_gen ) {
+ file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
+
+ close(this->fh);
+
+ if (this->sub)
+ fclose (this->sub);
+
+ free (this->mrl);
+
+ free (this);
+}
+
+static void *open_plugin (void *cls_gen, xine_stream_t *stream,
+ const void *data) {
+
+ file_input_class_t *cls = (file_input_class_t *) cls_gen;
+ file_input_plugin_t *this;
+ char *mrl = strdup ((char *) data);
+ FILE *sub;
+ char *filename, *subtitle;
+ int fh;
+
+ if (!strncasecmp (mrl, "file://", 7))
+ filename = &mrl[7];
+ else
+ filename = mrl;
+
+ subtitle = strrchr (filename, '%');
+ if (subtitle) {
+ *subtitle = 0;
+ subtitle++;
+
+ xine_log (cls->xine, XINE_LOG_MSG,
+ _("input_file: trying to open subtitle file '%s'\n"),
+ subtitle);
+
+ sub = fopen (subtitle, "r");
+
+ } else
+ sub = NULL;
+
+
+ fh = open (filename, O_RDONLY);
+
+ if (fh == -1) {
+ free (mrl);
+ return NULL;
}
-#endif
+
+ this = (file_input_plugin_t *) xine_xmalloc (sizeof (file_input_plugin_t));
+ this->stream = stream;
+ this->mrl = mrl;
+ this->fh = fh;
+ this->sub = sub;
+
+ this->input_plugin.get_capabilities = file_plugin_get_capabilities;
+ this->input_plugin.read = file_plugin_read;
+ this->input_plugin.read_block = file_plugin_read_block;
+ this->input_plugin.seek = file_plugin_seek;
+ this->input_plugin.get_current_pos = file_plugin_get_current_pos;
+ this->input_plugin.get_length = file_plugin_get_length;
+ this->input_plugin.get_blocksize = file_plugin_get_blocksize;
+ this->input_plugin.get_mrl = file_plugin_get_mrl;
+ this->input_plugin.get_optional_data = file_plugin_get_optional_data;
+ this->input_plugin.dispose = file_plugin_dispose;
+
+ return this;
+}
+
+
+/*
+ * plugin class functions
+ */
#ifndef S_ISLNK
#define S_ISLNK(mode) 0
@@ -85,38 +318,16 @@ extern int errno;
#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
#endif
-typedef struct {
- input_plugin_t input_plugin;
-
- xine_t *xine;
-
- int fh;
- int show_hidden_files;
- char *origin_path;
- FILE *sub;
- char *mrl;
- config_values_t *config;
-
- int mrls_allocated_entries;
- xine_mrl_t **mrls;
-
-} file_input_plugin_t;
-
-
-/* ***************************************************************************
- * PRIVATES FUNCTIONS
- */
-
/*
* Callback for config changes.
*/
static void hidden_bool_cb(void *data, xine_cfg_entry_t *cfg) {
- file_input_plugin_t *this = (file_input_plugin_t *) data;
+ file_input_class_t *this = (file_input_class_t *) data;
this->show_hidden_files = cfg->num_value;
}
static void origin_change_cb(void *data, xine_cfg_entry_t *cfg) {
- file_input_plugin_t *this = (file_input_plugin_t *) data;
+ file_input_class_t *this = (file_input_class_t *) data;
this->origin_path = cfg->str_value;
}
@@ -206,7 +417,9 @@ static uint32_t get_file_type(char *filepathname, char *origin, xine_t *xine) {
if((lstat(filepathname, &pstat)) < 0) {
sprintf(buf, "%s/%s", origin, filepathname);
if((lstat(buf, &pstat)) < 0) {
- LOG_MSG(xine, _("lstat failed for %s{%s}\n"), filepathname, origin);
+#ifdef LOG
+ printf ("lstat failed for %s{%s}\n", filepathname, origin);
+#endif
file_type |= mrl_unknown;
return file_type;
}
@@ -257,179 +470,17 @@ static off_t get_file_size(char *filepathname, char *origin) {
return pstat.st_size;
}
-/*
- * END OF PRIVATES
- *****************************************************************************/
-/*
- *
- */
-static uint32_t file_plugin_get_capabilities (input_plugin_t *this_gen) {
-
- return INPUT_CAP_SEEKABLE | INPUT_CAP_PREVIEW | INPUT_CAP_GET_DIR | INPUT_CAP_SPULANG;
-}
-
-/*
- *
- */
-static int file_plugin_open (input_plugin_t *this_gen, const char *mrl) {
-
- char *filename, *subtitle;
- file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
-
- if (this->mrl)
- free (this->mrl);
-
- this->mrl = strdup(mrl);
-
- if (!strncasecmp (this->mrl, "file://", 7))
- filename = &this->mrl[7];
- else
- filename = this->mrl;
-
- subtitle = strrchr (filename, '%');
- if (subtitle) {
- *subtitle = 0;
- subtitle++;
-
- LOG_MSG(this->xine, _("input_file: trying to open subtitle file '%s'\n"),
- subtitle);
-
- this->sub = fopen (subtitle, "r");
-
- } else
- this->sub = NULL;
-
-
- this->fh = open (filename, O_RDONLY);
-
- if (this->fh == -1) {
- return 0;
- }
-
- return 1;
-}
-
-/*
- *
- */
-static off_t file_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) {
- file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
-
- return read (this->fh, buf, len);
-}
-
-/*
- * helper function to release buffer
- * in case demux thread is cancelled
- */
-static void pool_release_buffer (void *arg) {
- buf_element_t *buf = (buf_element_t *) arg;
- if( buf != NULL )
- buf->free_buffer(buf);
-}
-
-/*
- *
- */
-static buf_element_t *file_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) {
-
- off_t num_bytes, total_bytes;
- file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
- buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
-
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
- pthread_cleanup_push( pool_release_buffer, buf );
-
- buf->content = buf->mem;
- buf->type = BUF_DEMUX_BLOCK;
- total_bytes = 0;
-
- while (total_bytes < todo) {
- pthread_testcancel();
- num_bytes = read (this->fh, buf->mem + total_bytes, todo-total_bytes);
- if (num_bytes <= 0) {
- if (num_bytes < 0)
- LOG_MSG_STDERR(this->xine, _("input_file: read error (%s)\n"), strerror(errno));
- buf->free_buffer (buf);
- buf = NULL;
- break;
- }
- total_bytes += num_bytes;
- }
-
- if( buf != NULL )
- buf->size = total_bytes;
-
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
- pthread_cleanup_pop(0);
-
- return buf;
-}
-
-/*
- *
- */
-static off_t file_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) {
- file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
-
- return lseek (this->fh, offset, origin);
-}
-
-/*
- *
- */
-static off_t file_plugin_get_current_pos (input_plugin_t *this_gen){
- file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
-
- if (this->fh <0)
- return 0;
-
- return lseek (this->fh, 0, SEEK_CUR);
-}
-
-/*
- *
- */
-static off_t file_plugin_get_length (input_plugin_t *this_gen) {
-
- struct stat buf ;
- file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
-
- if (this->fh <0)
- return 0;
-
- if (fstat (this->fh, &buf) == 0) {
- return buf.st_size;
- } else
- perror ("system call fstat");
- return 0;
+static char *file_class_get_description (input_class_t *this_gen) {
+ return _("file input plugin");
}
-/*
- *
- */
-static uint32_t file_plugin_get_blocksize (input_plugin_t *this_gen) {
- return 0;
-}
+static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
+ const char *filename, int *nFiles) {
-/*
- * Return 1 is filepathname is a directory, otherwise 0
- */
-static int is_a_dir(char *filepathname) {
- struct stat pstat;
-
- stat(filepathname, &pstat);
+ /* FIXME: this code needs cleanup badly */
- return (S_ISDIR(pstat.st_mode));
-}
-
-/*
- *
- */
-static xine_mrl_t **file_plugin_get_dir (input_plugin_t *this_gen,
- const char *filename, int *nFiles) {
- file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
+ file_input_class_t *this = (file_input_class_t *) this_gen;
struct dirent *pdirent;
DIR *pdir;
xine_mrl_t *hide_files, *dir_files, *norm_files;
@@ -522,10 +573,8 @@ static xine_mrl_t **file_plugin_get_dir (input_plugin_t *this_gen,
memset(linkbuf, 0, sizeof(linkbuf));
linksize = readlink(fullfilename, linkbuf, XINE_PATH_MAX + XINE_NAME_MAX);
- if(linksize < 0) {
- LOG_MSG_STDERR(this->xine, _("%s(%d): readlink() failed: %s\n"),
- __XINE_FUNCTION__, __LINE__, strerror(errno));
- }
+ if(linksize < 0)
+ printf ("input_file: readlink() failed: %s\n", strerror(errno));
else {
dir_files[num_dir_files].link = (char *) xine_xmalloc(linksize + 1);
strncpy(dir_files[num_dir_files].link, linkbuf, linksize);
@@ -562,8 +611,7 @@ static xine_mrl_t **file_plugin_get_dir (input_plugin_t *this_gen,
linksize = readlink(fullfilename, linkbuf, XINE_PATH_MAX + XINE_NAME_MAX);
if(linksize < 0) {
- LOG_MSG_STDERR(this->xine, _("%s(%d): readlink() failed: %s\n"),
- __XINE_FUNCTION__, __LINE__, strerror(errno));
+ printf ("input_file: readlink() failed: %s\n", strerror(errno));
}
else {
hide_files[num_hide_files].link = (char *)
@@ -598,8 +646,7 @@ static xine_mrl_t **file_plugin_get_dir (input_plugin_t *this_gen,
linksize = readlink(fullfilename, linkbuf, XINE_PATH_MAX + XINE_NAME_MAX);
if(linksize < 0) {
- LOG_MSG_STDERR(this->xine, _("%s(%d): readlink() failed: %s\n"),
- __XINE_FUNCTION__, __LINE__, strerror(errno));
+ printf ("input_file: readlink() failed: %s\n", strerror(errno));
}
else {
norm_files[num_norm_files].link = (char *)
@@ -743,143 +790,29 @@ static xine_mrl_t **file_plugin_get_dir (input_plugin_t *this_gen,
return this->mrls;
}
-/*
- *
- */
-static int file_plugin_eject_media (input_plugin_t *this_gen) {
- return 1; /* doesn't make sense */
-}
-
-/*
- *
- */
-static char* file_plugin_get_mrl (input_plugin_t *this_gen) {
- file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
-
- return this->mrl;
-}
-
-/*
- *
- */
-static void file_plugin_close (input_plugin_t *this_gen) {
- file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
-
- close(this->fh);
- this->fh = -1;
-
- if (this->sub) {
- fclose (this->sub);
- this->sub = NULL;
- }
-}
-
-/*
- *
- */
-static void file_plugin_stop (input_plugin_t *this_gen) {
-
- file_plugin_close(this_gen);
-}
-
-/*
- *
- */
-static char *file_plugin_get_description (input_plugin_t *this_gen) {
- return _("plain file input plugin as shipped with xine");
-}
-
-/*
- *
- */
-static char *file_plugin_get_identifier (input_plugin_t *this_gen) {
- return "file";
-}
-
-/*
- *
- */
-static int file_plugin_get_optional_data (input_plugin_t *this_gen,
- void *data, int data_type) {
-
- file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
-
-#ifdef LOG
- LOG_MSG(this->xine, _("input_file: get optional data, type %08x, sub %p\n"),
- data_type, this->sub);
-#endif
-
- switch(data_type) {
- case INPUT_OPTIONAL_DATA_TEXTSPU0:
- if(this->sub) {
- FILE **tmp;
-
- /* dirty hacks... */
- tmp = data;
- *tmp = this->sub;
-
- return INPUT_OPTIONAL_SUCCESS;
- }
- break;
-
- case INPUT_OPTIONAL_DATA_SPULANG:
- sprintf(data, "%3s", (this->sub) ? "sub" : "none");
- return INPUT_OPTIONAL_SUCCESS;
- break;
-
- default:
- return INPUT_OPTIONAL_UNSUPPORTED;
- break;
-
- }
-
- return INPUT_OPTIONAL_UNSUPPORTED;
-}
-
-static void file_plugin_dispose (input_plugin_t *this_gen ) {
- file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
-
- if (this->mrl)
- free (this->mrl);
+static void file_class_dispose (input_class_t *this_gen) {
+ file_input_class_t *this = (file_input_class_t *) this_gen;
free (this->mrls);
free (this);
}
-static void *init_input_plugin (xine_t *xine, void *data) {
+static void *init_plugin (xine_t *xine, void *data) {
- file_input_plugin_t *this;
+ file_input_class_t *this;
config_values_t *config;
- this = (file_input_plugin_t *) xine_xmalloc (sizeof (file_input_plugin_t));
- config = xine->config;
- this->xine = xine;
+ this = (file_input_class_t *) xine_xmalloc (sizeof (file_input_class_t));
- this->input_plugin.get_capabilities = file_plugin_get_capabilities;
- this->input_plugin.open = file_plugin_open;
- this->input_plugin.read = file_plugin_read;
- this->input_plugin.read_block = file_plugin_read_block;
- this->input_plugin.seek = file_plugin_seek;
- this->input_plugin.get_current_pos = file_plugin_get_current_pos;
- this->input_plugin.get_length = file_plugin_get_length;
- this->input_plugin.get_blocksize = file_plugin_get_blocksize;
- this->input_plugin.get_dir = file_plugin_get_dir;
- this->input_plugin.eject_media = file_plugin_eject_media;
- this->input_plugin.get_mrl = file_plugin_get_mrl;
- this->input_plugin.close = file_plugin_close;
- this->input_plugin.stop = file_plugin_stop;
- this->input_plugin.get_description = file_plugin_get_description;
- this->input_plugin.get_identifier = file_plugin_get_identifier;
- this->input_plugin.get_autoplay_list = NULL;
- this->input_plugin.get_optional_data = file_plugin_get_optional_data;
- this->input_plugin.dispose = file_plugin_dispose;
- this->input_plugin.is_branch_possible = NULL;
+ this->xine = xine;
+ this->config = xine->config;
+ config = xine->config;
+
+ this->input_class.get_dir = file_class_get_dir;
+ this->input_class.get_description = file_class_get_description;
+ this->input_class.get_autoplay_list = NULL;
+ this->input_class.dispose = file_class_dispose;
- this->fh = -1;
- this->sub = NULL;
- this->mrl = NULL;
- this->config = config;
-
this->mrls = (xine_mrl_t **) xine_xmalloc(sizeof(xine_mrl_t*));
this->mrls_allocated_entries = 0;
@@ -889,14 +822,18 @@ static void *init_input_plugin (xine_t *xine, void *data) {
if(getcwd(current_dir, sizeof(current_dir)) == NULL)
strcpy(current_dir, ".");
- this->origin_path = config->register_string(this->config, "input.file_origin_path",
- current_dir, _("file browsing start location"),
- NULL, 0, origin_change_cb, (void *) this);
+ this->origin_path = config->register_string(config, "input.file_origin_path",
+ current_dir,
+ _("file browsing start location"),
+ NULL, 0, origin_change_cb,
+ (void *) this);
}
- this->show_hidden_files = this->config->register_bool(this->config, "input.file_hidden_files",
- 1, _("list hidden files"),
- NULL, 10, hidden_bool_cb, (void *) this);
+ this->show_hidden_files = config->register_bool(config,
+ "input.file_hidden_files",
+ 1, _("list hidden files"),
+ NULL, 10, hidden_bool_cb,
+ (void *) this);
return this;
}
@@ -907,7 +844,7 @@ static void *init_input_plugin (xine_t *xine, void *data) {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_INPUT, 8, "file", XINE_VERSION_CODE, NULL, init_input_plugin },
+ { PLUGIN_INPUT, 8, "file", XINE_VERSION_CODE, NULL, init_plugin, open_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/input/input_plugin.h b/src/input/input_plugin.h
index 360cd9447..20ce70653 100644
--- a/src/input/input_plugin.h
+++ b/src/input/input_plugin.h
@@ -17,24 +17,163 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: input_plugin.h,v 1.31 2002/09/22 14:29:40 mroi Exp $
+ * $Id: input_plugin.h,v 1.32 2002/10/14 15:47:19 guenter Exp $
*/
#ifndef HAVE_INPUT_PLUGIN_H
#define HAVE_INPUT_PLUGIN_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include <inttypes.h>
#include <sys/types.h>
#include <assert.h>
#include "buffer.h"
#include "configfile.h"
-#define INPUT_PLUGIN_IFACE_VERSION 8
+#define INPUT_PLUGIN_IFACE_VERSION 9
+typedef struct input_class_s input_class_t ;
+
+struct input_class_s {
+
+ /*
+ * return short, human readable identifier for this plugin class
+ */
+ char* (*get_identifier) (input_class_t *this);
+
+ /*
+ * return human readable (verbose = 1 line) description for
+ * this plugin class
+ */
+ char* (*get_description) (input_class_t *this);
+
+ /*
+ * ls function, optional: may be NULL
+ * return value: NULL => filename is a file, **char=> filename is a dir
+ */
+ xine_mrl_t ** (*get_dir) (input_class_t *this, const char *filename, int *nFiles);
+
+ /*
+ * generate autoplay list, optional: may be NULL
+ * return value: list of MRLs
+ */
+ char ** (*get_autoplay_list) (input_class_t *this, int *num_files);
+
+ /*
+ * close down, free all resources
+ */
+ void (*dispose) (input_class_t *this);
+
+ /*
+ * eject/load the media (if possible)
+ *
+ * returns 0 for temporary failures
+ */
+ int (*eject_media) (input_class_t *this);
+};
+
+typedef struct input_plugin_s input_plugin_t;
+
+struct input_plugin_s {
+
+ /*
+ * return capabilities of input source
+ */
+
+ uint32_t (*get_capabilities) (input_plugin_t *this);
+
+ /*
+ * read nlen bytes, return number of bytes read
+ */
+ off_t (*read) (input_plugin_t *this, char *buf, off_t nlen);
+
+
+ /*
+ * read one block, return newly allocated block (or NULL on failure)
+ * for blocked input sources len must be == blocksize
+ * the fifo parameter is only used to get access to the buffer_pool_alloc function
+ */
+ buf_element_t *(*read_block)(input_plugin_t *this, fifo_buffer_t *fifo, off_t len);
+
+
+ /*
+ * seek position, return new position
+ *
+ * if seeking failed, -1 is returned
+ */
+ off_t (*seek) (input_plugin_t *this, off_t offset, int origin);
+
+
+ /*
+ * get current position in stream.
+ *
+ */
+ off_t (*get_current_pos) (input_plugin_t *this);
+
+
+ /*
+ * return length of input (-1 => unlimited, e.g. stream)
+ */
+ off_t (*get_length) (input_plugin_t *this);
+
+
+ /*
+ * return block size of input source (if supported, 0 otherwise)
+ */
+
+ uint32_t (*get_blocksize) (input_plugin_t *this);
+
+
+ /*
+ * return current MRL
+ */
+ char * (*get_mrl) (input_plugin_t *this);
+
+
+ /*
+ * request optional data from input plugin.
+ */
+ int (*get_optional_data) (input_plugin_t *this, void *data, int data_type);
+
+
+ /*
+ * close stream, free instance resources
+ */
+ void (*dispose) (input_plugin_t *this);
+
+ /*
+ * "backward" link to input plugin class struct
+ */
+
+ input_class_t *input_class;
+
+};
+
+/*
+ * possible capabilites an input plugin can have:
+ */
+#define INPUT_CAP_NOCAP 0x00000000
+#define INPUT_CAP_SEEKABLE 0x00000001
+#define INPUT_CAP_BLOCK 0x00000002
+#define INPUT_CAP_CLUT 0x00000004
+#define INPUT_CAP_AUDIOLANG 0x00000008
+#define INPUT_CAP_SPULANG 0x00000010
+#define INPUT_CAP_VARIABLE_BITRATE 0x00000020
+/* for non-seekable plugins, allows content detection: */
+#define INPUT_CAP_PREVIEW 0x00000040
+#define INPUT_CAP_CHAPTERS 0x00000080
+
+
+#define INPUT_OPTIONAL_UNSUPPORTED 0
+#define INPUT_OPTIONAL_SUCCESS 1
+
+#define INPUT_OPTIONAL_DATA_CLUT 1
+#define INPUT_OPTIONAL_DATA_AUDIOLANG 2
+#define INPUT_OPTIONAL_DATA_SPULANG 3
+#define INPUT_OPTIONAL_DATA_TEXTSPU0 4
+#define INPUT_OPTIONAL_DATA_TEXTSPU1 5
+#define INPUT_OPTIONAL_DATA_TEXTSPU2 6
+#define INPUT_OPTIONAL_DATA_PREVIEW 7
+
#define MAX_MRL_ENTRIES 255
/* Types of mrls returned by get_dir() */
@@ -136,174 +275,5 @@ extern "C" {
} \
}
-typedef struct input_plugin_s input_plugin_t;
-
-struct input_plugin_s
-{
-
- /*
- * return capabilities of input source
- */
-
- uint32_t (*get_capabilities) (input_plugin_t *this);
-
- /*
- * open input MRL - return 1 if succ
- */
- int (*open) (input_plugin_t *this, const char *mrl);
-
-
- /*
- * read nlen bytes, return number of bytes read
- */
- off_t (*read) (input_plugin_t *this, char *buf, off_t nlen);
-
-
- /*
- * read one block, return newly allocated block (or NULL on failure)
- * for blocked input sources len must be == blocksize
- * the fifo parameter is only used to get access to the buffer_pool_alloc function
- */
- buf_element_t *(*read_block)(input_plugin_t *this, fifo_buffer_t *fifo, off_t len);
-
-
- /*
- * seek position, return new position
- *
- * if seeking failed, -1 is returned
- */
- off_t (*seek) (input_plugin_t *this, off_t offset, int origin);
-
-
- /*
- * get current position in stream.
- *
- */
- off_t (*get_current_pos) (input_plugin_t *this);
-
-
- /*
- * return length of input (-1 => unlimited, e.g. stream)
- */
- off_t (*get_length) (input_plugin_t *this);
-
-
- /*
- * return block size of input source (if supported, 0 otherwise)
- */
-
- uint32_t (*get_blocksize) (input_plugin_t *this);
-
-
- /*
- * ls function
- * return value: NULL => filename is a file, **char=> filename is a dir
- */
- xine_mrl_t ** (*get_dir) (input_plugin_t *this, const char *filename, int *nFiles);
-
-
- /*
- * eject/load the media (if it's possible)
- *
- * returns 0 for temporary failures
- */
- int (*eject_media) (input_plugin_t *this);
-
-
- /*
- * return current MRL
- */
- char * (*get_mrl) (input_plugin_t *this);
-
-
- /*
- * stop input source
- */
- void (*stop) (input_plugin_t *this);
-
-
- /*
- * close input source
- */
- void (*close) (input_plugin_t *this);
-
-
- /*
- * return human readable (verbose = 1 line) description for this plugin
- */
- char* (*get_description) (input_plugin_t *this);
-
-
- /*
- * return short, human readable identifier for this plugin
- * this is used for GUI buttons, The identifier must have max. 4 characters
- * characters (max. 5 including terminating \0)
- */
- char* (*get_identifier) (input_plugin_t *this);
-
-
- /*
- * generate autoplay list
- * return value: list of MRLs
- */
- char ** (*get_autoplay_list) (input_plugin_t *this, int *nFiles);
-
-
- /*
- * request optional data from input plugin.
- */
- int (*get_optional_data) (input_plugin_t *this, void *data, int data_type);
-
- /*
- * check if it is possible/valid to directly branch to this MRL
- * optional: may be NULL
- */
-
- int (*is_branch_possible) (input_plugin_t *this, char *next_mrl);
-
- /*
- * free resources
- */
- void (*dispose) (input_plugin_t *this);
-};
-
-/*
- * possible capabilites an input plugin can have:
- */
-#define INPUT_CAP_NOCAP 0x00000000
-#define INPUT_CAP_SEEKABLE 0x00000001
-#define INPUT_CAP_BLOCK 0x00000002
-#define INPUT_CAP_AUTOPLAY 0x00000004
-#define INPUT_CAP_GET_DIR 0x00000008
-#define INPUT_CAP_BROWSABLE 0x00000010
-#define INPUT_CAP_CLUT 0x00000020
-#define INPUT_CAP_AUDIOLANG 0x00000040
-#define INPUT_CAP_SPULANG 0x00000080
-#define INPUT_CAP_VARIABLE_BITRATE 0x00000100
-#define INPUT_CAP_PREVIEW 0x00000200 /* Requires INPUT_CAP_SEEKABLE */
-#define INPUT_CAP_CHAPTERS 0x00000400
-
-
-#define INPUT_OPTIONAL_UNSUPPORTED 0
-#define INPUT_OPTIONAL_SUCCESS 1
-
-#define INPUT_OPTIONAL_DATA_CLUT 1
-#define INPUT_OPTIONAL_DATA_AUDIOLANG 2
-#define INPUT_OPTIONAL_DATA_SPULANG 3
-#define INPUT_OPTIONAL_DATA_TEXTSPU0 4
-#define INPUT_OPTIONAL_DATA_TEXTSPU1 5
-#define INPUT_OPTIONAL_DATA_TEXTSPU2 6
-#define INPUT_OPTIONAL_DATA_PREVIEW 7
-
-/*
- * each input plugin _must_ implement this function:
- *
- * input_plugin_t *init_input_plugin (int iface, xine_t *xine) ;
- *
- */
-
-#ifdef __cplusplus
-}
-#endif
#endif
diff --git a/src/input/net_buf_ctrl.c b/src/input/net_buf_ctrl.c
index 3065e5885..e9537bf6e 100644
--- a/src/input/net_buf_ctrl.c
+++ b/src/input/net_buf_ctrl.c
@@ -32,9 +32,9 @@
#define DEFAULT_LOW_WATER_MARK 2
#define DEFAULT_HIGH_WATER_MARK 5
-/*
+
#define LOG
-*/
+
struct nbc_s {
xine_t *xine;
@@ -55,8 +55,8 @@ void nbc_check_buffers (nbc_t *this) {
}
#ifdef LOG
if (this->buffering) {
- xine_log (this->xine, XINE_LOG_MSG,
- "net_buf_ctl: buffering (%d/%d)...\n", fifo_fill, this->high_water_mark);
+ printf ("net_buf_ctl: buffering (%d/%d)...\n",
+ fifo_fill, this->high_water_mark);
}
#endif
if (fifo_fill<this->low_water_mark) {
diff --git a/src/libspudec/spu_decoder_api.h b/src/libspudec/spu_decoder_api.h
index 34ed1b0f4..937bc7507 100644
--- a/src/libspudec/spu_decoder_api.h
+++ b/src/libspudec/spu_decoder_api.h
@@ -55,6 +55,7 @@ struct spu_decoder_s {
int (*get_nav_pci) (spu_decoder_t *this, pci_t *nav_pci);
+ void *node; /* used by plugin loader */
};
typedef struct spu_button_s spu_button_t;
diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am
index 59e3c0899..6eb07a850 100644
--- a/src/xine-engine/Makefile.am
+++ b/src/xine-engine/Makefile.am
@@ -24,7 +24,7 @@ libxine_la_LDFLAGS = \
include_HEADERS = buffer.h metronom.h configfile.h vo_scale.h \
audio_out.h resample.h video_out.h xine_internal.h spu_decoder.h \
lrb.h video_overlay.h osd.h scratch.h xine_plugin.h xineintl.h \
- plugin_catalog.h
+ plugin_catalog.h audio_decoder.h video_decoder.h
noinst_HEADERS = bswap.h nvtvd.h
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index 9ad8ddfdc..892fdbf8d 100644
--- a/src/xine-engine/audio_decoder.c
+++ b/src/xine-engine/audio_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_decoder.c,v 1.84 2002/09/18 00:51:34 guenter Exp $
+ * $Id: audio_decoder.c,v 1.85 2002/10/14 15:47:23 guenter Exp $
*
*
* functions that implement audio decoding
@@ -40,10 +40,10 @@
#define LOG
*/
-void *audio_decoder_loop (void *this_gen) {
+void *audio_decoder_loop (void *stream_gen) {
buf_element_t *buf;
- xine_t *this = (xine_t *) this_gen;
+ xine_stream_t *stream = (xine_stream_t *) stream_gen;
int running = 1;
audio_decoder_t *decoder;
static int prof_audio_decode = -1;
@@ -58,7 +58,7 @@ void *audio_decoder_loop (void *this_gen) {
printf ("audio_loop: waiting for package...\n");
#endif
- buf = this->audio_fifo->get (this->audio_fifo);
+ buf = stream->audio_fifo->get (stream->audio_fifo);
#ifdef LOG
@@ -67,75 +67,79 @@ void *audio_decoder_loop (void *this_gen) {
#endif
if (buf->input_pos)
- this->cur_input_pos = buf->input_pos;
+ stream->input_pos = buf->input_pos;
if (buf->input_length)
- this->cur_input_length = buf->input_length;
+ stream->input_length = buf->input_length;
if (buf->input_time) {
- this->cur_input_time = buf->input_time;
- pthread_mutex_lock (&this->osd_lock);
- if( this->curtime_needed_for_osd && !(--this->curtime_needed_for_osd) )
- xine_internal_osd (this, ">",90000);
- pthread_mutex_unlock (&this->osd_lock);
+ stream->input_time = buf->input_time;
}
switch (buf->type) {
+ case BUF_CONTROL_HEADERS_DONE:
+ pthread_mutex_lock (&stream->counter_lock);
+ stream->header_count_audio++;
+ pthread_cond_broadcast (&stream->counter_changed);
+ pthread_mutex_unlock (&stream->counter_lock);
+ break;
+
case BUF_CONTROL_START:
- if (this->cur_audio_decoder_plugin) {
- this->cur_audio_decoder_plugin->close (this->cur_audio_decoder_plugin);
- this->cur_audio_decoder_plugin = NULL;
- this->audio_track_map_entries = 0;
- this->audio_type = 0;
+ if (stream->audio_decoder_plugin) {
+ free_audio_decoder (stream, stream->audio_decoder_plugin);
+ stream->audio_decoder_plugin = NULL;
+ stream->audio_track_map_entries = 0;
+ stream->audio_type = 0;
}
- pthread_mutex_lock (&this->finished_lock);
- this->audio_finished = 0;
- pthread_mutex_unlock (&this->finished_lock);
-
- this->metronom->handle_audio_discontinuity (this->metronom, DISC_STREAMSTART, 0);
+ stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_STREAMSTART, 0);
break;
case BUF_CONTROL_END:
- if (this->cur_audio_decoder_plugin) {
- this->cur_audio_decoder_plugin->close (this->cur_audio_decoder_plugin);
- this->cur_audio_decoder_plugin = NULL;
- this->audio_track_map_entries = 0;
- this->audio_type = 0;
+ if (stream->audio_decoder_plugin) {
+ free_audio_decoder (stream, stream->audio_decoder_plugin);
+ stream->audio_decoder_plugin = NULL;
+ stream->audio_track_map_entries = 0;
+ stream->audio_type = 0;
}
+
+ /* wait for video to reach this marker, if necessary */
- pthread_mutex_lock (&this->finished_lock);
+ pthread_mutex_lock (&stream->counter_lock);
- if (!this->audio_finished ) {
- this->audio_finished = 1;
-
- if (this->video_finished) {
- if( this->playing_logo )
- buf->decoder_flags = 0;
- this->playing_logo = 0;
-
- if( buf->decoder_flags & BUF_FLAG_END_STREAM )
- xine_notify_stream_finished (this);
- }
- }
+ stream->finished_count_audio++;
- pthread_mutex_unlock (&this->finished_lock);
+ printf ("audio_decoder: reached end marker # %d\n",
+ stream->finished_count_audio);
- this->audio_channel_auto = -1;
+ pthread_cond_broadcast (&stream->counter_changed);
- /* future magic - coming soon
- lrb_flush (this->audio_temp);
- */
+ if (stream->stream_info[XINE_STREAM_INFO_HAS_AUDIO]) {
+
+ while (stream->finished_count_video < stream->finished_count_audio) {
+ pthread_cond_wait (&stream->counter_changed, &stream->counter_lock);
+ }
+ }
+
+ pthread_mutex_unlock (&stream->counter_lock);
+
+ if (!stream->stream_info[XINE_STREAM_INFO_HAS_VIDEO]) {
+ /* set engine status, send frontend notification event */
+ xine_handle_stream_end (stream,
+ buf->decoder_flags & BUF_FLAG_END_STREAM);
+ }
+
+ stream->audio_channel_auto = -1;
break;
case BUF_CONTROL_QUIT:
- if (this->cur_audio_decoder_plugin) {
- this->cur_audio_decoder_plugin->close (this->cur_audio_decoder_plugin);
- this->cur_audio_decoder_plugin = NULL;
- this->audio_track_map_entries = 0;
- this->audio_type = 0;
+ if (stream->audio_decoder_plugin) {
+ free_audio_decoder (stream, stream->audio_decoder_plugin);
+ stream->audio_decoder_plugin = NULL;
+ stream->audio_track_map_entries = 0;
+ stream->audio_type = 0;
}
running = 0;
break;
@@ -144,21 +148,21 @@ void *audio_decoder_loop (void *this_gen) {
break;
case BUF_CONTROL_RESET_DECODER:
- if (this->cur_audio_decoder_plugin)
- this->cur_audio_decoder_plugin->reset (this->cur_audio_decoder_plugin);
- if (this->audio_out)
- this->audio_out->control(this->audio_out, AO_CTRL_FLUSH_BUFFERS);
+ if (stream->audio_decoder_plugin)
+ stream->audio_decoder_plugin->reset (stream->audio_decoder_plugin);
+ if (stream->audio_out)
+ stream->audio_out->control(stream->audio_out, AO_CTRL_FLUSH_BUFFERS);
break;
case BUF_CONTROL_DISCONTINUITY:
- this->metronom->handle_audio_discontinuity (this->metronom, DISC_RELATIVE, buf->disc_off);
+ stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_RELATIVE, buf->disc_off);
break;
case BUF_CONTROL_NEWPTS:
if (buf->decoder_flags && BUF_FLAG_SEEK) {
- this->metronom->handle_audio_discontinuity (this->metronom, DISC_STREAMSEEK, buf->disc_off);
+ stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_STREAMSEEK, buf->disc_off);
} else {
- this->metronom->handle_audio_discontinuity (this->metronom, DISC_ABSOLUTE, buf->disc_off);
+ stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_ABSOLUTE, buf->disc_off);
}
break;
@@ -166,7 +170,7 @@ void *audio_decoder_loop (void *this_gen) {
{
printf ("audio_decoder: suggested switching to stream_id %02x\n",
buf->decoder_info[0]);
- this->audio_channel_auto = buf->decoder_info[0] & 0xff;
+ stream->audio_channel_auto = buf->decoder_info[0] & 0xff;
}
break;
@@ -182,83 +186,79 @@ void *audio_decoder_loop (void *this_gen) {
/*
printf("audio_decoder: buf_type=%08x auto=%08x user=%08x\n",
buf->type,
- this->audio_channel_auto,
- this->audio_channel_user);
+ stream->audio_channel_auto,
+ stream->audio_channel_user);
*/
/* update track map */
i = 0;
- while ( (i<this->audio_track_map_entries) && (this->audio_track_map[i]<buf->type) )
+ while ( (i<stream->audio_track_map_entries) && (stream->audio_track_map[i]<buf->type) )
i++;
- if ( (i==this->audio_track_map_entries) || (this->audio_track_map[i] != buf->type) ) {
+ if ( (i==stream->audio_track_map_entries) || (stream->audio_track_map[i] != buf->type) ) {
- j = this->audio_track_map_entries;
+ j = stream->audio_track_map_entries;
while (j>i) {
- this->audio_track_map[j] = this->audio_track_map[j-1];
+ stream->audio_track_map[j] = stream->audio_track_map[j-1];
j--;
}
- this->audio_track_map[i] = buf->type;
- this->audio_track_map_entries++;
+ stream->audio_track_map[i] = buf->type;
+ stream->audio_track_map_entries++;
}
/* find out which audio type to decode */
- if (this->audio_channel_user > -2) {
+ if (stream->audio_channel_user > -2) {
- if (this->audio_channel_user == -1) {
+ if (stream->audio_channel_user == -1) {
/* auto */
- if (this->audio_channel_auto>=0) {
+ if (stream->audio_channel_auto>=0) {
- if ((buf->type & 0xFF) == this->audio_channel_auto) {
+ if ((buf->type & 0xFF) == stream->audio_channel_auto) {
audio_type = buf->type;
} else
audio_type = -1;
} else
- audio_type = this->audio_track_map[0];
+ audio_type = stream->audio_track_map[0];
} else {
- if (this->audio_channel_user <= this->audio_track_map_entries)
- audio_type = this->audio_track_map[this->audio_channel_user];
+ if (stream->audio_channel_user <= stream->audio_track_map_entries)
+ audio_type = stream->audio_track_map[stream->audio_channel_user];
else
audio_type = -1;
}
- /* now, decode this buffer if it's the right audio type */
+ /* now, decode stream buffer if it's the right audio type */
if (buf->type == audio_type) {
int streamtype = (buf->type>>16) & 0xFF;
- decoder = get_audio_decoder (this, streamtype);
+ decoder = get_audio_decoder (stream, streamtype);
/* close old decoder of audio type has changed */
- if (audio_type != this->audio_type) {
+ if (audio_type != stream->audio_type) {
- if (this->cur_audio_decoder_plugin) {
- this->cur_audio_decoder_plugin->close (this->cur_audio_decoder_plugin);
- this->cur_audio_decoder_plugin = NULL;
+ if (stream->audio_decoder_plugin) {
+ free_audio_decoder (stream, stream->audio_decoder_plugin);
+ stream->audio_decoder_plugin = NULL;
}
if (decoder) {
xine_event_t event;
- this->meta_info[XINE_META_INFO_AUDIOCODEC]
- = strdup (decoder->get_identifier());
- xine_report_codec( this, XINE_CODEC_AUDIO, 0, buf->type, 1);
-
- this->cur_audio_decoder_plugin = decoder;
- this->cur_audio_decoder_plugin->init (this->cur_audio_decoder_plugin, this->audio_out);
+ stream->audio_decoder_plugin = decoder;
- this->audio_type = audio_type;
+ stream->audio_type = audio_type;
- event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
- xine_send_event(this, &event);
+ event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
+ event.data_length = 0;
+ xine_event_send(stream, &event);
}
}
@@ -267,15 +267,16 @@ void *audio_decoder_loop (void *this_gen) {
if (decoder)
decoder->decode_data (decoder, buf);
else if( buf->type != buftype_unknown ) {
- xine_log (this, XINE_LOG_MSG, "audio_decoder: no plugin available to handle '%s'\n",
+ xine_log (stream->xine, XINE_LOG_MSG,
+ "audio_decoder: no plugin available to handle '%s'\n",
buf_audio_name( buf->type ) );
- xine_report_codec( this, XINE_CODEC_AUDIO, 0, buf->type, 0);
buftype_unknown = buf->type;
}
}
}
} else if( buf->type != buftype_unknown ) {
- xine_log (this, XINE_LOG_MSG, "audio_decoder: unknown buffer type: %08x\n",
+ xine_log (stream->xine, XINE_LOG_MSG,
+ "audio_decoder: unknown buffer type: %08x\n",
buf->type );
buftype_unknown = buf->type;
}
@@ -289,15 +290,14 @@ void *audio_decoder_loop (void *this_gen) {
pthread_exit(NULL);
}
-void audio_decoder_init (xine_t *this) {
+void audio_decoder_init (xine_stream_t *stream) {
pthread_attr_t pth_attrs;
struct sched_param pth_params;
int err;
- if (this->audio_out == NULL) {
- this->audio_finished = 1;
- this->audio_fifo = NULL;
+ if (stream->audio_out == NULL) {
+ stream->audio_fifo = NULL;
return;
}
@@ -308,14 +308,14 @@ void audio_decoder_init (xine_t *this) {
* We provide buffers of 8k size instead of 2k for demuxers sending
* larger chunks.
*/
- this->audio_fifo = fifo_buffer_new (230, 8192);
- this->audio_channel_user = -1;
- this->audio_channel_auto = 0;
- this->audio_track_map_entries = 0;
- this->audio_type = 0;
+ stream->audio_fifo = fifo_buffer_new (230, 8192);
+ stream->audio_channel_user = -1;
+ stream->audio_channel_auto = 0;
+ stream->audio_track_map_entries = 0;
+ stream->audio_type = 0;
/* future magic - coming soon
- this->audio_temp = lrb_new (100, this->audio_fifo);
+ stream->audio_temp = lrb_new (100, stream->audio_fifo);
*/
pthread_attr_init(&pth_attrs);
@@ -324,41 +324,41 @@ void audio_decoder_init (xine_t *this) {
pthread_attr_setschedparam(&pth_attrs, &pth_params);
pthread_attr_setscope(&pth_attrs, PTHREAD_SCOPE_SYSTEM);
- if ((err = pthread_create (&this->audio_thread,
- &pth_attrs, audio_decoder_loop, this)) != 0) {
+ if ((err = pthread_create (&stream->audio_thread,
+ &pth_attrs, audio_decoder_loop, stream)) != 0) {
fprintf (stderr, "audio_decoder: can't create new thread (%s)\n",
strerror(err));
abort();
}
}
-void audio_decoder_shutdown (xine_t *this) {
+void audio_decoder_shutdown (xine_stream_t *stream) {
buf_element_t *buf;
void *p;
- if (this->audio_fifo) {
- /* this->audio_fifo->clear(this->audio_fifo); */
+ if (stream->audio_fifo) {
+ /* stream->audio_fifo->clear(stream->audio_fifo); */
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_QUIT;
- this->audio_fifo->put (this->audio_fifo, buf);
+ stream->audio_fifo->put (stream->audio_fifo, buf);
- pthread_join (this->audio_thread, &p);
+ pthread_join (stream->audio_thread, &p);
}
- if(this->audio_out) {
- this->audio_out->exit (this->audio_out);
- this->audio_out = NULL;
+ if(stream->audio_out) {
+ stream->audio_out->exit (stream->audio_out);
+ stream->audio_out = NULL;
}
- if (this->audio_fifo) {
- this->audio_fifo->dispose (this->audio_fifo);
- this->audio_fifo = NULL;
+ if (stream->audio_fifo) {
+ stream->audio_fifo->dispose (stream->audio_fifo);
+ stream->audio_fifo = NULL;
}
}
-int xine_get_audio_channel (xine_t *this) {
+int xine_get_audio_channel (xine_stream_t *stream) {
- return this->audio_type & 0xFFFF;
+ return stream->audio_type & 0xFFFF;
}
diff --git a/src/xine-engine/audio_decoder.h b/src/xine-engine/audio_decoder.h
new file mode 100644
index 000000000..dd5fcc591
--- /dev/null
+++ b/src/xine-engine/audio_decoder.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2000-2002 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
+ *
+ * $Id: audio_decoder.h,v 1.3 2002/10/14 15:47:25 guenter Exp $
+ *
+ * xine audio decoder plugin interface
+ *
+ */
+
+#ifndef HAVE_AUDIO_DECODER_H
+#define HAVE_AUDIO_DECODER_H
+
+#include <inttypes.h>
+#include "buffer.h"
+
+#define AUDIO_DECODER_IFACE_VERSION 10
+
+/*
+ * generic xine audio decoder plugin interface
+ */
+
+typedef struct audio_decoder_class_s audio_decoder_class_t;
+
+struct audio_decoder_class_s {
+
+ /*
+ * return short, human readable identifier for this plugin class
+ */
+ char* (*get_identifier) (audio_decoder_class_t *this);
+
+ /*
+ * return human readable (verbose = 1 line) description for
+ * this plugin class
+ */
+ char* (*get_description) (audio_decoder_class_t *this);
+};
+
+
+typedef struct audio_decoder_s audio_decoder_t;
+
+struct audio_decoder_s {
+
+ /*
+ * decode data from buf and feed decoded samples to
+ * audio output
+ */
+ void (*decode_data) (audio_decoder_t *this, buf_element_t *buf);
+
+ /*
+ * reset decoder after engine flush (prepare for new
+ * audio data not related to recently decoded data)
+ */
+ void (*reset) (audio_decoder_t *this);
+
+ /*
+ * close down, free all resources
+ */
+ void (*dispose) (audio_decoder_t *this);
+
+ void *node; /* used by plugin loader */
+
+};
+
+#endif
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 5e2da61f9..e0c371629 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -17,7 +17,7 @@
* along with self program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.c,v 1.69 2002/10/12 19:20:02 jkeil Exp $
+ * $Id: audio_out.c,v 1.70 2002/10/14 15:47:25 guenter Exp $
*
* 22-8-2001 James imported some useful AC3 sections from the previous alsa driver.
* (c) 2001 Andy Lo A Foe <andy@alsaplayer.org>
@@ -581,28 +581,28 @@ static int ao_open(ao_instance_t *this,
switch (mode) {
case AO_CAP_MODE_MONO:
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 1;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 1;
break;
case AO_CAP_MODE_STEREO:
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 2;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 2;
break;
case AO_CAP_MODE_4CHANNEL:
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 4;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 4;
break;
case AO_CAP_MODE_5CHANNEL:
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 5;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 5;
break;
case AO_CAP_MODE_5_1CHANNEL:
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 6;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 6;
break;
case AO_CAP_MODE_A52:
case AO_CAP_MODE_AC5:
default:
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 255; /* unknown */
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 255; /* unknown */
}
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = bits;
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] = rate;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = bits;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] = rate;
this->input.mode = mode;
this->input.rate = rate;
@@ -861,9 +861,10 @@ static int ao_control (ao_instance_t *this, int cmd, ...) {
return rval;
}
-ao_instance_t *ao_new_instance (xine_ao_driver_t *driver, xine_t *xine) {
+ao_instance_t *ao_new_instance (xine_ao_driver_t *driver,
+ xine_stream_t *stream) {
- config_values_t *config = xine->config;
+ config_values_t *config = stream->xine->config;
ao_instance_t *this;
int i;
static char *resample_modes[] = {"auto", "off", "on", NULL};
@@ -871,8 +872,9 @@ ao_instance_t *ao_new_instance (xine_ao_driver_t *driver, xine_t *xine) {
this = xine_xmalloc (sizeof (ao_instance_t)) ;
this->driver = driver;
- this->metronom = xine->metronom;
- this->xine = xine;
+ this->metronom = stream->metronom;
+ this->xine = stream->xine;
+ this->stream = stream;
pthread_mutex_init( &this->driver_lock, NULL );
this->open = ao_open;
diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h
index e43d5f3a4..68e0ca750 100644
--- a/src/xine-engine/audio_out.h
+++ b/src/xine-engine/audio_out.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.h,v 1.34 2002/09/18 00:51:34 guenter Exp $
+ * $Id: audio_out.h,v 1.35 2002/10/14 15:47:27 guenter Exp $
*/
#ifndef HAVE_AUDIO_OUT_H
#define HAVE_AUDIO_OUT_H
@@ -124,6 +124,8 @@ struct xine_ao_driver_s {
* See AO_CTRL_* below.
*/
int (*control) (xine_ao_driver_t *this, int cmd, /* arg */ ...);
+
+ void *node;
};
/*
@@ -203,9 +205,10 @@ struct ao_instance_s {
/* private stuff */
xine_ao_driver_t *driver;
- pthread_mutex_t driver_lock;
- metronom_t *metronom;
- xine_t *xine;
+ pthread_mutex_t driver_lock;
+ metronom_t *metronom;
+ xine_stream_t *stream;
+ xine_t *xine;
int audio_loop_running;
int audio_paused;
@@ -231,20 +234,12 @@ struct ao_instance_s {
int64_t passthrough_offset;
};
-/* This initiates the audio_out sync routines
+/*
+ * this initiates the audio_out sync routines
* found in ./src/xine-engine/audio_out.c
*/
-ao_instance_t *ao_new_instance (xine_ao_driver_t *driver, xine_t *xine) ;
-/*
- * to build a dynamic audio output plugin,
- * you have to implement these driver:
- *
- *
- * xine_ao_driver_t *init_audio_out_plugin (config_values_t *config)
- *
- * init this plugin, check if device is available
- *
- */
+ao_instance_t *ao_new_instance (xine_ao_driver_t *driver,
+ xine_stream_t *stream) ;
/*
* audio output modes + capabilities
diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c
index 008f6ca1d..8453bf91f 100644
--- a/src/xine-engine/demux.c
+++ b/src/xine-engine/demux.c
@@ -32,92 +32,92 @@
* indication must be sent. relative discontinuities are likely
* to cause "jumps" on metronom.
*/
-void xine_demux_flush_engine (xine_t *this) {
+void xine_demux_flush_engine (xine_stream_t *stream) {
buf_element_t *buf;
- this->video_fifo->clear(this->video_fifo);
+ stream->video_fifo->clear(stream->video_fifo);
- if( this->audio_fifo )
- this->audio_fifo->clear(this->audio_fifo);
+ if( stream->audio_fifo )
+ stream->audio_fifo->clear(stream->audio_fifo);
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
buf->type = BUF_CONTROL_RESET_DECODER;
- this->video_fifo->put (this->video_fifo, buf);
+ stream->video_fifo->put (stream->video_fifo, buf);
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ if(stream->audio_fifo) {
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_RESET_DECODER;
- this->audio_fifo->put (this->audio_fifo, buf);
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
- this->metronom->adjust_clock(this->metronom,
- this->metronom->get_current_time(this->metronom) + 30 * 90000 );
+ stream->metronom->adjust_clock(stream->metronom,
+ stream->metronom->get_current_time(stream->metronom) + 30 * 90000 );
}
-void xine_demux_control_newpts( xine_t *this, int64_t pts, uint32_t flags ) {
+void xine_demux_control_newpts( xine_stream_t *stream, int64_t pts, uint32_t flags ) {
buf_element_t *buf;
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
buf->type = BUF_CONTROL_NEWPTS;
buf->decoder_flags = flags;
buf->disc_off = pts;
- this->video_fifo->put (this->video_fifo, buf);
+ stream->video_fifo->put (stream->video_fifo, buf);
- if (this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ if (stream->audio_fifo) {
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_NEWPTS;
buf->decoder_flags = flags;
buf->disc_off = pts;
- this->audio_fifo->put (this->audio_fifo, buf);
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
}
-void xine_demux_control_headers_done (xine_t *this) {
+void xine_demux_control_headers_done (xine_stream_t *stream) {
buf_element_t *buf;
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
buf->type = BUF_CONTROL_HEADERS_DONE;
- this->video_fifo->put (this->video_fifo, buf);
+ stream->video_fifo->put (stream->video_fifo, buf);
- if (this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ if (stream->audio_fifo) {
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_HEADERS_DONE;
- this->audio_fifo->put (this->audio_fifo, buf);
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
}
-void xine_demux_control_start( xine_t *this ) {
+void xine_demux_control_start( xine_stream_t *stream ) {
buf_element_t *buf;
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
buf->type = BUF_CONTROL_START;
- this->video_fifo->put (this->video_fifo, buf);
+ stream->video_fifo->put (stream->video_fifo, buf);
- if (this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ if (stream->audio_fifo) {
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_START;
- this->audio_fifo->put (this->audio_fifo, buf);
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
}
-void xine_demux_control_end( xine_t *this, uint32_t flags ) {
+void xine_demux_control_end( xine_stream_t *stream, uint32_t flags ) {
buf_element_t *buf;
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
buf->type = BUF_CONTROL_END;
buf->decoder_flags = flags;
- this->video_fifo->put (this->video_fifo, buf);
+ stream->video_fifo->put (stream->video_fifo, buf);
- if (this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ if (stream->audio_fifo) {
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_END;
buf->decoder_flags = flags;
- this->audio_fifo->put (this->audio_fifo, buf);
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
}
diff --git a/src/xine-engine/events.c b/src/xine-engine/events.c
index c41486550..1e2c11965 100644
--- a/src/xine-engine/events.c
+++ b/src/xine-engine/events.c
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2000-2001 the xine project
+ * Copyright (C) 2000-2002 the xine project
*
- * This file is part of xine, a unix video player.
+ * 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
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id:
+ * $Id: events.c,v 1.10 2002/10/14 15:47:33 guenter Exp $
*
* Event handling functions
*
@@ -29,88 +29,185 @@
#include "xine_internal.h"
-int xine_register_event_listener (xine_t *this,
- xine_event_listener_cb_t listener,
- void *user_data) {
- /* Ensure the listener is non-NULL */
- if(listener == NULL) {
- return 0;
+xine_event_t *xine_event_get (xine_event_queue_t *queue) {
+
+ xine_event_t *event;
+
+ pthread_mutex_lock (&queue->lock);
+
+ event = (xine_event_t *) xine_list_first_content (queue->events);
+ if (event)
+ xine_list_delete_current (queue->events);
+
+ pthread_mutex_unlock (&queue->lock);
+
+ return event;
+}
+
+xine_event_t *xine_event_wait (xine_event_queue_t *queue) {
+
+ xine_event_t *event;
+
+ pthread_mutex_lock (&queue->lock);
+
+ while (!(event = (xine_event_t *) xine_list_first_content (queue->events))) {
+ pthread_cond_wait (&queue->new_event, &queue->lock);
}
- pthread_mutex_lock(&this->event_lock);
- /* Check we hava a slot free */
- if(this->num_event_listeners < XINE_MAX_EVENT_LISTENERS) {
+ xine_list_delete_current (queue->events);
+
+ pthread_mutex_unlock (&queue->lock);
+
+ return event;
+}
+
+void xine_event_free (xine_event_t *event) {
+ free (event->data);
+ free (event);
+}
+
+void xine_event_send (xine_stream_t *stream, const xine_event_t *event) {
+
+ xine_event_queue_t *queue;
+
+ pthread_mutex_lock (&stream->event_queues_lock);
+
+ queue = (xine_event_queue_t *)xine_list_first_content (stream->event_queues);
+
+ while (queue) {
+
+ xine_event_t *cevent;
+
+ cevent = malloc (sizeof (xine_event_t));
+ cevent->type = event->type;
+ cevent->stream = event->stream;
+ cevent->data_length = event->data_length;
+ cevent->data = malloc (event->data_length);
+ memcpy (cevent->data, event->data, event->data_length);
- this->event_listeners[this->num_event_listeners] = listener;
- this->event_listener_user_data[this->num_event_listeners] = user_data;
+ pthread_mutex_lock (&queue->lock);
+ xine_list_append_content (queue->events, cevent);
+ pthread_cond_signal (&queue->new_event);
+ pthread_mutex_unlock (&queue->lock);
+
+ queue=(xine_event_queue_t *)xine_list_next_content (stream->event_queues);
+ }
+
+ pthread_mutex_unlock (&stream->event_queues_lock);
+}
+
+
+xine_event_queue_t *xine_event_new_queue (xine_stream_t *stream) {
+
+ xine_event_queue_t *queue;
- this->num_event_listeners++;
+ queue = malloc (sizeof (xine_event_queue_t));
- pthread_mutex_unlock(&this->event_lock);
- return 1;
- }
+ pthread_mutex_init (&queue->lock, NULL);
+ pthread_cond_init (&queue->new_event, NULL);
+ queue->events = xine_list_new ();
+ queue->stream = stream;
- pthread_mutex_unlock(&this->event_lock);
- return 0;
+ pthread_mutex_lock (&stream->event_queues_lock);
+ xine_list_append_content (stream->event_queues, queue);
+ pthread_mutex_unlock (&stream->event_queues_lock);
+
+ return queue;
}
-void xine_send_event(xine_t *this, xine_event_t *event) {
- uint16_t i;
+void xine_event_dispose_queue (xine_event_queue_t *queue) {
+
+ xine_stream_t *stream = queue->stream;
+ xine_event_t *event;
+ xine_event_t qevent;
+ xine_event_queue_t *q;
+
+ pthread_mutex_lock (&stream->event_queues_lock);
+
+ q = (xine_event_queue_t *) xine_list_first_content (stream->event_queues);
+
+ while (q && (q != queue))
+ q = (xine_event_queue_t *) xine_list_next_content (stream->event_queues);
+
+ if (!q) {
+ printf ("events: tried to dispose queue which is not in list\n");
+
+ pthread_mutex_unlock (&stream->event_queues_lock);
+ return;
+ }
+
+ xine_list_delete_current (stream->event_queues);
+ pthread_mutex_unlock (&stream->event_queues_lock);
+
+ /*
+ * send quit event
+ */
- pthread_mutex_lock(&this->event_lock);
- while (this->event_pending[event->type])
- /* there is already one event of that type around */
- pthread_cond_wait(&this->event_handled, &this->event_lock);
- this->event_pending[event->type] = 1;
- pthread_mutex_unlock(&this->event_lock);
+ qevent.type = XINE_EVENT_QUIT;
+ qevent.data_length = 0;
+
+ pthread_mutex_lock (&queue->lock);
+ xine_list_append_content (queue->events, &event);
+ pthread_cond_signal (&queue->new_event);
+ pthread_mutex_unlock (&queue->lock);
+
+ /*
+ * join listener thread, if any
+ */
- /* Iterate through all event handlers */
- for(i=0; i < this->num_event_listeners; i++) {
- (this->event_listeners[i]) ((void *)this->event_listener_user_data[i], event);
+ if (queue->listener_thread) {
+ void *p;
+ pthread_join (*queue->listener_thread, &p);
}
- this->event_pending[event->type] = 0;
- pthread_cond_signal(&this->event_handled);
+ /*
+ * clean up pending events
+ */
+
+ while ( (event = xine_event_get (queue)) ) {
+ xine_event_free (event);
+ }
+
+ free (queue);
}
-int xine_remove_event_listener(xine_t *this,
- xine_event_listener_cb_t listener) {
- uint16_t i, found, pending;
-
- found = 1;
-
- pthread_mutex_lock(&this->event_lock);
- /* wait for any pending events */
- do {
- pending = 0;
- for (i = 0; i < XINE_MAX_EVENT_TYPES; i++)
- pending += this->event_pending[i];
- if (pending)
- pthread_cond_wait(&this->event_handled, &this->event_lock);
- } while (pending);
-
- i = 0;
- /* Attempt to find the listener */
- while((found == 1) && (i < this->num_event_listeners)) {
- if(this->event_listeners[i] == listener) {
- /* Set found flag */
- found = 0;
-
- this->event_listeners[i] = NULL;
-
- /* If possible, move the last listener to the hole thats left */
- if(this->num_event_listeners > 1) {
- this->event_listeners[i] = this->event_listeners[this->num_event_listeners - 1];
- this->event_listener_user_data[i] = this->event_listener_user_data[this->num_event_listeners - 1];
- this->event_listeners[this->num_event_listeners - 1] = NULL;
- }
-
- this->num_event_listeners --;
- }
-
- i++;
+
+static void *listener_loop (void *queue_gen) {
+
+ xine_event_queue_t *queue = (xine_event_queue_t *) queue_gen;
+ int running = 1;
+
+ while (running) {
+
+ xine_event_t *event;
+
+ event = xine_event_wait (queue);
+
+ if (event->type == XINE_EVENT_QUIT)
+ running = 0;
+ else
+ queue->callback (queue->user_data, event);
+
+ xine_event_free (event);
}
- pthread_mutex_unlock(&this->event_lock);
- return found;
+ pthread_exit(NULL);
+}
+
+
+void xine_event_create_listener_thread (xine_event_queue_t *queue,
+ xine_event_listener_cb_t callback,
+ void *user_data) {
+ int err;
+
+ queue->listener_thread = malloc (sizeof (pthread_t));
+ queue->callback = callback;
+ queue->user_data = user_data;
+
+ if ((err = pthread_create (queue->listener_thread,
+ NULL, listener_loop, queue)) != 0) {
+ fprintf (stderr, "events: can't create new thread (%s)\n",
+ strerror(err));
+ abort();
+ }
}
diff --git a/src/xine-engine/events.h b/src/xine-engine/events.h
deleted file mode 100644
index b96416694..000000000
--- a/src/xine-engine/events.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2000-2001 the xine project
- *
- * Copyright (C) Rich Wareham <richwareham@users.sourceforge.net> - July 2001
- *
- * This file is part of xine, a unix 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
- *
- */
-
-#ifndef HAVE_EVENTS_H
-#define HAVE_EVENTS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <inttypes.h>
-
-/*
- * This file defines types for many events which can be sent in xine.
- */
-
-/* event types */
-
-#define XINE_EVENT_MOUSE_BUTTON 1
-#define XINE_EVENT_MOUSE_MOVE 2
-#define XINE_EVENT_SPU_BUTTON 3
-#define XINE_EVENT_SPU_CLUT 4
-#define XINE_EVENT_UI_CHANNELS_CHANGED 5 /* inform ui that new channel info is available */
-#define XINE_EVENT_UI_SET_TITLE 6 /* request title display change in ui */
-#define XINE_EVENT_INPUT_MENU1 7
-#define XINE_EVENT_INPUT_MENU2 8
-#define XINE_EVENT_INPUT_MENU3 9
-#define XINE_EVENT_INPUT_UP 10
-#define XINE_EVENT_INPUT_DOWN 11
-#define XINE_EVENT_INPUT_LEFT 12
-#define XINE_EVENT_INPUT_RIGHT 13
-#define XINE_EVENT_INPUT_SELECT 14
-#define XINE_EVENT_PLAYBACK_FINISHED 15
-#define XINE_EVENT_BRANCHED 16
-#define XINE_EVENT_NEED_NEXT_MRL 17
-#define XINE_EVENT_INPUT_NEXT 18
-#define XINE_EVENT_INPUT_PREVIOUS 19
-#define XINE_EVENT_INPUT_ANGLE_NEXT 20
-#define XINE_EVENT_INPUT_ANGLE_PREVIOUS 21
-#define XINE_EVENT_SPU_FORCEDISPLAY 22
-#define XINE_EVENT_FRAME_CHANGE 23
-#define XINE_EVENT_CLOSED_CAPTION 24
-#define XINE_EVENT_INPUT_BUTTON_FORCE 25
-#define XINE_EVENT_INPUT_MENU4 26
-#define XINE_EVENT_INPUT_MENU5 27
-#define XINE_EVENT_INPUT_MENU6 28
-#define XINE_EVENT_INPUT_MENU7 29
-
-#define XINE_EVENT_INPUT_NUMBER_0 30
-#define XINE_EVENT_INPUT_NUMBER_1 31
-#define XINE_EVENT_INPUT_NUMBER_2 32
-#define XINE_EVENT_INPUT_NUMBER_3 33
-#define XINE_EVENT_INPUT_NUMBER_4 34
-#define XINE_EVENT_INPUT_NUMBER_5 35
-#define XINE_EVENT_INPUT_NUMBER_6 36
-#define XINE_EVENT_INPUT_NUMBER_7 37
-#define XINE_EVENT_INPUT_NUMBER_8 38
-#define XINE_EVENT_INPUT_NUMBER_9 39
-#define XINE_EVENT_INPUT_NUMBER_10_ADD 40
-
-#define XINE_EVENT_ASPECT_CHANGE 41 /* Generally should be viewed as a hint to the GUI */
-#define XINE_EVENT_OUTPUT_VIDEO 42
-#define XINE_EVENT_OUTPUT_NO_VIDEO 43
-
-
-/*
- * generic event type.
- */
-typedef struct {
- uint32_t type; /* The event type (determines remainder of struct) */
-
- /* Event dependent data goes after this. */
-} xine_event_t;
-
-/*
- * input events
- */
-typedef struct {
- xine_event_t event;
- uint8_t button; /* Generally 1 = left, 2 = mid, 3 = right */
- uint16_t x,y; /* In Image space */
-} xine_input_event_t;
-
-/*
- * Menu events
- */
-typedef struct {
- xine_event_t event;
- uint8_t button; /* Generally 1 = left, 2 = mid, 3 = right */
- uint16_t status; /* 0:no status, 1:selected, 2:actioned */
- uint8_t command[8]; /* DVD virtual machine command. */
-} xine_menu_event_t;
-
-/*
- * SPU event - send control events to the spu decoder
- */
-typedef struct {
- xine_event_t event;
- void *data;
-} xine_spu_event_t;
-
-/*
- * UI event - send information to/from UI.
- */
-
-typedef struct {
- xine_event_t event;
- void *data;
- uint32_t data_len;
- int handled;
-} xine_ui_event_t;
-
-/*
- * next_mrl
- */
-typedef struct {
- xine_event_t event;
- char *mrl;
- int handled;
-} xine_next_mrl_event_t;
-
-/*
- * notify frame change
- */
-typedef struct {
- xine_event_t event;
- int width;
- int height;
- int aspect;
-} xine_frame_change_event_t;
-
-/*
- * closed caption
- */
-typedef struct {
- xine_event_t event;
- uint8_t *buffer;
- uint32_t buf_len;
- int64_t pts;
- uint32_t scr;
-} xine_closed_caption_event_t;
-
-/*
- * Aspect ratio change (suggested)
- */
-typedef struct {
- xine_event_t event;
- int ratio_code;
- int scale_permission;
-} xine_aspect_ratio_event_t;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAVE_EVENTS_H */
-
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index e248a2777..0bc17c9ff 100644
--- a/src/xine-engine/load_plugins.c
+++ b/src/xine-engine/load_plugins.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: load_plugins.c,v 1.98 2002/09/22 14:29:40 mroi Exp $
+ * $Id: load_plugins.c,v 1.99 2002/10/14 15:47:37 guenter Exp $
*
*
* Load input/demux/audio_out/video_out/codec plugins
@@ -135,11 +135,13 @@ static void _insert_plugin (xine_t *this,
}
entry = xine_xmalloc(sizeof(plugin_node_t));
- entry->filename = _strclone(filename);
- entry->info = xine_xmalloc(sizeof(plugin_info_t));
- *(entry->info) = *info;
- entry->info->id = _strclone(info->id);
- entry->info->init = NULL;
+ entry->filename = _strclone(filename);
+ entry->info = xine_xmalloc(sizeof(plugin_info_t));
+ *(entry->info) = *info;
+ entry->info->id = _strclone(info->id);
+ entry->info->init = NULL;
+ entry->plugin_class = NULL;
+ entry->ref = 0;
switch (info->type){
@@ -188,7 +190,7 @@ static void _insert_plugin (xine_t *this,
}
-static plugin_catalog_t *_empty_catalog(void){
+static plugin_catalog_t *_new_catalog(void){
plugin_catalog_t *catalog;
@@ -201,6 +203,8 @@ static plugin_catalog_t *_empty_catalog(void){
catalog->aout = xine_list_new();
catalog->vout = xine_list_new();
+ pthread_mutex_init (&catalog->lock, NULL);
+
return catalog;
}
@@ -328,9 +332,9 @@ static void collect_plugins(xine_t *this, char *path){
* generic 2nd stage plugin loader
*/
-static void *_load_plugin(xine_t *this,
- char *filename, plugin_info_t *target,
- void *data) {
+static void *_load_plugin_class(xine_t *this,
+ char *filename, plugin_info_t *target,
+ void *data) {
void *lib;
@@ -385,7 +389,7 @@ static void load_plugins(xine_t *this) {
node->info->id, node->filename);
#endif
- node->plugin = _load_plugin(this, node->filename, node->info, NULL);
+ node->plugin_class = _load_plugin_class (this, node->filename, node->info, NULL);
node = xine_list_next_content (this->plugin_catalog->input);
}
@@ -402,7 +406,7 @@ static void load_plugins(xine_t *this) {
node->info->id, node->filename);
#endif
- node->plugin = _load_plugin(this, node->filename, node->info, NULL);
+ node->plugin_class = _load_plugin_class (this, node->filename, node->info, NULL);
node = xine_list_next_content (this->plugin_catalog->demux);
}
@@ -585,7 +589,7 @@ void scan_plugins (xine_t *this) {
abort();
}
- this->plugin_catalog = _empty_catalog();
+ this->plugin_catalog = _new_catalog();
/* TODO: add more plugin dir(s), maybe ~/.xine/plugins or /usr/local/... */
collect_plugins(this, XINE_PLUGINDIR);
@@ -594,7 +598,108 @@ void scan_plugins (xine_t *this) {
map_decoders (this);
}
-static const char **_xine_get_featured_input_plugin_ids(xine_t *this, int feature) {
+/*
+ * input / demuxer plugin loading
+ */
+
+input_plugin_t *find_input_plugin (xine_stream_t *stream, const char *mrl) {
+
+ xine_t *xine = stream->xine;
+ plugin_catalog_t *catalog = xine->plugin_catalog;
+ plugin_node_t *node;
+
+ pthread_mutex_lock (&catalog->lock);
+
+ node = xine_list_first_content (catalog->input);
+ while (node) {
+ input_plugin_t *plugin;
+
+ if ((plugin = node->info->open (node->plugin_class, stream, mrl))) {
+ pthread_mutex_unlock (&catalog->lock);
+ return plugin;
+ }
+
+ node = xine_list_next_content (stream->xine->plugin_catalog->input);
+ }
+
+ pthread_mutex_unlock (&catalog->lock);
+
+ return NULL;
+}
+
+static demux_plugin_t *probe_demux (xine_stream_t *stream, int method1, int method2,
+ input_plugin_t *input) {
+
+ int i;
+ int methods[3];
+ xine_t *xine = stream->xine;
+ plugin_catalog_t *catalog = xine->plugin_catalog;
+
+ methods[0] = method1;
+ methods[1] = method2;
+ methods[2] = -1;
+
+ if (methods[0] == -1) {
+ printf ("load_plugins: probe_demux method1 = %d is not allowed \n", method1);
+ abort();
+ }
+
+ i = 0;
+ while (methods[i] != -1) {
+
+ plugin_node_t *node;
+
+ stream->content_detection_method = methods[i];
+
+ pthread_mutex_lock (&catalog->lock);
+
+ node = xine_list_first_content (catalog->demux);
+
+ while (node) {
+ demux_plugin_t *plugin;
+
+ if ((plugin = node->info->open (node->plugin_class, stream, input))) {
+ pthread_mutex_unlock (&catalog->lock);
+ return plugin;
+ }
+
+ node = xine_list_next_content (stream->xine->plugin_catalog->demux);
+ }
+
+ pthread_mutex_unlock (&catalog->lock);
+
+ i++;
+ }
+
+ return NULL;
+}
+
+demux_plugin_t *find_demux_plugin (xine_stream_t *stream, input_plugin_t *input) {
+
+ switch (stream->xine->demux_strategy) {
+
+ case XINE_DEMUX_DEFAULT_STRATEGY:
+ return probe_demux (stream, METHOD_BY_CONTENT, METHOD_BY_EXTENSION, input);
+
+ case XINE_DEMUX_REVERT_STRATEGY:
+ return probe_demux (stream, METHOD_BY_EXTENSION, METHOD_BY_CONTENT, input);
+
+ case XINE_DEMUX_CONTENT_STRATEGY:
+ return probe_demux (stream, METHOD_BY_CONTENT, -1, input);
+
+ case XINE_DEMUX_EXTENSION_STRATEGY:
+ return probe_demux (stream, METHOD_BY_EXTENSION, -1, input);
+
+ default:
+ printf ("load_plugins: unknown content detection strategy %d\n",
+ stream->xine->demux_strategy);
+ abort();
+ }
+
+ return NULL;
+}
+
+const char *const *xine_get_autoplay_input_plugin_ids(xine_t *this) {
plugin_catalog_t *catalog;
int i;
@@ -602,13 +707,15 @@ static const char **_xine_get_featured_input_plugin_ids(xine_t *this, int featur
catalog = this->plugin_catalog;
+ pthread_mutex_lock (&catalog->lock);
+
i = 0;
node = xine_list_first_content (catalog->input);
while (node) {
- input_plugin_t *ip;
+ input_class_t *ic;
- ip = (input_plugin_t *) node->plugin;
- if (ip->get_capabilities(ip) & feature) {
+ ic = (input_class_t *) node->plugin_class;
+ if (ic->get_autoplay_list) {
catalog->ids[i] = node->info->id;
@@ -619,20 +726,45 @@ static const char **_xine_get_featured_input_plugin_ids(xine_t *this, int featur
catalog->ids[i] = NULL;
+ pthread_mutex_unlock (&catalog->lock);
+
return catalog->ids;
}
-const char *const *xine_get_autoplay_input_plugin_ids(xine_t *this) {
+const char *const *xine_get_browsable_input_plugin_ids(xine_t *this) {
- return (_xine_get_featured_input_plugin_ids(this, INPUT_CAP_AUTOPLAY));
-}
-const char *const *xine_get_browsable_input_plugin_ids(xine_t *this) {
+ plugin_catalog_t *catalog;
+ int i;
+ plugin_node_t *node;
+
+ catalog = this->plugin_catalog;
- return (_xine_get_featured_input_plugin_ids(this, INPUT_CAP_GET_DIR));
+ pthread_mutex_lock (&catalog->lock);
+
+ i = 0;
+ node = xine_list_first_content (catalog->input);
+ while (node) {
+ input_class_t *ic;
+
+ ic = (input_class_t *) node->plugin_class;
+ if (ic->get_dir) {
+
+ catalog->ids[i] = node->info->id;
+
+ i++;
+ }
+ node = xine_list_next_content (catalog->input);
+ }
+
+ catalog->ids[i] = NULL;
+
+ pthread_mutex_unlock (&catalog->lock);
+
+ return catalog->ids;
}
-const char *xine_get_input_plugin_description(xine_t *this, const char *plugin_id) {
+const char *xine_get_input_plugin_description (xine_t *this, const char *plugin_id) {
plugin_catalog_t *catalog;
plugin_node_t *node;
@@ -644,9 +776,9 @@ const char *xine_get_input_plugin_description(xine_t *this, const char *plugin_i
if (!strcasecmp (node->info->id, plugin_id)) {
- input_plugin_t *ip = (input_plugin_t *) node->plugin;
+ input_class_t *ic = (input_class_t *) node->plugin_class;
- return ip->get_description(ip);
+ return ic->get_description(ic);
}
node = xine_list_next_content (catalog->input);
}
@@ -657,32 +789,61 @@ const char *xine_get_input_plugin_description(xine_t *this, const char *plugin_i
* video out plugins section
*/
+static xine_vo_driver_t *_load_video_driver (xine_t *this, plugin_node_t *node,
+ void *data) {
+
+ xine_vo_driver_t *driver;
+
+ if (!node->plugin_class)
+ node->plugin_class = _load_plugin_class (this, node->filename, node->info, data);
+
+ if (!node->plugin_class)
+ return NULL;
+
+ driver = (xine_vo_driver_t *) node->info->open (node->plugin_class, NULL, data);
+
+ if (driver) {
+ driver->node = node;
+ node->ref ++;
+ } else {
+
+ /* FIXME
+ if (!node->ref)
+ unload class
+ */
+ }
+
+ return driver;
+}
+
xine_vo_driver_t *xine_open_video_driver (xine_t *this,
- const char *id,
- int visual_type, void *visual) {
+ const char *id,
+ int visual_type, void *visual) {
plugin_node_t *node;
xine_vo_driver_t *driver;
vo_info_t *vo_info;
+ plugin_catalog_t *catalog = this->plugin_catalog;
driver = NULL;
- node = xine_list_first_content (this->plugin_catalog->vout);
+ pthread_mutex_lock (&catalog->lock);
+
+ node = xine_list_first_content (catalog->vout);
while (node) {
vo_info = node->info->special_info;
if (vo_info->visual_type == visual_type) {
if (id) {
if (!strcasecmp (node->info->id, id)) {
- driver = (xine_vo_driver_t*)_load_plugin (this, node->filename,
- node->info, visual);
+ driver = _load_video_driver (this, node, visual);
break;
}
} else {
- driver = (xine_vo_driver_t*)_load_plugin (this, node->filename,
- node->info, visual);
+ driver = _load_video_driver (this, node, visual);
+
if (driver) {
xine_cfg_entry_t entry;
@@ -699,12 +860,14 @@ xine_vo_driver_t *xine_open_video_driver (xine_t *this,
}
}
- node = xine_list_next_content (this->plugin_catalog->vout);
+ node = xine_list_next_content (catalog->vout);
}
if (!driver)
printf ("load_plugins: failed to load video output plugin <%s>\n", id);
+ pthread_mutex_unlock (&catalog->lock);
+
return driver;
}
@@ -720,6 +883,8 @@ const char *const *xine_list_audio_output_plugins (xine_t *this) {
catalog = this->plugin_catalog;
+ pthread_mutex_lock (&catalog->lock);
+
i = 0;
node = xine_list_first_content (catalog->aout);
while (node) {
@@ -733,6 +898,8 @@ const char *const *xine_list_audio_output_plugins (xine_t *this) {
catalog->ids[i] = NULL;
+ pthread_mutex_unlock (&catalog->lock);
+
return catalog->ids;
}
@@ -744,6 +911,8 @@ const char *const *xine_list_video_output_plugins (xine_t *this) {
catalog = this->plugin_catalog;
+ pthread_mutex_lock (&catalog->lock);
+
i = 0;
node = xine_list_first_content (catalog->vout);
while (node) {
@@ -757,15 +926,47 @@ const char *const *xine_list_video_output_plugins (xine_t *this) {
catalog->ids[i] = NULL;
+ pthread_mutex_unlock (&catalog->lock);
+
return catalog->ids;
}
+static xine_ao_driver_t *_load_audio_driver (xine_t *this, plugin_node_t *node,
+ void *data) {
+
+ xine_ao_driver_t *driver;
+
+ if (!node->plugin_class)
+ node->plugin_class = _load_plugin_class (this, node->filename, node->info, data);
+
+ if (!node->plugin_class)
+ return NULL;
+
+ driver = (xine_ao_driver_t *) node->info->open (node->plugin_class, NULL, data);
+
+ if (driver) {
+ driver->node = node;
+ node->ref ++;
+ } else {
+
+ /* FIXME
+ if (!node->ref)
+ unload class
+ */
+ }
+
+ return driver;
+}
+
xine_ao_driver_t *xine_open_audio_driver (xine_t *this, const char *id,
- void *data) {
+ void *data) {
plugin_node_t *node;
xine_ao_driver_t *driver;
ao_info_t *ao_info;
+ plugin_catalog_t *catalog = this->plugin_catalog;
+
+ pthread_mutex_lock (&catalog->lock);
driver = NULL;
@@ -776,11 +977,11 @@ xine_ao_driver_t *xine_open_audio_driver (xine_t *this, const char *id,
if (id) {
if (!strcasecmp(node->info->id, id)) {
- driver = (xine_ao_driver_t*)_load_plugin(this, node->filename, node->info, data);
+ driver = _load_audio_driver (this, node, data);
break;
}
} else {
- driver = (xine_ao_driver_t*)_load_plugin (this, node->filename, node->info, data);
+ driver = _load_audio_driver (this, node, data);
if (driver) {
xine_cfg_entry_t entry;
@@ -805,9 +1006,19 @@ xine_ao_driver_t *xine_open_audio_driver (xine_t *this, const char *id,
else
printf ("load_plugins: audio output auto-probing didn't find any usable audio driver.\n");
}
+
+ pthread_mutex_unlock (&catalog->lock);
+
return driver;
}
+void xine_close_audio_driver (xine_t *this, xine_ao_driver_t *driver) {
+
+ /* FIXME : implement */
+
+}
+
+
/*
* get autoplay mrl list from input plugin
*/
@@ -825,14 +1036,12 @@ char **xine_get_autoplay_mrls (xine_t *this, const char *plugin_id,
if (!strcasecmp (node->info->id, plugin_id)) {
- input_plugin_t *ip = (input_plugin_t *) node->plugin;
+ input_class_t *ic = (input_class_t *) node->plugin_class;
- if (!( ip->get_capabilities(ip) & INPUT_CAP_AUTOPLAY))
+ if (!ic->get_autoplay_list)
return NULL;
- /* this->cur_input_plugin = ip; FIXME: needed? */
-
- return ip->get_autoplay_list (ip, num_mrls);
+ return ic->get_autoplay_list (ic, num_mrls);
}
node = xine_list_next_content (catalog->input);
}
@@ -855,117 +1064,223 @@ xine_mrl_t **xine_get_browse_mrls (xine_t *this, const char *plugin_id,
if (!strcasecmp (node->info->id, plugin_id)) {
- input_plugin_t *ip = (input_plugin_t *) node->plugin;
+ input_class_t *ic = (input_class_t *) node->plugin_class;
- if (!( ip->get_capabilities(ip) & INPUT_CAP_GET_DIR))
+ if (!ic->get_dir)
return NULL;
- return ip->get_dir (ip, start_mrl, num_mrls);
+ return ic->get_dir (ic, start_mrl, num_mrls);
}
node = xine_list_next_content (catalog->input);
}
return NULL;
}
-video_decoder_t *get_video_decoder (xine_t *this, uint8_t stream_type) {
+video_decoder_t *get_video_decoder (xine_stream_t *stream, uint8_t stream_type) {
- plugin_node_t *node;
- int i, j;
+ plugin_node_t *node;
+ int i, j;
+ plugin_catalog_t *catalog = stream->xine->plugin_catalog;
#ifdef LOG
printf ("load_plugins: looking for video decoder for streamtype %02x\n",
stream_type);
#endif
+ pthread_mutex_lock (&catalog->lock);
+
for (i = 0; i < PLUGINS_PER_TYPE; i++) {
- node = this->plugin_catalog->video_decoder_map[stream_type][i];
+
+ video_decoder_t *vd=NULL;
+
+ node = catalog->video_decoder_map[stream_type][i];
- if (!node)
+ if (!node) {
+ pthread_mutex_unlock (&catalog->lock);
return NULL;
+ }
- if (!node->plugin)
- node->plugin = _load_plugin(this, node->filename, node->info, NULL);
+ if (!node->plugin_class)
+ node->plugin_class = _load_plugin_class (stream->xine, node->filename,
+ node->info, NULL);
- if (node->plugin)
- return node->plugin;
- else {
+ if (!node->plugin_class) {
/* remove non working plugin from catalog */
for (j = i + 1; j < PLUGINS_PER_TYPE; j++)
- this->plugin_catalog->video_decoder_map[stream_type][j - 1] =
- this->plugin_catalog->video_decoder_map[stream_type][j];
- this->plugin_catalog->video_decoder_map[stream_type][PLUGINS_PER_TYPE] = NULL;
+ catalog->video_decoder_map[stream_type][j - 1] =
+ catalog->video_decoder_map[stream_type][j];
+ catalog->video_decoder_map[stream_type][PLUGINS_PER_TYPE] = NULL;
i--;
+ pthread_mutex_unlock (&catalog->lock);
+ return NULL;
}
+
+ vd = (video_decoder_t *) node->info->open (node->plugin_class, stream, NULL);
+
+ if (vd) {
+ vd->node = node;
+ node->ref ++;
+ }
+
+ pthread_mutex_unlock (&catalog->lock);
+ return vd;
}
+
+ pthread_mutex_unlock (&catalog->lock);
return NULL;
}
-audio_decoder_t *get_audio_decoder (xine_t *this, uint8_t stream_type) {
+void free_video_decoder (xine_stream_t *stream, video_decoder_t *vd) {
+ plugin_catalog_t *catalog = stream->xine->plugin_catalog;
+ plugin_node_t *node = vd->node;
+
+ pthread_mutex_lock (&catalog->lock);
+
+ vd->dispose (vd);
+
+ node->ref--;
+ /* FIXME: unload plugin if no-longer used */
+
+ pthread_mutex_unlock (&catalog->lock);
+}
+
+
+audio_decoder_t *get_audio_decoder (xine_stream_t *stream, uint8_t stream_type) {
- plugin_node_t *node;
- int i, j;
+ plugin_node_t *node;
+ int i, j;
+ plugin_catalog_t *catalog = stream->xine->plugin_catalog;
#ifdef LOG
printf ("load_plugins: looking for audio decoder for streamtype %02x\n",
stream_type);
#endif
+ pthread_mutex_lock (&catalog->lock);
+
for (i = 0; i < PLUGINS_PER_TYPE; i++) {
- node = this->plugin_catalog->audio_decoder_map[stream_type][i];
- if (!node)
+ audio_decoder_t *ad;
+
+ node = catalog->audio_decoder_map[stream_type][i];
+
+ if (!node) {
+ pthread_mutex_unlock (&catalog->lock);
return NULL;
+ }
- if (!node->plugin)
- node->plugin = _load_plugin(this, node->filename, node->info, NULL);
+ if (!node->plugin_class)
+ node->plugin_class = _load_plugin_class (stream->xine, node->filename,
+ node->info, NULL);
- if (node->plugin)
- return node->plugin;
- else {
+ if (!node->plugin_class) {
/* remove non working plugin from catalog */
for (j = i + 1; j < PLUGINS_PER_TYPE; j++)
- this->plugin_catalog->audio_decoder_map[stream_type][j - 1] =
- this->plugin_catalog->audio_decoder_map[stream_type][j];
- this->plugin_catalog->audio_decoder_map[stream_type][PLUGINS_PER_TYPE] = NULL;
+ catalog->audio_decoder_map[stream_type][j - 1] =
+ catalog->audio_decoder_map[stream_type][j];
+ catalog->audio_decoder_map[stream_type][PLUGINS_PER_TYPE] = NULL;
i--;
+ pthread_mutex_unlock (&catalog->lock);
+ return NULL;
+ }
+
+ ad = (audio_decoder_t *) node->info->open (node->plugin_class, stream, NULL);
+
+ if (ad) {
+ ad->node = node;
+ node->ref ++;
}
+
+ pthread_mutex_unlock (&catalog->lock);
+ return ad;
}
+
+ pthread_mutex_unlock (&catalog->lock);
return NULL;
}
-spu_decoder_t *get_spu_decoder (xine_t *this, uint8_t stream_type) {
+void free_audio_decoder (xine_stream_t *stream, audio_decoder_t *ad) {
+ plugin_catalog_t *catalog = stream->xine->plugin_catalog;
+ plugin_node_t *node = ad->node;
+
+ pthread_mutex_lock (&catalog->lock);
+
+ ad->dispose (ad);
- plugin_node_t *node;
- int i, j;
+ node->ref--;
+ /* FIXME: unload plugin if no-longer used */
+
+ pthread_mutex_unlock (&catalog->lock);
+}
+
+
+spu_decoder_t *get_spu_decoder (xine_stream_t *stream, uint8_t stream_type) {
+
+ plugin_node_t *node;
+ int i, j;
+ plugin_catalog_t *catalog = stream->xine->plugin_catalog;
#ifdef LOG
printf ("load_plugins: looking for spu decoder for streamtype %02x\n",
stream_type);
#endif
+ pthread_mutex_lock (&catalog->lock);
+
for (i = 0; i < PLUGINS_PER_TYPE; i++) {
- node = this->plugin_catalog->spu_decoder_map[stream_type][i];
+ spu_decoder_t *sd;
+
+ node = catalog->spu_decoder_map[stream_type][i];
- if (!node)
+ if (!node) {
+ pthread_mutex_unlock (&catalog->lock);
return NULL;
+ }
- if (!node->plugin)
- node->plugin = _load_plugin(this, node->filename, node->info, NULL);
+ if (!node->plugin_class)
+ node->plugin_class = _load_plugin_class (stream->xine, node->filename,
+ node->info, NULL);
- if (node->plugin)
- return node->plugin;
- else {
+ if (!node->plugin_class) {
/* remove non working plugin from catalog */
for (j = i + 1; j < PLUGINS_PER_TYPE; j++)
- this->plugin_catalog->spu_decoder_map[stream_type][j - 1] =
- this->plugin_catalog->spu_decoder_map[stream_type][j];
- this->plugin_catalog->spu_decoder_map[stream_type][PLUGINS_PER_TYPE] = NULL;
+ catalog->spu_decoder_map[stream_type][j - 1] =
+ catalog->spu_decoder_map[stream_type][j];
+ catalog->spu_decoder_map[stream_type][PLUGINS_PER_TYPE] = NULL;
i--;
+ pthread_mutex_unlock (&catalog->lock);
+ return NULL;
+ }
+
+ sd = (spu_decoder_t *) node->info->open (node->plugin_class, stream, NULL);
+
+ if (sd) {
+ sd->node = node;
+ node->ref ++;
}
+
+ pthread_mutex_unlock (&catalog->lock);
+ return sd;
}
+
+ pthread_mutex_unlock (&catalog->lock);
return NULL;
}
+void free_spu_decoder (xine_stream_t *stream, spu_decoder_t *sd) {
+ plugin_catalog_t *catalog = stream->xine->plugin_catalog;
+ plugin_node_t *node = sd->node;
+
+ pthread_mutex_lock (&catalog->lock);
+
+ sd->dispose (sd);
+
+ node->ref--;
+ /* FIXME: unload plugin if no-longer used */
+
+ pthread_mutex_unlock (&catalog->lock);
+}
+
/*
* dispose all currently loaded plugins (shutdown)
@@ -973,7 +1288,9 @@ spu_decoder_t *get_spu_decoder (xine_t *this, uint8_t stream_type) {
void dispose_plugins (xine_t *this) {
- /* FIXME: adapt old code */
+/* FIXME */
+
+#if 0
plugin_node_t *node;
node = xine_list_first_content (this->plugin_catalog->demux);
@@ -996,7 +1313,6 @@ void dispose_plugins (xine_t *this) {
node = xine_list_next_content (this->plugin_catalog->input);
}
-#if 0
for (i = 0; i < this->num_audio_decoders_loaded; i++)
this->audio_decoders_loaded[i]->dispose (this->audio_decoders_loaded[i]);
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index d189142c0..de31f1916 100644
--- a/src/xine-engine/metronom.c
+++ b/src/xine-engine/metronom.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: metronom.c,v 1.93 2002/09/05 22:29:17 mroi Exp $
+ * $Id: metronom.c,v 1.94 2002/10/14 15:47:38 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -657,7 +657,7 @@ static int metronom_sync_loop (metronom_t *this) {
scr_plugin_t** scr;
int64_t pts;
- while (((xine_t*)this->xine)->status != XINE_STATUS_QUIT) {
+ while (this->stream->status != XINE_STATUS_QUIT) {
pts = this->scr_master->get_current(this->scr_master);
for (scr = this->scr_list; scr < this->scr_list+MAX_SCR_PROVIDERS; scr++)
@@ -699,12 +699,12 @@ static void metronom_exit (metronom_t *this) {
}
-metronom_t * metronom_init (int have_audio, void *xine) {
+metronom_t * metronom_init (int have_audio, xine_stream_t *stream) {
metronom_t *this = xine_xmalloc (sizeof (metronom_t));
int err;
- this->xine = xine;
+ this->stream = stream;
this->set_audio_rate = metronom_set_audio_rate;
this->got_video_frame = metronom_got_video_frame;
this->got_audio_samples = metronom_got_audio_samples;
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
index 3fb081b37..77ec59614 100644
--- a/src/xine-engine/metronom.h
+++ b/src/xine-engine/metronom.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: metronom.h,v 1.36 2002/09/05 22:29:17 mroi Exp $
+ * $Id: metronom.h,v 1.37 2002/10/14 15:47:39 guenter Exp $
*
* metronom: general pts => virtual calculation/assoc
*
@@ -51,6 +51,7 @@ extern "C" {
#include <sys/time.h>
#include <pthread.h>
#include "video_out.h"
+#include "xine.h"
typedef struct metronom_s metronom_t ;
typedef struct scr_plugin_s scr_plugin_t;
@@ -64,11 +65,6 @@ typedef struct scr_plugin_s scr_plugin_t;
struct metronom_s {
/*
- * pointer to current xine object. a void pointer is used to avoid type declaration clash.
- */
- void *xine;
-
- /*
* called by audio output driver to inform metronom about current audio
* samplerate
*
@@ -206,6 +202,11 @@ struct metronom_s {
void (*exit) (metronom_t *this);
/*
+ * pointer to current xine stream object.
+ */
+ xine_stream_t *stream;
+
+ /*
* metronom internal stuff
*/
@@ -247,7 +248,7 @@ struct metronom_s {
int force_audio_jump;
};
-metronom_t *metronom_init (int have_audio, void *xine);
+metronom_t *metronom_init (int have_audio, xine_stream_t *stream);
/*
* metronom options
diff --git a/src/xine-engine/plugin_catalog.h b/src/xine-engine/plugin_catalog.h
index 9e166d813..fd0581488 100644
--- a/src/xine-engine/plugin_catalog.h
+++ b/src/xine-engine/plugin_catalog.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: plugin_catalog.h,v 1.5 2002/09/09 13:57:13 mroi Exp $
+ * $Id: plugin_catalog.h,v 1.6 2002/10/14 15:47:39 guenter Exp $
*
* xine-internal header: Definitions for plugin lists
*
@@ -36,26 +36,28 @@
#define PLUGINS_PER_TYPE 10
typedef struct {
- char *filename;
- plugin_info_t *info;
- void *plugin;
+ char *filename;
+ plugin_info_t *info;
+ void *plugin_class;
+ int ref; /* count instances created of this plugin */
} plugin_node_t ;
struct plugin_catalog_s {
- xine_list_t *input;
- xine_list_t *demux;
- xine_list_t *spu;
- xine_list_t *audio;
- xine_list_t *video;
- xine_list_t *aout;
- xine_list_t *vout;
+ xine_list_t *input;
+ xine_list_t *demux;
+ xine_list_t *spu;
+ xine_list_t *audio;
+ xine_list_t *video;
+ xine_list_t *aout;
+ xine_list_t *vout;
- plugin_node_t *audio_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE];
- plugin_node_t *video_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE];
- plugin_node_t *spu_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE];
+ plugin_node_t *audio_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE];
+ plugin_node_t *video_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE];
+ plugin_node_t *spu_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE];
- const char *ids[PLUGIN_MAX];
+ const char *ids[PLUGIN_MAX];
+ pthread_mutex_t lock;
};
typedef struct plugin_catalog_s plugin_catalog_t;
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index c910101f4..0464a9e69 100644
--- a/src/xine-engine/video_decoder.c
+++ b/src/xine-engine/video_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_decoder.c,v 1.99 2002/09/18 15:37:43 mroi Exp $
+ * $Id: video_decoder.c,v 1.100 2002/10/14 15:47:40 guenter Exp $
*
*/
@@ -37,28 +37,28 @@
#define VIDEO_DECODER_LOG
*/
-static spu_decoder_t* update_spu_decoder(xine_t *this, int type) {
+static spu_decoder_t* update_spu_decoder (xine_stream_t *this, int type) {
int streamtype = (type>>16) & 0xFF;
spu_decoder_t *spu_decoder = get_spu_decoder (this, streamtype);
- if (spu_decoder && this->cur_spu_decoder_plugin != spu_decoder) {
+ if (spu_decoder && this->spu_decoder_plugin != spu_decoder) {
- if (this->cur_spu_decoder_plugin)
- this->cur_spu_decoder_plugin->close (this->cur_spu_decoder_plugin);
+ if (this->spu_decoder_plugin)
+ this->spu_decoder_plugin->close (this->spu_decoder_plugin);
- this->cur_spu_decoder_plugin = spu_decoder;
+ this->spu_decoder_plugin = spu_decoder;
- this->cur_spu_decoder_plugin->init (this->cur_spu_decoder_plugin,
+ this->spu_decoder_plugin->init (this->spu_decoder_plugin,
this->video_out);
}
return spu_decoder;
}
-void *video_decoder_loop (void *this_gen) {
+void *video_decoder_loop (void *stream_gen) {
buf_element_t *buf;
- xine_t *this = (xine_t *) this_gen;
+ xine_stream_t *stream = (xine_stream_t *) stream_gen;
int running = 1;
int streamtype;
video_decoder_t *decoder;
@@ -78,18 +78,14 @@ void *video_decoder_loop (void *this_gen) {
printf ("video_decoder: getting buffer...\n");
#endif
- buf = this->video_fifo->get (this->video_fifo);
+ buf = stream->video_fifo->get (stream->video_fifo);
if (buf->input_pos)
- this->cur_input_pos = buf->input_pos;
+ stream->input_pos = buf->input_pos;
if (buf->input_length)
- this->cur_input_length = buf->input_length;
+ stream->input_length = buf->input_length;
if (buf->input_time) {
- this->cur_input_time = buf->input_time;
- pthread_mutex_lock (&this->osd_lock);
- if( this->curtime_needed_for_osd && !(--this->curtime_needed_for_osd) )
- xine_internal_osd (this, ">",90000);
- pthread_mutex_unlock (&this->osd_lock);
+ stream->input_time = buf->input_time;
}
#ifdef VIDEO_DECODER_LOG
@@ -98,28 +94,26 @@ void *video_decoder_loop (void *this_gen) {
switch (buf->type & 0xffff0000) {
case BUF_CONTROL_HEADERS_DONE:
- this->header_sent_counter++;
+ pthread_mutex_lock (&stream->counter_lock);
+ stream->header_count_video++;
+ pthread_cond_broadcast (&stream->counter_changed);
+ pthread_mutex_unlock (&stream->counter_lock);
break;
case BUF_CONTROL_START:
- if (this->cur_video_decoder_plugin) {
- this->cur_video_decoder_plugin->close (this->cur_video_decoder_plugin);
- this->cur_video_decoder_plugin = NULL;
+ if (stream->video_decoder_plugin) {
+ free_video_decoder (stream, stream->video_decoder_plugin);
+ stream->video_decoder_plugin = NULL;
}
- if (this->cur_spu_decoder_plugin) {
- this->cur_spu_decoder_plugin->close (this->cur_spu_decoder_plugin);
- this->cur_spu_decoder_plugin = NULL;
+ if (stream->spu_decoder_plugin) {
+ free_spu_decoder (stream, stream->spu_decoder_plugin);
+ stream->spu_decoder_plugin = NULL;
}
- pthread_mutex_lock (&this->finished_lock);
- this->video_finished = 0;
- this->spu_finished = 0;
-
- pthread_mutex_unlock (&this->finished_lock);
-
- this->metronom->handle_video_discontinuity (this->metronom, DISC_STREAMSTART, 0);
+ stream->metronom->handle_video_discontinuity (stream->metronom,
+ DISC_STREAMSTART, 0);
break;
case BUF_SPU_SUBP_CONTROL:
@@ -129,7 +123,7 @@ void *video_decoder_loop (void *this_gen) {
case BUF_SPU_NAV:
xine_profiler_start_count (prof_spu_decode);
- spu_decoder = update_spu_decoder(this, buf->type);
+ spu_decoder = update_spu_decoder(stream, buf->type);
if (spu_decoder) {
spu_decoder->decode_data (spu_decoder, buf);
@@ -140,120 +134,122 @@ void *video_decoder_loop (void *this_gen) {
case BUF_CONTROL_SPU_CHANNEL:
{
- xine_ui_event_t ui_event;
+ xine_event_t ui_event;
/* We use widescreen spu as the auto selection, because widescreen
* display is common. SPU decoders can choose differently if it suits
* them. */
- this->spu_channel_auto = buf->decoder_info[0];
- this->spu_channel_letterbox = buf->decoder_info[1];
- this->spu_channel_pan_scan = buf->decoder_info[2];
- if (this->spu_channel_user == -1)
- this->spu_channel = this->spu_channel_auto;
+ stream->spu_channel_auto = buf->decoder_info[0];
+ stream->spu_channel_letterbox = buf->decoder_info[1];
+ stream->spu_channel_pan_scan = buf->decoder_info[2];
+ if (stream->spu_channel_user == -1)
+ stream->spu_channel = stream->spu_channel_auto;
/* Inform UI of SPU channel changes */
- ui_event.event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
- ui_event.data = NULL;
- xine_send_event(this, &ui_event.event);
-
+ ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
+ ui_event.data_length = 0;
+
+ xine_event_send (stream, &ui_event);
}
break;
case BUF_CONTROL_END:
- if (this->cur_video_decoder_plugin) {
- this->cur_video_decoder_plugin->close (this->cur_video_decoder_plugin);
- this->cur_video_decoder_plugin = NULL;
+ if (stream->video_decoder_plugin) {
+ free_video_decoder (stream, stream->video_decoder_plugin);
+ stream->video_decoder_plugin = NULL;
}
- if (this->cur_spu_decoder_plugin) {
- this->cur_spu_decoder_plugin->close (this->cur_spu_decoder_plugin);
- this->cur_spu_decoder_plugin = NULL;
+ if (stream->spu_decoder_plugin) {
+ free_spu_decoder (stream, stream->spu_decoder_plugin);
+ stream->spu_decoder_plugin = NULL;
}
- pthread_mutex_lock (&this->finished_lock);
- this->spu_finished = 1;
-
- if (!this->video_finished ) {
- this->video_finished = 1;
-
- if (this->audio_finished) {
- if( this->playing_logo )
- buf->decoder_flags = 0;
- this->playing_logo = 0;
-
- if( buf->decoder_flags & BUF_FLAG_END_STREAM )
- xine_notify_stream_finished (this);
- }
+
+ /* wait for audio to reach this marker, if necessary */
+
+ pthread_mutex_lock (&stream->counter_lock);
+
+ stream->finished_count_video++;
+
+ printf ("video_decoder: reached end marker # %d\n",
+ stream->finished_count_video);
+
+ pthread_cond_broadcast (&stream->counter_changed);
+
+ if (stream->stream_info[XINE_STREAM_INFO_HAS_VIDEO]
+ && stream->audio_fifo) {
+
+ while (stream->finished_count_video > stream->finished_count_audio) {
+ pthread_cond_wait (&stream->counter_changed, &stream->counter_lock);
+ }
}
+
+ pthread_mutex_unlock (&stream->counter_lock);
- pthread_mutex_unlock (&this->finished_lock);
+ if (stream->stream_info[XINE_STREAM_INFO_HAS_VIDEO]) {
+ /* set engine status, send frontend notification event */
+ xine_handle_stream_end (stream,
+ buf->decoder_flags & BUF_FLAG_END_STREAM);
+ }
break;
case BUF_CONTROL_QUIT:
- if (this->cur_video_decoder_plugin) {
- this->cur_video_decoder_plugin->close (this->cur_video_decoder_plugin);
- this->cur_video_decoder_plugin = NULL;
+ if (stream->video_decoder_plugin) {
+ free_video_decoder (stream, stream->video_decoder_plugin);
+ stream->video_decoder_plugin = NULL;
}
- if (this->cur_spu_decoder_plugin) {
- this->cur_spu_decoder_plugin->close (this->cur_spu_decoder_plugin);
- this->cur_spu_decoder_plugin = NULL;
+ if (stream->spu_decoder_plugin) {
+ free_spu_decoder (stream, stream->spu_decoder_plugin);
+ stream->spu_decoder_plugin = NULL;
}
running = 0;
break;
case BUF_CONTROL_RESET_DECODER:
- if (this->cur_video_decoder_plugin) {
- this->cur_video_decoder_plugin->reset (this->cur_video_decoder_plugin);
+ if (stream->video_decoder_plugin) {
+ stream->video_decoder_plugin->reset (stream->video_decoder_plugin);
}
- if (this->cur_spu_decoder_plugin) {
- this->cur_spu_decoder_plugin->reset (this->cur_spu_decoder_plugin);
+ if (stream->spu_decoder_plugin) {
+ stream->spu_decoder_plugin->reset (stream->spu_decoder_plugin);
}
break;
case BUF_CONTROL_DISCONTINUITY:
printf ("video_decoder: discontinuity ahead\n");
- this->video_in_discontinuity = 1;
+ stream->video_in_discontinuity = 1;
- this->metronom->handle_video_discontinuity (this->metronom, DISC_RELATIVE, buf->disc_off);
+ stream->metronom->handle_video_discontinuity (stream->metronom, DISC_RELATIVE, buf->disc_off);
- this->video_in_discontinuity = 0;
+ stream->video_in_discontinuity = 0;
break;
case BUF_CONTROL_NEWPTS:
printf ("video_decoder: new pts %lld\n", buf->disc_off);
- this->video_in_discontinuity = 1;
+ stream->video_in_discontinuity = 1;
if (buf->decoder_flags & BUF_FLAG_SEEK) {
- this->metronom->handle_video_discontinuity (this->metronom, DISC_STREAMSEEK, buf->disc_off);
+ stream->metronom->handle_video_discontinuity (stream->metronom, DISC_STREAMSEEK, buf->disc_off);
} else {
- this->metronom->handle_video_discontinuity (this->metronom, DISC_ABSOLUTE, buf->disc_off);
+ stream->metronom->handle_video_discontinuity (stream->metronom, DISC_ABSOLUTE, buf->disc_off);
}
- this->video_in_discontinuity = 0;
+ stream->video_in_discontinuity = 0;
break;
case BUF_CONTROL_AUDIO_CHANNEL:
{
- xine_ui_event_t ui_event;
+ xine_event_t ui_event;
/* Inform UI of AUDIO channel changes */
- ui_event.event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
- ui_event.data = NULL;
- xine_send_event(this, &ui_event.event);
+ ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
+ ui_event.data_length = 0;
+ xine_event_send (stream, &ui_event);
}
break;
case BUF_CONTROL_NOP:
- /* Inform UI of NO_VIDEO usage */
- if(buf->decoder_flags & BUF_FLAG_NO_VIDEO) {
- xine_ui_event_t ui_event;
-
- ui_event.event.type = XINE_EVENT_OUTPUT_NO_VIDEO;
- ui_event.data = this->cur_input_plugin->get_mrl(this->cur_input_plugin);
- xine_send_event(this, &ui_event.event);
- }
break;
default:
@@ -268,44 +264,32 @@ void *video_decoder_loop (void *this_gen) {
streamtype = (buf->type>>16) & 0xFF;
- decoder = get_video_decoder (this, streamtype);
+ decoder = get_video_decoder (stream, streamtype);
if (decoder) {
- if (this->cur_video_decoder_plugin != decoder) {
- xine_ui_event_t ui_event;
+ if (stream->video_decoder_plugin != decoder) {
- if (this->cur_video_decoder_plugin) {
- this->cur_video_decoder_plugin->close (this->cur_video_decoder_plugin);
- printf ("video_decoder: closing old decoder >%s<\n",this->cur_video_decoder_plugin->get_identifier());
+ if (stream->video_decoder_plugin) {
+ free_video_decoder (stream, stream->video_decoder_plugin);
}
- this->cur_video_decoder_plugin = decoder;
- this->cur_video_decoder_plugin->init (this->cur_video_decoder_plugin, this->video_out);
-
- this->meta_info[XINE_META_INFO_VIDEOCODEC]
- = strdup (decoder->get_identifier());
-
- xine_report_codec( this, XINE_CODEC_VIDEO, 0, buf->type, 1);
-
- ui_event.event.type = XINE_EVENT_OUTPUT_VIDEO;
- ui_event.data = this->cur_input_plugin->get_mrl(this->cur_input_plugin);
- xine_send_event(this, &ui_event.event);
-
+ stream->video_decoder_plugin = decoder;
}
- decoder->decode_data (this->cur_video_decoder_plugin, buf);
+ decoder->decode_data (stream->video_decoder_plugin, buf);
- } else if( buf->type != buftype_unknown ) {
- xine_log (this, XINE_LOG_MSG, "video_decoder: no plugin available to handle '%s'\n",
- buf_video_name( buf->type ) );
- xine_report_codec( this, XINE_CODEC_VIDEO, 0, buf->type, 0);
- buftype_unknown = buf->type;
- }
- } else if( buf->type != buftype_unknown ) {
- xine_log (this, XINE_LOG_MSG, "video_decoder: unknown buffer type: %08x\n",
- buf->type );
+ } else if (buf->type != buftype_unknown) {
+ xine_log (stream->xine, XINE_LOG_MSG,
+ "video_decoder: no plugin available to handle '%s'\n",
+ buf_video_name( buf->type ) );
buftype_unknown = buf->type;
+ }
+ } else if (buf->type != buftype_unknown) {
+ xine_log (stream->xine, XINE_LOG_MSG,
+ "video_decoder: unknown buffer type: %08x\n",
+ buf->type );
+ buftype_unknown = buf->type;
}
xine_profiler_stop_count (prof_video_decode);
@@ -320,7 +304,7 @@ void *video_decoder_loop (void *this_gen) {
pthread_exit(NULL);
}
-void video_decoder_init (xine_t *this) {
+void video_decoder_init (xine_stream_t *stream) {
pthread_attr_t pth_attrs;
struct sched_param pth_params;
@@ -333,7 +317,7 @@ void video_decoder_init (xine_t *this) {
* We provide buffers of 8k size instead of 2k for demuxers sending
* larger chunks.
*/
- this->video_fifo = fifo_buffer_new (500, 8192);
+ stream->video_fifo = fifo_buffer_new (500, 8192);
pthread_attr_init(&pth_attrs);
pthread_attr_getschedparam(&pth_attrs, &pth_params);
@@ -341,32 +325,32 @@ void video_decoder_init (xine_t *this) {
pthread_attr_setschedparam(&pth_attrs, &pth_params);
pthread_attr_setscope(&pth_attrs, PTHREAD_SCOPE_SYSTEM);
- if ((err = pthread_create (&this->video_thread,
- &pth_attrs, video_decoder_loop, this)) != 0) {
+ if ((err = pthread_create (&stream->video_thread,
+ &pth_attrs, video_decoder_loop, stream)) != 0) {
fprintf (stderr, "video_decoder: can't create new thread (%s)\n",
strerror(err));
abort();
}
- this->video_in_discontinuity = 0;
+ stream->video_in_discontinuity = 0;
}
-void video_decoder_shutdown (xine_t *this) {
+void video_decoder_shutdown (xine_stream_t *stream) {
buf_element_t *buf;
void *p;
printf ("video_decoder: shutdown...\n");
- /* this->video_fifo->clear(this->video_fifo); */
+ /* stream->video_fifo->clear(stream->video_fifo); */
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
printf ("video_decoder: shutdown...2\n");
buf->type = BUF_CONTROL_QUIT;
- this->video_fifo->put (this->video_fifo, buf);
+ stream->video_fifo->put (stream->video_fifo, buf);
printf ("video_decoder: shutdown...3\n");
- pthread_join (this->video_thread, &p);
+ pthread_join (stream->video_thread, &p);
printf ("video_decoder: shutdown...4\n");
}
diff --git a/src/xine-engine/video_decoder.h b/src/xine-engine/video_decoder.h
new file mode 100644
index 000000000..5fbcfb4d9
--- /dev/null
+++ b/src/xine-engine/video_decoder.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2000-2002 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
+ *
+ * $Id: video_decoder.h,v 1.3 2002/10/14 15:47:40 guenter Exp $
+ *
+ * xine video decoder plugin interface
+ *
+ */
+
+#ifndef HAVE_VIDEO_DECODER_H
+#define HAVE_VIDEO_DECODER_H
+
+#include <inttypes.h>
+#include "buffer.h"
+
+#define VIDEO_DECODER_IFACE_VERSION 11
+
+/*
+ * generic xine video decoder plugin interface
+ */
+
+typedef struct video_decoder_class_s video_decoder_class_t;
+
+struct video_decoder_class_s {
+
+ /*
+ * return short, human readable identifier for this plugin class
+ */
+ char* (*get_identifier) (video_decoder_class_t *this);
+
+ /*
+ * return human readable (verbose = 1 line) description for
+ * this plugin class
+ */
+ char* (*get_description) (video_decoder_class_t *this);
+};
+
+
+typedef struct video_decoder_s video_decoder_t;
+
+struct video_decoder_s {
+
+ /*
+ * decode data from buf and feed decoded frames to
+ * video output
+ */
+ void (*decode_data) (video_decoder_t *this, buf_element_t *buf);
+
+ /*
+ * reset decoder after engine flush (prepare for new
+ * video data not related to recently decoded data)
+ */
+ void (*reset) (video_decoder_t *this);
+
+ /*
+ * flush out any frames that are still stored in the decoder
+ */
+ void (*flush) (video_decoder_t *this);
+
+ /*
+ * close down, free all resources
+ */
+ void (*dispose) (video_decoder_t *this);
+
+
+ void *node; /*used by plugin loader */
+
+};
+
+#endif
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index 5a9d91fca..879059fb8 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out.c,v 1.104 2002/09/09 03:06:14 miguelfreitas Exp $
+ * $Id: video_out.c,v 1.105 2002/10/14 15:47:41 guenter Exp $
*
* frame allocation / queuing / scheduling / output functions
*/
@@ -54,6 +54,7 @@ typedef struct {
xine_vo_driver_t *driver;
metronom_t *metronom;
xine_t *xine;
+ xine_stream_t *stream;
img_buf_fifo_t *free_img_buf_queue;
img_buf_fifo_t *display_img_buf_queue;
@@ -550,11 +551,11 @@ static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts) {
*/
pthread_mutex_lock( &this->free_img_buf_queue->mutex );
if (img && !img->next &&
- (this->xine->video_fifo->size(this->xine->video_fifo) < 10
- || this->xine->video_in_discontinuity) ) {
+ (this->stream->video_fifo->size(this->stream->video_fifo) < 10
+ || this->stream->video_in_discontinuity) ) {
printf ("video_out: possible still frame (fifosize = %d)\n",
- this->xine->video_fifo->size(this->xine->video_fifo));
+ this->stream->video_fifo->size(this->stream->video_fifo));
this->img_backup = duplicate_frame (this, img);
}
@@ -620,7 +621,7 @@ static void paused_loop( vos_t *this, int64_t vpts )
/* prevent decoder thread from allocating new frames */
this->free_img_buf_queue->locked_for_read = 1;
- while( this->xine->speed == XINE_SPEED_PAUSE ) {
+ while (this->stream->speed == XINE_SPEED_PAUSE) {
/* we need at least one free frame to keep going */
if( this->display_img_buf_queue->first &&
@@ -716,7 +717,7 @@ static void *video_out_loop (void *this_gen) {
diff = vpts - this->last_delivery_pts;
if (diff > 30000 && !this->display_img_buf_queue->first) {
- if (this->xine->cur_video_decoder_plugin) {
+ if (this->stream->video_decoder_plugin) {
#ifdef LOG
printf ("video_out: flushing current video decoder plugin (%d %d)\n",
@@ -724,7 +725,7 @@ static void *video_out_loop (void *this_gen) {
this->free_img_buf_queue->num_buffers);
#endif
- this->xine->cur_video_decoder_plugin->flush(this->xine->cur_video_decoder_plugin);
+ this->stream->video_decoder_plugin->flush(this->stream->video_decoder_plugin);
}
this->last_delivery_pts = vpts;
}
@@ -747,8 +748,8 @@ static void *video_out_loop (void *this_gen) {
do {
vpts = this->metronom->get_current_time (this->metronom);
- if( this->xine->speed == XINE_SPEED_PAUSE )
- paused_loop( this, vpts );
+ if (this->stream->speed == XINE_SPEED_PAUSE)
+ paused_loop (this, vpts);
usec_to_sleep = (next_frame_vpts - vpts) * 100 / 9;
@@ -886,7 +887,8 @@ static void vo_enable_overlay (vo_instance_t *this_gen, int overlay_enabled) {
}
-vo_instance_t *vo_new_instance (xine_vo_driver_t *driver, xine_t *xine) {
+vo_instance_t *vo_new_instance (xine_vo_driver_t *driver,
+ xine_stream_t *stream) {
vos_t *this;
int i;
@@ -898,8 +900,9 @@ vo_instance_t *vo_new_instance (xine_vo_driver_t *driver, xine_t *xine) {
this = xine_xmalloc (sizeof (vos_t)) ;
this->driver = driver;
- this->xine = xine;
- this->metronom = xine->metronom;
+ this->xine = stream->xine;
+ this->metronom = stream->metronom;
+ this->stream = stream;
this->vo.open = vo_open;
this->vo.get_frame = vo_get_frame;
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index fa955cac9..2e7585af7 100644
--- a/src/xine-engine/video_out.h
+++ b/src/xine-engine/video_out.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out.h,v 1.63 2002/10/09 05:13:40 storri Exp $
+ * $Id: video_out.h,v 1.64 2002/10/14 15:47:42 guenter Exp $
*
*
* xine version of video_out.h
@@ -303,6 +303,8 @@ struct xine_vo_driver_s {
*/
int (*redraw_needed) (xine_vo_driver_t *this);
+ void *node; /* needed by plugin_loader */
+
};
typedef struct rle_elem_s {
@@ -363,7 +365,8 @@ video_overlay_instance_t *video_overlay_new_instance ();
* a given video driver
*/
-vo_instance_t *vo_new_instance (xine_vo_driver_t *driver, xine_t *xine) ;
+vo_instance_t *vo_new_instance (xine_vo_driver_t *driver,
+ xine_stream_t *stream) ;
#ifdef __cplusplus
}
diff --git a/src/xine-engine/video_overlay.h b/src/xine-engine/video_overlay.h
index be6d392ff..d2d50348c 100644
--- a/src/xine-engine/video_overlay.h
+++ b/src/xine-engine/video_overlay.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_overlay.h,v 1.8 2002/04/09 13:20:44 jcdutton Exp $
+ * $Id: video_overlay.h,v 1.9 2002/10/14 15:47:43 guenter Exp $
*
*/
@@ -25,6 +25,7 @@
#define HAVE_VIDEO_OVERLAY_H
#include "xine_internal.h"
+#include "events.h"
#ifdef __GNUC__
#define CLUT_Y_CR_CB_INIT(_y,_cr,_cb) {y: (_y), cr: (_cr), cb: (_cb)}
@@ -67,10 +68,10 @@ typedef struct vo_buttons_s {
int32_t right;
uint32_t select_color[OVL_PALETTE_SIZE];
uint8_t select_trans[OVL_PALETTE_SIZE];
- xine_menu_event_t select_event;
+ xine_event_t select_event;
uint32_t active_color[OVL_PALETTE_SIZE];
uint8_t active_trans[OVL_PALETTE_SIZE];
- xine_menu_event_t active_event;
+ xine_event_t active_event;
int32_t clip_rgb_clut; /* true if clut was converted to rgb*/
/* FIXME: Probably not needed ^^^ */
} vo_buttons_t;
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index f8474baf2..51b57d0a1 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine.c,v 1.164 2002/10/12 19:22:05 jkeil Exp $
+ * $Id: xine.c,v 1.165 2002/10/14 15:47:43 guenter Exp $
*
* top-level xine functions
*
@@ -57,507 +57,362 @@
#include "xineutils.h"
#include "compat.h"
-#define LOGO_DELAY 500000 /* usec */
+void xine_notify_stream_finished (xine_stream_t *stream) {
-static void play_logo_internal (xine_t *this) {
- pthread_mutex_lock (&this->logo_lock);
- this->playing_logo = 1;
- if( !xine_open_internal(this, this->logo_mrl) )
- this->playing_logo = 0;
- else {
- xine_play_internal (this, 0, 0);
- this->status = XINE_STATUS_LOGO;
- }
- pthread_mutex_unlock (&this->logo_lock);
-}
-
-/* config callback for logo mrl changing */
-static void _logo_change_cb(void *data, xine_cfg_entry_t *cfg) {
- xine_t *this = (xine_t *) data;
-
- pthread_mutex_lock (&this->logo_lock);
- this->logo_mrl = cfg->str_value;
- pthread_mutex_unlock (&this->logo_lock);
-
- /*
- * Start playback of new mrl only if
- * current status is XINE_STATUS_STOP or XINE_STATUS_LOGO
- */
- pthread_mutex_lock (&this->xine_lock);
- if(this->metronom && (this->status == XINE_STATUS_LOGO || this->status == XINE_STATUS_STOP)) {
- xine_stop_internal(this);
- this->metronom->adjust_clock(this->metronom,
- this->metronom->get_current_time(this->metronom) + 30 * 90000 );
- play_logo_internal(this);
- }
- pthread_mutex_unlock (&this->xine_lock);
-}
-
-void * xine_notify_stream_finished_thread (void * this_gen) {
- xine_t *this = this_gen;
xine_event_t event;
- pthread_mutex_lock (&this->xine_lock);
- xine_stop_internal (this);
- pthread_mutex_unlock (&this->xine_lock);
-
- event.type = XINE_EVENT_PLAYBACK_FINISHED;
- xine_send_event (this, &event);
-
- xine_usec_sleep (LOGO_DELAY);
-
- pthread_mutex_lock (&this->xine_lock);
- if (this->status == XINE_STATUS_STOP) {
- play_logo_internal(this);
- }
- pthread_mutex_unlock (&this->xine_lock);
-
- return NULL;
-}
-
-void xine_notify_stream_finished (xine_t *this) {
- int err;
-
- if (this->status == XINE_STATUS_QUIT)
+ if (stream->status == XINE_STATUS_QUIT)
return;
- if (this->finished_thread_running)
- pthread_join (this->finished_thread, NULL);
-
- this->finished_thread_running = 1;
-
- /* This thread will just execute xine_stop and (possibly) xine_play then die.
- It might look useless but i need to detach this code from the current
- thread to make sure that video_decoder and audio_decoder are running and
- freeing buffers. Free buffers might be needed by the main thread during
- a xine_play, for example.
+ event.data_length = 0;
+ event.type = XINE_EVENT_UI_PLAYBACK_FINISHED;
- This is not a theorical situation: i was able to trigger it with simple
- user actions (play,seek,etc). [MF]
- */
- if ((err = pthread_create (&this->finished_thread,
- NULL, xine_notify_stream_finished_thread, this)) != 0) {
- printf (_("xine_notify_stream_finished: can't create new thread (%s)\n"),
- strerror(err));
- abort();
- }
+ xine_event_send (stream, &event);
}
-void xine_report_codec( xine_t *this, int codec_type, uint32_t fourcc, uint32_t buf_type, int handled ) {
+void xine_report_codec (xine_stream_t *stream, int codec_type,
+ uint32_t fourcc, uint32_t buf_type, int handled) {
- if( this->report_codec_cb ) {
- if( codec_type == XINE_CODEC_VIDEO ) {
- if( !buf_type )
- buf_type = fourcc_to_buf_video( fourcc );
-
- this->report_codec_cb( this->report_codec_user_data,
- codec_type, fourcc,
- buf_video_name( buf_type ), handled );
- } else {
- if( !buf_type )
- buf_type = formattag_to_buf_audio( fourcc );
-
- this->report_codec_cb( this->report_codec_user_data,
- codec_type, fourcc,
- buf_audio_name( buf_type ), handled );
- }
- }
-}
-
-int xine_register_report_codec_cb(xine_t *this,
- xine_report_codec_cb_t report_codec,
- void *user_data) {
-
- this->report_codec_cb = report_codec;
- this->report_codec_user_data = user_data;
- return 1;
-}
-
-void xine_internal_osd (xine_t *this, char *str, int duration) {
-
- uint32_t seconds;
- char tstr[256];
- int64_t start_time;
-
- this->curtime_needed_for_osd = 0;
- start_time = this->metronom->get_current_time (this->metronom);
-
- if (this->osd_display) {
-
- this->osd_renderer->filled_rect (this->osd, 0, 0, 299, 99, 0);
- this->osd_renderer->render_text (this->osd, 0, 5, str, OSD_TEXT1);
-
- seconds = this->cur_input_time;
-
- sprintf (tstr, "%02d:%02d:%02d",
- seconds / (60 * 60),
- (seconds % (60*60)) / 60,
- seconds % 60);
-
- this->osd_renderer->render_text (this->osd, 45, 5, tstr, OSD_TEXT1);
-
- this->osd_renderer->show (this->osd, start_time);
- this->osd_renderer->hide (this->osd, start_time+duration);
+ if (codec_type == XINE_CODEC_VIDEO) {
+ stream->stream_info[XINE_STREAM_INFO_VIDEO_FOURCC] = fourcc;
+ stream->stream_info[XINE_STREAM_INFO_VIDEO_HANDLED] = handled;
+ } else {
+ stream->stream_info[XINE_STREAM_INFO_AUDIO_FOURCC] = fourcc;
+ stream->stream_info[XINE_STREAM_INFO_AUDIO_HANDLED] = handled;
}
}
-static void update_osd_display(void *this_gen, xine_cfg_entry_t *entry)
-{
- xine_t *this = (xine_t *) this_gen;
-
- this->osd_display = entry->num_value;
-}
-
-static void xine_set_speed_internal (xine_t *this, int speed) {
+static void xine_set_speed_internal (xine_stream_t *stream, int speed) {
- this->metronom->set_speed (this->metronom, speed);
+ stream->metronom->set_speed (stream->metronom, speed);
/* see coment on audio_out loop about audio_paused */
- if( this->audio_out ) {
- this->audio_out->audio_paused = (speed != XINE_SPEED_NORMAL) +
- (speed == XINE_SPEED_PAUSE);
+ if( stream->audio_out ) {
+ stream->audio_out->audio_paused = (speed != XINE_SPEED_NORMAL) +
+ (speed == XINE_SPEED_PAUSE);
/*
* slow motion / fast forward does not play sound, drop buffered
* samples from the sound driver
*/
if (speed != XINE_SPEED_NORMAL && speed != XINE_SPEED_PAUSE)
- this->audio_out->control(this->audio_out, AO_CTRL_FLUSH_BUFFERS);
+ stream->audio_out->control(stream->audio_out, AO_CTRL_FLUSH_BUFFERS);
- this->audio_out->control(this->audio_out,
- speed == XINE_SPEED_PAUSE ? AO_CTRL_PLAY_PAUSE : AO_CTRL_PLAY_RESUME);
+ stream->audio_out->control(stream->audio_out,
+ speed == XINE_SPEED_PAUSE ? AO_CTRL_PLAY_PAUSE : AO_CTRL_PLAY_RESUME);
}
-
- this->speed = speed;
+
+ stream->speed = speed;
}
-void xine_stop_internal (xine_t *this) {
+static void xine_stop_internal (xine_stream_t *stream) {
+
+ int finished_count_audio = 0;
+ int finished_count_video = 0;
- printf ("xine_stop. status before = %d\n", this->status);
+ printf ("xine: xine_stop. status before = %d\n", stream->status);
- if (this->status == XINE_STATUS_STOP) {
- printf ("xine_stop ignored\n");
+ if (stream->status == XINE_STATUS_STOP) {
+ printf ("xine: xine_stop ignored\n");
return;
}
/* make sure we're not in "paused" state */
- xine_set_speed_internal(this, XINE_SPEED_NORMAL);
+ xine_set_speed_internal (stream, XINE_SPEED_NORMAL);
/* Don't change status if we're quitting */
- if(this->status != XINE_STATUS_QUIT)
- this->status = XINE_STATUS_STOP;
+ if (stream->status != XINE_STATUS_QUIT)
+ stream->status = XINE_STATUS_STOP;
- printf ("xine_stop: stopping demuxer\n");
- if(this->cur_demuxer_plugin) {
- this->cur_demuxer_plugin->stop (this->cur_demuxer_plugin);
- this->cur_demuxer_plugin = NULL;
+ /*
+ * stop demux
+ */
+
+ pthread_mutex_lock (&stream->counter_lock);
+ if (stream->audio_fifo)
+ finished_count_audio = stream->finished_count_audio + 1;
+ else
+ finished_count_audio = 0;
+
+ finished_count_video = stream->finished_count_video + 1;
+ pthread_mutex_unlock (&stream->counter_lock);
+
+ printf ("xine_stop: stopping demux\n");
+ if (stream->demux_plugin) {
+ stream->demux_plugin->dispose (stream->demux_plugin);
+ stream->demux_plugin = NULL;
+
+ /*
+ * wait until engine has really stopped
+ */
+
+ pthread_mutex_lock (&stream->counter_lock);
+ while ((stream->finished_count_audio<finished_count_audio) ||
+ (stream->finished_count_video<finished_count_video)) {
+ printf ("xine: waiting for finisheds.\n");
+ pthread_cond_wait (&stream->counter_changed, &stream->counter_lock);
+ }
+ pthread_mutex_unlock (&stream->counter_lock);
}
- printf ("xine_stop: stopped demuxer\n");
+ printf ("xine_stop: demux stopped\n");
- if(this->cur_input_plugin) {
- this->cur_input_plugin->close(this->cur_input_plugin);
- if (strcmp(this->cur_mrl, this->logo_mrl) != 0)
- /* remember the last input plugin for a possible eject */
- this->last_input_plugin = this->cur_input_plugin;
+ /*
+ * close input plugin
+ */
+
+ if (stream->input_plugin) {
+ stream->input_plugin->dispose(stream->input_plugin);
+ stream->input_plugin = NULL;
}
/* remove buffered samples from the sound device driver */
- if (this->audio_out)
- this->audio_out->control(this->audio_out, AO_CTRL_FLUSH_BUFFERS);
+ if (stream->audio_out)
+ stream->audio_out->control (stream->audio_out, AO_CTRL_FLUSH_BUFFERS);
printf ("xine_stop: done\n");
}
-void xine_stop (xine_t *this) {
- pthread_mutex_lock (&this->xine_lock);
- xine_stop_internal(this);
+void xine_stop (xine_stream_t *stream) {
+
+ pthread_mutex_lock (&stream->frontend_lock);
+
+ xine_stop_internal (stream);
/*
- this will make output threads discard about everything
- am i abusing of xine architeture? :)
- */
- this->metronom->adjust_clock(this->metronom,
- this->metronom->get_current_time(this->metronom) + 30 * 90000 );
+ * stream will make output threads discard about everything
+ * am i abusing of xine architeture? :)
+ */
+ stream->metronom->adjust_clock (stream->metronom,
+ stream->metronom->get_current_time(stream->metronom) + 30 * 90000 );
- if(this->status == XINE_STATUS_STOP) {
- play_logo_internal(this);
- }
-
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
}
+xine_stream_t *xine_stream_new (xine_t *this,
+ xine_ao_driver_t *ao, xine_vo_driver_t *vo) {
-/*
- * demuxer probing
- */
-static int probe_demux (xine_t *this, int stage1, int stage2) {
-
- int i;
- int stages[3];
+ xine_stream_t *stream;
+ int i;
- stages[0] = stage1;
- stages[1] = stage2;
- stages[2] = -1;
+ printf ("xine: xine_stream_new\n");
- if (stages[0] == -1) {
- printf ("xine: probe_demux stage1 = %d is not allowed \n", stage1);
- return 0;
- }
+ /*
+ * create a new stream object
+ */
- i = 0;
- while (stages[i] != -1) {
+ pthread_mutex_lock (&this->streams_lock);
- plugin_node_t *node;
+ stream = (xine_stream_t *) xine_xmalloc (sizeof (xine_stream_t)) ;
- node = xine_list_first_content (this->plugin_catalog->demux);
+ stream->xine = this;
+ stream->status = XINE_STATUS_STOP;
+ for (i=0; i<XINE_STREAM_INFO_MAX; i++) {
+ stream->stream_info[i] = 0;
+ stream->meta_info[i] = NULL;
+ }
+ stream->speed = XINE_SPEED_NORMAL;
+ stream->input_pos = 0;
+ stream->input_length = 0;
+ stream->input_time = 0;
+ stream->spu_out = NULL;
+ stream->spu_decoder_plugin = NULL;
+ stream->audio_channel_user = -1;
+ stream->audio_channel_auto = 0;
+ stream->spu_channel_auto = -1;
+ stream->spu_channel_letterbox = -1;
+ stream->spu_channel_pan_scan = -1;
+ stream->spu_channel_user = -1;
+ stream->spu_channel = -1;
+ stream->video_driver = vo;
+ stream->video_in_discontinuity = 0;
+ stream->video_channel = 0;
+ stream->header_count_audio = 0;
+ stream->header_count_video = 0;
+ stream->finished_count_audio = 0;
+ stream->finished_count_video = 0;
+ stream->err = 0;
- while (node) {
- demux_plugin_t *plugin;
+ /*
+ * init mutexes and conditions
+ */
- plugin = (demux_plugin_t *) node->plugin;
+ pthread_mutex_init (&stream->frontend_lock, NULL);
+ pthread_mutex_init (&stream->event_queues_lock, NULL);
+ pthread_mutex_init (&stream->osd_lock, NULL);
+ pthread_mutex_init (&stream->counter_lock, NULL);
+ pthread_cond_init (&stream->counter_changed, NULL);
- if (plugin->open (plugin,
- this->cur_input_plugin,
- stages[i]) == DEMUX_CAN_HANDLE) {
-
- this->cur_demuxer_plugin = plugin;
+ /*
+ * create a metronom
+ */
- return 1;
- }
- node = xine_list_next_content (this->plugin_catalog->demux);
- }
- i++;
- }
+ stream->metronom = metronom_init ( (ao != NULL), stream);
- return 0;
-}
+ /*
+ * alloc fifos, init and start decoder threads
+ */
-/*
- * try to find a demuxer which handle current mrl.
- */
-static int find_demuxer(xine_t *this) {
+ stream->video_out = vo_new_instance (vo, stream);
+ video_decoder_init (stream);
- this->cur_demuxer_plugin = NULL;
+ if (ao)
+ stream->audio_out = ao_new_instance (ao, stream);
+ audio_decoder_init (stream);
- switch (this->demux_strategy) {
+ /*
+ * osd
+ */
- case DEMUX_DEFAULT_STRATEGY:
- if (probe_demux (this, STAGE_BY_CONTENT, STAGE_BY_EXTENSION))
- return 1;
- break;
+ stream->osd_renderer = osd_renderer_init (stream->video_out->get_overlay_instance (stream->video_out), stream->xine->config );
+
+ /*
+ * register stream
+ */
- case DEMUX_REVERT_STRATEGY:
- if (probe_demux (this, STAGE_BY_EXTENSION, STAGE_BY_CONTENT))
- return 1;
- break;
+ xine_list_append_content (this->streams, stream);
- case DEMUX_CONTENT_STRATEGY:
- if (probe_demux (this, STAGE_BY_CONTENT, -1))
- return 1;
- break;
+ pthread_mutex_unlock (&this->streams_lock);
- case DEMUX_EXTENSION_STRATEGY:
- if (probe_demux (this, STAGE_BY_EXTENSION, -1))
- return 1;
- break;
- }
-
- return 0;
+ return stream;
}
-int xine_open_internal (xine_t *this, const char *mrl) {
-
- printf ("xine: open mrl '%s'\n", mrl);
+static int xine_open_internal (xine_stream_t *stream, const char *mrl) {
- /*
- * is this an 'opt:' mrlstyle ?
- */
- if (xine_config_change_opt(this->config, mrl)) {
- xine_event_t event;
-
- this->status = XINE_STATUS_STOP;
-
- event.type = XINE_EVENT_PLAYBACK_FINISHED;
- pthread_mutex_unlock (&this->xine_lock);
- xine_send_event (this, &event);
- pthread_mutex_lock (&this->xine_lock);
- return 1;
- }
+ int header_count_audio;
+ int header_count_video;
/*
- * stop engine only for different mrl
+ * find an input plugin
*/
- if ((this->status == XINE_STATUS_PLAY && strcmp (mrl, this->cur_mrl))
- || (this->status == XINE_STATUS_LOGO)) {
-
- printf ("xine: stopping engine\n");
+ if (!(stream->input_plugin = find_input_plugin (stream, mrl))) {
+ xine_log (stream->xine, XINE_LOG_MSG,
+ _("xine: cannot find input plugin for this MRL\n"));
- if (this->speed != XINE_SPEED_NORMAL)
- xine_set_speed_internal (this, XINE_SPEED_NORMAL);
+ stream->err = XINE_ERROR_NO_INPUT_PLUGIN;
+ return 0;
+ }
+ stream->input_class = stream->input_plugin->input_class;
+ stream->meta_info[XINE_META_INFO_INPUT_PLUGIN]
+ = strdup (stream->input_class->get_identifier (stream->input_class));
- if(this->cur_demuxer_plugin) {
- this->playing_logo = 0;
- this->cur_demuxer_plugin->stop (this->cur_demuxer_plugin);
- }
-
- if(this->cur_input_plugin) {
- if (strcmp (mrl, this->cur_mrl))
- this->cur_input_plugin->close(this->cur_input_plugin);
- else
- this->cur_input_plugin->stop(this->cur_input_plugin);
- }
+ /*
+ * find a demux plugin
+ */
+ if (!find_demux_plugin (stream, stream->input_plugin)) {
+ xine_log (stream->xine, XINE_LOG_MSG,
+ _("xine: couldn't find demux for >%s<\n"), mrl);
+ stream->input_plugin->dispose (stream->input_plugin);
+ stream->input_plugin = NULL;
+ stream->err = XINE_ERROR_NO_DEMUX_PLUGIN;
/* remove buffered samples from the sound device driver */
- if (this->audio_out)
- this->audio_out->control(this->audio_out, AO_CTRL_FLUSH_BUFFERS);
+ if (stream->audio_out)
+ stream->audio_out->control (stream->audio_out, AO_CTRL_FLUSH_BUFFERS);
- this->status = XINE_STATUS_STOP;
+ stream->status = XINE_STATUS_STOP;
+ return 0;
}
- if (this->status == XINE_STATUS_STOP) {
-
- plugin_node_t *node;
- int i, header_count;
-
- /*
- * (1/3) reset metainfo
- */
-
- for (i=0; i<XINE_STREAM_INFO_MAX; i++) {
- this->stream_info[i] = 0;
- if (this->meta_info[i]) {
- free (this->meta_info[i]);
- this->meta_info[i] = NULL;
- }
- }
+ stream->meta_info[XINE_META_INFO_SYSTEMLAYER]
+ = strdup (stream->demux_plugin->demux_class->get_identifier());
- /*
- * (2/3) start engine for new mrl'
- */
+ /*
+ * start metronom clock
+ */
- printf ("xine: starting engine for new mrl\n");
+ stream->metronom->start_clock (stream->metronom, 0);
- /*
- * find input plugin
- */
- this->cur_input_plugin = NULL;
- node = xine_list_first_content (this->plugin_catalog->input);
- while (node) {
- input_plugin_t *plugin;
-
- plugin = (input_plugin_t *) node->plugin;
-
- if (plugin->open (plugin, mrl)) {
- this->cur_input_plugin = plugin;
- break;
- }
- node = xine_list_next_content (this->plugin_catalog->input);
- }
+ /*
+ * send and decode headers
+ */
- if (!this->cur_input_plugin) {
- xine_log (this, XINE_LOG_MSG,
- _("xine: cannot find input plugin for this MRL\n"));
- this->cur_demuxer_plugin = NULL;
- this->err = XINE_ERROR_NO_INPUT_PLUGIN;
+ pthread_mutex_lock (&stream->counter_lock);
+ if (stream->audio_fifo)
+ header_count_audio = stream->header_count_audio + 1;
+ else
+ header_count_audio = 0;
- return 0;
- }
+ header_count_video = stream->header_count_video + 1;
+ pthread_mutex_unlock (&stream->counter_lock);
- this->meta_info[XINE_META_INFO_INPUT_PLUGIN]
- = strdup (this->cur_input_plugin->get_identifier(this->cur_input_plugin));
+ stream->demux_plugin->send_headers (stream->demux_plugin);
- /*
- * find demuxer plugin
- */
- header_count = this->header_sent_counter+1;
-
- if (!find_demuxer(this)) {
- xine_log (this, XINE_LOG_MSG,
- _("xine: couldn't find demuxer for >%s<\n"), mrl);
- this->cur_input_plugin->close(this->cur_input_plugin);
- this->err = XINE_ERROR_NO_DEMUXER_PLUGIN;
- return 0;
- }
+ pthread_mutex_lock (&stream->counter_lock);
+ while ((stream->header_count_audio<header_count_audio) ||
+ (stream->header_count_video<header_count_video)) {
+ printf ("xine: waiting for headers.\n");
+ pthread_cond_wait (&stream->counter_changed, &stream->counter_lock);
+ }
+ pthread_mutex_unlock (&stream->counter_lock);
- this->meta_info[XINE_META_INFO_SYSTEMLAYER]
- = strdup (this->cur_demuxer_plugin->get_identifier());
+ return 1;
+}
- /* FIXME: ?? limited length ??? */
- strncpy (this->cur_mrl, mrl, 1024);
+int xine_open (xine_stream_t *stream, const char *mrl) {
- printf ("xine: engine start successful - waiting for headers to be sent\n");
+ int ret;
- /*
- * (3/3) wait for headers to be sent and decoded
- */
+ pthread_mutex_lock (&stream->frontend_lock);
- while (header_count>this->header_sent_counter) {
- printf ("xine: waiting for headers.\n");
- xine_usec_sleep (20000);
- }
+ printf ("xine: xine_open %s\n", mrl);
- printf ("xine: xine_open done.\n");
+ ret = xine_open_internal (stream, mrl);
- return 1;
- }
+ pthread_mutex_unlock (&stream->frontend_lock);
- printf ("xine: xine_open ignored (same mrl, already playing)\n");
- return 0;
+ return ret;
}
-int xine_play_internal (xine_t *this, int start_pos, int start_time) {
+
+static int xine_play_internal (xine_stream_t *stream, int start_pos, int start_time) {
double share ;
off_t pos, len;
int demux_status;
- printf ("xine: xine_play_internal\n");
+ printf ("xine: xine_play\n");
- if (this->speed != XINE_SPEED_NORMAL)
- xine_set_speed_internal (this, XINE_SPEED_NORMAL);
+ if (stream->speed != XINE_SPEED_NORMAL)
+ xine_set_speed_internal (stream, XINE_SPEED_NORMAL);
/*
- * start/seek demuxer
+ * start/seek demux
*/
if (start_pos) {
/* FIXME: do we need to protect concurrent access to input plugin here? */
- len = this->cur_input_plugin->get_length (this->cur_input_plugin);
+ len = stream->input_plugin->get_length (stream->input_plugin);
share = (double) start_pos / 65535;
pos = (off_t) (share * len) ;
} else
pos = 0;
- if (this->status == XINE_STATUS_STOP) {
+ if (stream->status == XINE_STATUS_STOP) {
- demux_status = this->cur_demuxer_plugin->start (this->cur_demuxer_plugin,
+ demux_status = stream->demux_plugin->start (stream->demux_plugin,
pos, start_time);
} else {
- demux_status = this->cur_demuxer_plugin->seek (this->cur_demuxer_plugin,
+ demux_status = stream->demux_plugin->seek (stream->demux_plugin,
pos, start_time);
}
if (demux_status != DEMUX_OK) {
- xine_log (this, XINE_LOG_MSG,
- _("xine_play: demuxer failed to start\n"));
+ xine_log (stream->xine, XINE_LOG_MSG,
+ _("xine_play: demux failed to start\n"));
- this->err = XINE_ERROR_DEMUXER_FAILED;
+ stream->err = XINE_ERROR_DEMUX_FAILED;
- if( this->status == XINE_STATUS_STOP )
- this->cur_input_plugin->close(this->cur_input_plugin);
+ if (stream->status == XINE_STATUS_STOP)
+ stream->input_plugin->dispose(stream->input_plugin);
+ pthread_mutex_unlock (&stream->frontend_lock);
return 0;
} else {
-
- this->status = XINE_STATUS_PLAY;
-
- /* osd will be updated as soon as we know cur_input_time */
- if( !this->playing_logo )
- this->curtime_needed_for_osd = 5;
+ stream->status = XINE_STATUS_PLAY;
}
printf ("xine: xine_play_internal ...done\n");
@@ -565,102 +420,88 @@ int xine_play_internal (xine_t *this, int start_pos, int start_time) {
return 1;
}
-int xine_open (xine_t *this, const char *mrl) {
+int xine_play (xine_stream_t *stream, int start_pos, int start_time) {
+
int ret;
- pthread_mutex_lock (&this->xine_lock);
- ret = xine_open_internal (this, mrl);
- pthread_mutex_unlock (&this->xine_lock);
-
- return ret;
-}
+ pthread_mutex_lock (&stream->frontend_lock);
-int xine_play (xine_t *this, int start_pos, int start_time) {
- int ret;
+ ret = xine_play_internal (stream, start_pos, start_time);
- pthread_mutex_lock (&this->xine_lock);
- ret = xine_play_internal (this, start_pos, start_time);
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
return ret;
}
-
-int xine_eject (xine_t *this) {
+int xine_eject (xine_stream_t *stream) {
int status;
- if(this->last_input_plugin == NULL)
+ if (!stream->input_class)
return 0;
- pthread_mutex_lock (&this->xine_lock);
+ pthread_mutex_lock (&stream->frontend_lock);
status = 0;
- if (((this->status == XINE_STATUS_STOP) || (this->status == XINE_STATUS_LOGO))
- && this->last_input_plugin && this->last_input_plugin->eject_media) {
+ if ((stream->status == XINE_STATUS_STOP)
+ && stream->input_class && stream->input_class->eject_media) {
- status = this->last_input_plugin->eject_media (this->last_input_plugin);
+ status = stream->input_class->eject_media (stream->input_class);
}
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
return status;
}
-void xine_exit (xine_t *this) {
+void xine_dispose (xine_stream_t *stream) {
- int i;
+ printf ("xine: xine_dispose\n");
- /* skip some cleanup steps, when xine_init wasn't run */
- if (this->video_driver && this->metronom) {
+ stream->status = XINE_STATUS_QUIT;
- /* cleanup things from xine_init... */
- this->status = XINE_STATUS_QUIT;
+ xine_stop(stream);
- xine_stop(this);
+ printf ("xine_exit: shutdown audio\n");
- pthread_mutex_lock (&this->finished_lock);
+ audio_decoder_shutdown (stream);
- if (this->finished_thread_running)
- pthread_join (this->finished_thread, NULL);
+ printf ("xine_exit: shutdown video\n");
- pthread_mutex_unlock (&this->finished_lock);
+ video_decoder_shutdown (stream);
- printf ("xine_exit: shutdown audio\n");
+ stream->osd_renderer->close( stream->osd_renderer );
+ stream->video_out->exit (stream->video_out);
+ stream->video_fifo->dispose (stream->video_fifo);
- audio_decoder_shutdown (this);
+ pthread_mutex_destroy (&stream->frontend_lock);
+ pthread_mutex_destroy (&stream->counter_lock);
+ pthread_mutex_destroy (&stream->osd_lock);
+ pthread_mutex_destroy (&stream->event_queues_lock);
+ pthread_cond_destroy (&stream->counter_changed);
- printf ("xine_exit: shutdown video\n");
+ free (stream);
+}
- video_decoder_shutdown (this);
+void xine_exit (xine_t *this) {
- this->osd_renderer->close( this->osd_renderer );
- this->video_out->exit (this->video_out);
- this->video_fifo->dispose (this->video_fifo);
+ /* FIXME */
- this->metronom->exit (this->metronom);
+ printf ("xine_exit: bye!\n");
- printf ("xine_exit: bye!\n");
- }
+#if 0
- /* cleanup things from xine_new... */
- this->status = XINE_STATUS_QUIT;
+ int i;
for (i = 0; i < XINE_LOG_NUM; i++)
- this->log_buffers[i]->dispose (this->log_buffers[i]);
-
- dispose_plugins (this);
- xine_profiler_print_results ();
- this->config->dispose(this->config);
+ stream->log_buffers[i]->dispose (stream->log_buffers[i]);
- pthread_mutex_destroy (&this->logo_lock);
- pthread_mutex_destroy (&this->xine_lock);
- pthread_mutex_destroy (&this->finished_lock);
- pthread_mutex_destroy (&this->osd_lock);
- pthread_mutex_destroy (&this->event_lock);
- pthread_cond_destroy (&this->event_handled);
+ stream->metronom->exit (stream->metronom);
- free (this);
+ dispose_plugins (stream);
+ xine_profiler_print_results ();
+ stream->config->dispose(stream->config);
+#endif
}
xine_t *xine_new (void) {
@@ -684,22 +525,6 @@ xine_t *xine_new (void) {
#endif
/*
- * init locks
- */
-
- pthread_mutex_init (&this->xine_lock, NULL);
-
- pthread_mutex_init (&this->finished_lock, NULL);
-
- pthread_mutex_init (&this->osd_lock, NULL);
-
- pthread_mutex_init (&this->event_lock, NULL);
-
- pthread_cond_init (&this->event_handled, NULL);
-
- this->finished_thread_running = 0;
-
- /*
* config
*/
@@ -711,33 +536,12 @@ xine_t *xine_new (void) {
for (i = 0; i < XINE_LOG_NUM; i++)
this->log_buffers[i] = new_scratch_buffer (25);
-
- /*
- * defaults
- */
- this->err = XINE_ERROR_NONE;
- this->spu_channel_auto = -1;
- this->spu_channel_letterbox = -1;
- this->spu_channel_pan_scan = -1;
- this->spu_channel_user = -1;
- this->cur_input_pos = 0;
- this->cur_input_length = 0;
- this->last_input_plugin = NULL;
- this->num_event_listeners = 0; /* initially there are none */
- this->cur_input_plugin = NULL;
- this->cur_spu_decoder_plugin = NULL;
- this->report_codec_cb = NULL;
- this->header_sent_counter = 0;
-
- /*
- * meta info
+ /*
+ * streams_lock
*/
- for (i=0; i<XINE_STREAM_INFO_MAX; i++) {
- this->stream_info[i] = 0;
- this->meta_info [i] = NULL;
- }
+ pthread_mutex_init (&this->streams_lock, NULL);
/*
* plugins
@@ -745,48 +549,21 @@ xine_t *xine_new (void) {
scan_plugins(this);
- /*
- * logo
- */
-
- pthread_mutex_init (&this->logo_lock, NULL);
-
- pthread_mutex_lock (&this->logo_lock);
- this->logo_mrl = this->config->register_string(this->config,
- "misc.logo_mrl",
- XINE_LOGO_FILE,
- _("logo mrl, displayed in video output window"),
- NULL, 0, _logo_change_cb,
- (void *) this);
- pthread_mutex_unlock (&this->logo_lock);
-
return this;
-
}
-void xine_init (xine_t *this,
- xine_ao_driver_t *ao,
- xine_vo_driver_t *vo) {
+void xine_init (xine_t *this) {
static char *demux_strategies[] = {"default", "reverse", "content",
"extension", NULL};
- this->video_driver = vo;
-
/* initialize color conversion tables and functions */
init_yuv_conversion();
-
- /*
- * create a metronom
- */
-
- this->metronom = metronom_init ( (ao != NULL), this);
-
/* probe for optimized memcpy or config setting */
xine_probe_fast_memcpy (this->config);
-
+
/*
* content detection strategy
*/
@@ -797,216 +574,121 @@ void xine_init (xine_t *this,
demux_strategies,
"media format detection strategy",
NULL, 10, NULL, NULL);
-
/*
- * init and start decoder threads
+ * keep track of all opened streams
*/
- this->video_out = vo_new_instance (vo, this);
- video_decoder_init (this);
-
- this->osd_renderer = osd_renderer_init (this->video_out->get_overlay_instance (this->video_out), this->config );
-
- this->osd = this->osd_renderer->new_object (this->osd_renderer, 300, 100);
- this->osd_renderer->set_font (this->osd, "cetus", 24);
- this->osd_renderer->set_text_palette (this->osd, TEXTPALETTE_WHITE_BLACK_TRANSPARENT, OSD_TEXT1 );
- this->osd_renderer->set_position (this->osd, 10,10);
-
- this->osd_display = this->config->register_bool (this->config,
- "misc.osd_display", 1,
- "Show status on play, pause, ff, ...",
- NULL, 0,
- update_osd_display, this );
-
- if (ao)
- this->audio_out = ao_new_instance (ao, this);
-
- audio_decoder_init (this);
-
- /*
- * start metronom clock (needed for osd)
- */
-
- this->metronom->start_clock (this->metronom, 0);
-
- if (this->osd_display) {
-
- char tstr[30];
-
- this->osd_renderer->filled_rect (this->osd, 0, 0, 299, 99, 0);
- sprintf (tstr, "xine-lib v%01d.%01d.%01d", XINE_MAJOR, XINE_MINOR, XINE_SUB);
-
- this->osd_renderer->render_text (this->osd, 5, 5, tstr, OSD_TEXT1);
-
- this->osd_renderer->show (this->osd, 0);
- this->osd_renderer->hide (this->osd, 300000);
- }
-
- this->status = XINE_STATUS_STOP;
+ this->streams = xine_list_new();
+ pthread_mutex_init (&this->streams_lock, NULL);
- play_logo_internal(this);
}
-void xine_select_spu_channel (xine_t *this, int channel) {
+void xine_select_spu_channel (xine_stream_t *stream, int channel) {
- pthread_mutex_lock (&this->xine_lock);
+ pthread_mutex_lock (&stream->frontend_lock);
- this->spu_channel_user = (channel >= -2 ? channel : -2);
+ stream->spu_channel_user = (channel >= -2 ? channel : -2);
- switch (this->spu_channel_user) {
+ switch (stream->spu_channel_user) {
case -2:
- this->spu_channel = -1;
- this->video_out->enable_ovl (this->video_out, 0);
+ stream->spu_channel = -1;
+ stream->video_out->enable_ovl (stream->video_out, 0);
break;
case -1:
- this->spu_channel = this->spu_channel_auto;
- this->video_out->enable_ovl (this->video_out, 1);
+ stream->spu_channel = stream->spu_channel_auto;
+ stream->video_out->enable_ovl (stream->video_out, 1);
break;
default:
- this->spu_channel = this->spu_channel_user;
- this->video_out->enable_ovl (this->video_out, 1);
+ stream->spu_channel = stream->spu_channel_user;
+ stream->video_out->enable_ovl (stream->video_out, 1);
}
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
}
-static int xine_get_current_position (xine_t *this) {
+static int xine_get_current_position (xine_stream_t *stream) {
off_t len;
double share;
- pthread_mutex_lock (&this->xine_lock);
+ pthread_mutex_lock (&stream->frontend_lock);
- if (!this->cur_input_plugin) {
+ if (!stream->input_plugin) {
printf ("xine: xine_get_current_position: no input source\n");
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
return 0;
}
- /* pos = this->mCurInput->seek (0, SEEK_CUR); */
- len = this->cur_input_length;
- if (len == 0) len = this->cur_input_plugin->get_length (this->cur_input_plugin);
- share = (double) this->cur_input_pos / (double) len * 65535;
+ /* pos = stream->mCurInput->seek (0, SEEK_CUR); */
+ len = stream->input_length;
+ if (len == 0) len = stream->input_plugin->get_length (stream->input_plugin);
+ share = (double) stream->input_pos / (double) len * 65535;
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
return (int) share;
}
-int xine_get_status(xine_t *this) {
- int status;
-
- status = this->status;
- if( status == XINE_STATUS_LOGO )
- status = XINE_STATUS_STOP;
- return status;
+int xine_get_status (xine_stream_t *stream) {
+ return stream->status;
}
/*
* trick play
*/
-void xine_set_speed (xine_t *this, int speed) {
+void xine_set_speed (xine_stream_t *stream, int speed) {
- pthread_mutex_lock (&this->xine_lock);
+ pthread_mutex_lock (&stream->frontend_lock);
if (speed <= XINE_SPEED_PAUSE)
speed = XINE_SPEED_PAUSE;
else if (speed > XINE_SPEED_FAST_4)
speed = XINE_SPEED_FAST_4;
- /* osd */
-
- pthread_mutex_lock (&this->osd_lock);
- switch (speed) {
- case XINE_SPEED_PAUSE:
- xine_internal_osd (this, "<", 90000);
- break;
- case XINE_SPEED_SLOW_4:
- xine_internal_osd (this, "<>", 20000 * speed);
- break;
- case XINE_SPEED_SLOW_2:
- xine_internal_osd (this, "@>", 20000 * speed);
- break;
- case XINE_SPEED_NORMAL:
- xine_internal_osd (this, ">", 20000 * speed);
- break;
- case XINE_SPEED_FAST_2:
- xine_internal_osd (this, "$$", 20000 * speed);
- break;
- case XINE_SPEED_FAST_4:
- xine_internal_osd (this, "$$$", 20000 * speed);
- break;
- }
- pthread_mutex_unlock (&this->osd_lock);
-
printf ("xine: set_speed %d\n", speed);
- xine_set_speed_internal (this, speed);
+ xine_set_speed_internal (stream, speed);
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
}
-int xine_get_speed (xine_t *this) {
- return this->speed;
+int xine_get_speed (xine_stream_t *stream) {
+ return stream->speed;
}
/*
* time measurement / seek
*/
-static int xine_get_stream_length (xine_t *this) {
+static int xine_get_stream_length (xine_stream_t *stream) {
- if(this->cur_demuxer_plugin)
- return this->cur_demuxer_plugin->get_stream_length (this->cur_demuxer_plugin);
+ if (stream->demux_plugin)
+ return stream->demux_plugin->get_stream_length (stream->demux_plugin);
return 0;
}
-int xine_get_pos_length (xine_t *this, int *pos_stream,
+int xine_get_pos_length (xine_stream_t *stream, int *pos_stream,
int *pos_time, int *length_time) {
if (pos_stream)
- *pos_stream = xine_get_current_position (this);
+ *pos_stream = xine_get_current_position (stream);
if (pos_time)
- *pos_time = this->cur_input_time * 1000;
+ *pos_time = stream->input_time * 1000;
if (length_time)
- *length_time = xine_get_stream_length (this) * 1000;
+ *length_time = xine_get_stream_length (stream) * 1000;
return 1;
}
-static int xine_get_audio_capabilities(xine_t *this) {
-
- if(this->audio_out)
- return (this->audio_out->get_capabilities(this->audio_out));
-
- return AO_CAP_NOCAP;
-}
-
-static int xine_get_audio_property(xine_t *this, int property) {
-
- if(this->audio_out)
- return(this->audio_out->get_property(this->audio_out, property));
-
- return 0;
-}
-
-static int xine_set_audio_property(xine_t *this, int property, int value) {
-
- if(this->audio_out)
- return(this->audio_out->set_property(this->audio_out, property, value));
-
- return ~value;
-}
-
-int xine_get_current_frame (xine_t *this, int *width, int *height,
+int xine_get_current_frame (xine_stream_t *stream, int *width, int *height,
int *ratio_code, int *format,
uint8_t *img) {
vo_frame_t *frame;
- frame = this->video_out->get_last_frame (this->video_out);
+ frame = stream->video_out->get_last_frame (stream->video_out);
if (!frame)
return 0;
@@ -1041,42 +723,39 @@ int xine_get_current_frame (xine_t *this, int *width, int *height,
return 1;
}
-const char * xine_get_spu_lang (xine_t *this, int channel) {
+int xine_get_spu_lang (xine_stream_t *stream, int channel, char *lang) {
- if (this->cur_input_plugin) {
- if (this->cur_input_plugin->get_capabilities (this->cur_input_plugin) & INPUT_CAP_SPULANG) {
- this->cur_input_plugin->get_optional_data (this->cur_input_plugin,
- this->spu_lang,
- INPUT_OPTIONAL_DATA_SPULANG);
- return this->spu_lang;
+ if (stream->input_plugin) {
+ if (stream->input_plugin->get_capabilities (stream->input_plugin) & INPUT_CAP_SPULANG) {
+ stream->input_plugin->get_optional_data (stream->input_plugin, lang,
+ INPUT_OPTIONAL_DATA_SPULANG);
+ return 1;
}
}
- return NULL;
+ return 0;
}
-const char* xine_get_audio_lang (xine_t *this, int channel) {
+int xine_get_audio_lang (xine_stream_t *stream, int channel, char *lang) {
- if (this->cur_input_plugin) {
- if (this->cur_input_plugin->get_capabilities (this->cur_input_plugin) & INPUT_CAP_AUDIOLANG) {
- this->cur_input_plugin->get_optional_data (this->cur_input_plugin,
- this->audio_lang,
- INPUT_OPTIONAL_DATA_AUDIOLANG);
- return this->audio_lang;
+ if (stream->input_plugin) {
+ if (stream->input_plugin->get_capabilities (stream->input_plugin) & INPUT_CAP_AUDIOLANG) {
+ stream->input_plugin->get_optional_data (stream->input_plugin, lang,
+ INPUT_OPTIONAL_DATA_AUDIOLANG);
+ return 1;
}
}
- return NULL;
+ return 0;
}
-int xine_get_spu_channel (xine_t *this) {
-
- return this->spu_channel_user;
+int xine_get_spu_channel (xine_stream_t *stream) {
+ return stream->spu_channel_user;
}
-osd_renderer_t *xine_get_osd_renderer (xine_t *this) {
+osd_renderer_t *xine_get_osd_renderer (xine_stream_t *stream) {
- return this->osd_renderer;
+ return stream->osd_renderer;
}
/*
@@ -1127,11 +806,11 @@ void xine_register_log_cb (xine_t *this, xine_log_cb_t cb, void *user_data) {
}
-int xine_get_error (xine_t *this) {
- return this->err;
+int xine_get_error (xine_stream_t *stream) {
+ return stream->err;
}
-int xine_trick_mode (xine_t *this, int mode, int value) {
+int xine_trick_mode (xine_stream_t *stream, int mode, int value) {
printf ("xine: xine_trick_mode not implemented yet.\n");
abort ();
}
diff --git a/src/xine-engine/xine_interface.c b/src/xine-engine/xine_interface.c
index 541fe3f0a..677a16c67 100644
--- a/src/xine-engine/xine_interface.c
+++ b/src/xine-engine/xine_interface.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_interface.c,v 1.22 2002/09/22 14:29:40 mroi Exp $
+ * $Id: xine_interface.c,v 1.23 2002/10/14 15:47:44 guenter Exp $
*
* convenience/abstraction layer, functions to implement
* libxine's public interface
@@ -304,41 +304,42 @@ void xine_config_reset (xine_t *this) {
pthread_mutex_unlock(&config->config_lock);
}
-int xine_gui_send_vo_data (xine_t *this,
+int xine_gui_send_vo_data (xine_stream_t *stream,
int type, void *data) {
- return this->video_driver->gui_data_exchange (this->video_driver, type, data);
+ return stream->video_driver->gui_data_exchange (stream->video_driver,
+ type, data);
}
-void xine_set_param (xine_t *this, int param, int value) {
+void xine_set_param (xine_stream_t *stream, int param, int value) {
switch (param) {
case XINE_PARAM_SPEED:
- xine_set_speed (this, value);
+ xine_set_speed (stream, value);
break;
case XINE_PARAM_AV_OFFSET:
- this->metronom->set_option (this->metronom, METRONOM_AV_OFFSET, value);
+ stream->metronom->set_option (stream->metronom, METRONOM_AV_OFFSET, value);
break;
case XINE_PARAM_AUDIO_CHANNEL_LOGICAL:
- pthread_mutex_lock (&this->xine_lock);
+ pthread_mutex_lock (&stream->frontend_lock);
if (value < -2)
value = -2;
- this->audio_channel_user = value;
- pthread_mutex_unlock (&this->xine_lock);
+ stream->audio_channel_user = value;
+ pthread_mutex_unlock (&stream->frontend_lock);
break;
case XINE_PARAM_SPU_CHANNEL:
- xine_select_spu_channel (this, value);
+ xine_select_spu_channel (stream, value);
break;
case XINE_PARAM_VIDEO_CHANNEL:
- pthread_mutex_lock (&this->xine_lock);
+ pthread_mutex_lock (&stream->frontend_lock);
if (value<0)
value = 0;
- this->video_channel = value;
- pthread_mutex_unlock (&this->xine_lock);
+ stream->video_channel = value;
+ pthread_mutex_unlock (&stream->frontend_lock);
break;
case XINE_PARAM_AUDIO_VOLUME:
@@ -357,7 +358,7 @@ void xine_set_param (xine_t *this, int param, int value) {
case XINE_PARAM_VO_ZOOM_Y:
case XINE_PARAM_VO_PAN_SCAN:
case XINE_PARAM_VO_TVMODE:
- this->video_driver->set_property(this->video_driver, param & 0xffffff, value);
+ stream->video_driver->set_property(stream->video_driver, param & 0xffffff, value);
break;
default:
@@ -365,23 +366,23 @@ void xine_set_param (xine_t *this, int param, int value) {
}
}
-int xine_get_param (xine_t *this, int param) {
+int xine_get_param (xine_stream_t *stream, int param) {
switch (param) {
case XINE_PARAM_SPEED:
- return this->speed;
+ return stream->speed;
case XINE_PARAM_AV_OFFSET:
- return this->metronom->get_option (this->metronom, METRONOM_AV_OFFSET);
+ return stream->metronom->get_option (stream->metronom, METRONOM_AV_OFFSET);
case XINE_PARAM_AUDIO_CHANNEL_LOGICAL:
- return this->audio_channel_user;
+ return stream->audio_channel_user;
case XINE_PARAM_SPU_CHANNEL:
- return this->spu_channel_user;
+ return stream->spu_channel_user;
case XINE_PARAM_VIDEO_CHANNEL:
- return this->video_channel;
+ return stream->video_channel;
case XINE_PARAM_AUDIO_VOLUME:
return -1; /* FIXME: implement */
@@ -399,7 +400,7 @@ int xine_get_param (xine_t *this, int param) {
case XINE_PARAM_VO_ZOOM_Y:
case XINE_PARAM_VO_PAN_SCAN:
case XINE_PARAM_VO_TVMODE:
- return this->video_driver->get_property(this->video_driver, param & 0xffffff);
+ return stream->video_driver->get_property(stream->video_driver, param & 0xffffff);
break;
default:
@@ -409,18 +410,18 @@ int xine_get_param (xine_t *this, int param) {
return 0;
}
-uint32_t xine_get_stream_info (xine_t *this, int info) {
+uint32_t xine_get_stream_info (xine_stream_t *stream, int info) {
switch (info) {
case XINE_STREAM_INFO_SEEKABLE:
- if (this->cur_input_plugin)
- return this->cur_input_plugin->get_capabilities (this->cur_input_plugin) & INPUT_CAP_SEEKABLE;
+ if (stream->input_plugin)
+ return stream->input_plugin->get_capabilities (stream->input_plugin) & INPUT_CAP_SEEKABLE;
return 0;
case XINE_STREAM_INFO_HAS_CHAPTERS:
- if (this->cur_input_plugin)
- return this->cur_input_plugin->get_capabilities (this->cur_input_plugin) & INPUT_CAP_CHAPTERS;
+ if (stream->input_plugin)
+ return stream->input_plugin->get_capabilities (stream->input_plugin) & INPUT_CAP_CHAPTERS;
return 0;
case XINE_STREAM_INFO_BITRATE:
@@ -435,7 +436,7 @@ uint32_t xine_get_stream_info (xine_t *this, int info) {
case XINE_STREAM_INFO_AUDIO_BITS:
case XINE_STREAM_INFO_AUDIO_SAMPLERATE:
case XINE_STREAM_INFO_AUDIO_BITRATE:
- return this->stream_info[info];
+ return stream->stream_info[info];
default:
printf ("xine_interface: error, unknown stream info (%d) requested\n",
@@ -444,8 +445,8 @@ uint32_t xine_get_stream_info (xine_t *this, int info) {
return 0;
}
-const char *xine_get_meta_info (xine_t *this, int info) {
+const char *xine_get_meta_info (xine_stream_t *stream, int info) {
- return this->meta_info[info];
+ return stream->meta_info[info];
}
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index a00095ee4..a07916a9e 100644
--- a/src/xine-engine/xine_internal.h
+++ b/src/xine-engine/xine_internal.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_internal.h,v 1.103 2002/09/20 22:34:26 f1rmb Exp $
+ * $Id: xine_internal.h,v 1.104 2002/10/14 15:47:45 guenter Exp $
*
*/
@@ -66,245 +66,183 @@ extern "C" {
#include "scratch.h"
#include "xineintl.h"
#include "plugin_catalog.h"
+#include "video_decoder.h"
+#include "audio_decoder.h"
-#define VIDEO_DECODER_IFACE_VERSION 10
-#define AUDIO_DECODER_IFACE_VERSION 9
#define XINE_MAX_EVENT_LISTENERS 50
#define XINE_MAX_EVENT_TYPES 100
+#define XINE_CODEC_AUDIO 0
+#define XINE_CODEC_VIDEO 1
+
/* used by plugin loader */
#define XINE_VERSION_CODE XINE_MAJOR_VERSION*10000+XINE_MINOR_VERSION*100+XINE_SUB_VERSION
/*
- * generic xine video decoder plugin interface
- *
- * for a dynamic plugin make sure you provide this function call:
- * video_decoder_t *init_video_decoder_plugin (int iface_version,
- * xine_t *xine);
+ * log constants
*/
-typedef struct video_decoder_s video_decoder_t;
-
-struct video_decoder_s {
-
- void (*init) (video_decoder_t *this, vo_instance_t *video_out);
-
- void (*decode_data) (video_decoder_t *this, buf_element_t *buf);
-
- void (*reset) (video_decoder_t *this);
-
- void (*flush) (video_decoder_t *this);
-
- void (*close) (video_decoder_t *this);
-
- char* (*get_identifier) (void);
-
- void (*dispose) (video_decoder_t *this);
+#define XINE_LOG_MSG 0 /* warnings, errors, ... */
+#define XINE_LOG_PLUGIN 1
+#define XINE_LOG_NUM 2 /* # of log buffers defined */
-};
+#define XINE_STREAM_INFO_MAX 99
/*
- * generic xine audio decoder plugin interface
- *
- * for a dynamic plugin make sure you provide this function call:
- * audio_decoder_t *init_audio_decoder_plugin (int iface_version,
- * xine_t *xine);
+ * the "big" xine struct, holding everything together
*/
-typedef struct audio_decoder_s audio_decoder_t;
-
-struct audio_decoder_s {
-
- void (*init) (audio_decoder_t *this, ao_instance_t *audio_out);
-
- void (*decode_data) (audio_decoder_t *this, buf_element_t *buf);
-
- void (*reset) (audio_decoder_t *this);
+struct xine_s {
- void (*close) (audio_decoder_t *this);
+ config_values_t *config;
- char* (*get_identifier) (void);
+ plugin_catalog_t *plugin_catalog;
+
+ int demux_strategy;
- void (*dispose) (audio_decoder_t *this);
+ /* log output that may be presented to the user */
+ scratch_buffer_t *log_buffers[XINE_LOG_NUM];
+ xine_list_t *streams;
+ pthread_mutex_t streams_lock;
};
/*
- * log constants
+ * xine event queue
*/
-#define XINE_LOG_MSG 0 /* warnings, errors, ... */
-#define XINE_LOG_PLUGIN 1
-#define XINE_LOG_NUM 2 /* # of log buffers defined */
-
-#define XINE_STREAM_INFO_MAX 99
+struct xine_event_queue_s {
+ xine_list_t *events;
+ pthread_mutex_t lock;
+ pthread_cond_t new_event;
+ xine_stream_t *stream;
+ pthread_t *listener_thread;
+ xine_event_listener_cb_t callback;
+ void *user_data;
+};
/*
- * the big xine struct, holding everything together
+ * xine_stream - per-stream parts of the xine engine
*/
-struct xine_s {
-
- /* private : */
-
- metronom_t *metronom;
-
- config_values_t *config;
-
- /* MRL of displayed logo */
- char *logo_mrl;
- /* Logo manipulation mutex */
- pthread_mutex_t logo_lock;
-
- plugin_catalog_t *plugin_catalog;
+struct xine_stream_s {
- input_plugin_t *cur_input_plugin;
- /* kept to do proper ejecting (otherwise we eject the logo) */
- input_plugin_t *last_input_plugin;
-
- demux_plugin_t *cur_demuxer_plugin;
- int demux_strategy;
+ xine_t *xine;
int status;
- int speed;
- off_t cur_input_pos;
- off_t cur_input_length;
- int cur_input_time;
- char cur_mrl[1024];
- spu_functions_t *spu_out;
- pthread_t spu_thread;
- spu_decoder_t *cur_spu_decoder_plugin;
- int spu_finished;
+ input_plugin_t *input_plugin;
+ input_class_t *input_class; /* eject */
+ int content_detection_method;
+ demux_plugin_t *demux_plugin;
- /* *_user: -2 => off
- -1 => auto (use *_auto value)
- >=0 => respect the user's choice
- */
-
- int audio_channel_user;
- int audio_channel_auto;
- int spu_channel_user;
- int spu_channel_auto;
- int spu_channel_letterbox;
- int spu_channel_pan_scan;
- int spu_channel;
+ metronom_t *metronom;
+ int speed;
+ off_t input_pos;
+ off_t input_length;
+ int input_time;
xine_vo_driver_t *video_driver;
vo_instance_t *video_out;
fifo_buffer_t *video_fifo;
pthread_t video_thread;
- video_decoder_t *cur_video_decoder_plugin;
- int video_finished;
+ video_decoder_t *video_decoder_plugin;
int video_in_discontinuity;
int video_channel;
- osd_renderer_t *osd_renderer;
- osd_object_t *osd;
- int osd_display;
-
ao_instance_t *audio_out;
fifo_buffer_t *audio_fifo;
lrb_t *audio_temp;
pthread_t audio_thread;
- audio_decoder_t *cur_audio_decoder_plugin;
+ audio_decoder_t *audio_decoder_plugin;
uint32_t audio_track_map[50];
int audio_track_map_entries;
- int audio_finished;
uint32_t audio_type;
+ /* *_user: -2 => off
+ -1 => auto (use *_auto value)
+ >=0 => respect the user's choice
+ */
+ int audio_channel_user;
+ int audio_channel_auto;
- /* Lock for xine player functions */
- pthread_mutex_t xine_lock;
-
- /* Lock for xxx_finished variables */
- pthread_mutex_t finished_lock;
-
- /* Array of event handlers. */
- xine_event_listener_cb_t event_listeners[XINE_MAX_EVENT_LISTENERS];
- void *event_listener_user_data[XINE_MAX_EVENT_LISTENERS];
- uint16_t num_event_listeners;
- uint8_t event_pending[XINE_MAX_EVENT_TYPES];
- pthread_cond_t event_handled;
- pthread_mutex_t event_lock;
-
- /* scratch string buffers */
- char str[1024];
- char spu_lang[80];
- char audio_lang[80];
-
- /* log output that may be presented to the user */
- scratch_buffer_t *log_buffers[XINE_LOG_NUM];
+ spu_functions_t *spu_out;
+ pthread_t spu_thread;
+ spu_decoder_t *spu_decoder_plugin;
+ int spu_channel_user;
+ int spu_channel_auto;
+ int spu_channel_letterbox;
+ int spu_channel_pan_scan;
+ int spu_channel;
- int err;
+ /* lock for public xine player functions */
+ pthread_mutex_t frontend_lock;
- pthread_t finished_thread;
- int finished_thread_running;
-
- xine_report_codec_cb_t report_codec_cb;
- void *report_codec_user_data;
-
- int playing_logo;
- int curtime_needed_for_osd;
pthread_mutex_t osd_lock;
+ osd_renderer_t *osd_renderer;
/* stream meta information */
int stream_info[XINE_STREAM_INFO_MAX];
char *meta_info [XINE_STREAM_INFO_MAX];
- int header_sent_counter; /* wait for headers sent */
-};
+ /* wait for headers sent / stream decoding finished */
+ pthread_mutex_t counter_lock;
+ pthread_cond_t counter_changed;
+ int header_count_audio;
+ int header_count_video;
+ int finished_count_audio;
+ int finished_count_video;
-/*
- * private function prototypes:
- */
+ /* event mechanism */
+ xine_list_t *event_queues;
+ pthread_mutex_t event_queues_lock;
-int xine_open_internal (xine_t *this, const char *mrl);
-int xine_play_internal (xine_t *this,
- int start_pos, int start_time);
-void xine_stop_internal (xine_t *this);
-void xine_notify_stream_finished (xine_t *this);
-void xine_report_codec (xine_t *this, int codec_type,
- uint32_t fourcc, uint32_t buf_type, int handled );
-void xine_internal_osd (xine_t *this, char *str, int duration);
+ int err;
+};
-void video_decoder_init (xine_t *this);
-void video_decoder_shutdown (xine_t *this);
-void audio_decoder_init (xine_t *this);
-void audio_decoder_shutdown (xine_t *this);
-/*
- * demuxer helper functions from demux.c
+/*
+ * private function prototypes:
*/
-void xine_demux_flush_engine (xine_t *this);
+void xine_handle_stream_end (xine_stream_t *stream, int non_user);
-void xine_demux_control_newpts (xine_t *this, int64_t pts, uint32_t flags );
+/* find and instantiate input and demux plugins */
-void xine_demux_control_headers_done (xine_t *this );
+input_plugin_t *find_input_plugin (xine_stream_t *stream, const char *mrl);
+demux_plugin_t *find_demux_plugin (xine_stream_t *stream, input_plugin_t *input);
-void xine_demux_control_start (xine_t *this );
+/* create decoder fifos and threads */
-void xine_demux_control_end (xine_t *this, uint32_t flags );
+void video_decoder_init (xine_stream_t *stream);
+void video_decoder_shutdown (xine_stream_t *stream);
-/*
- * plugin management
- */
+void audio_decoder_init (xine_stream_t *stream);
+void audio_decoder_shutdown (xine_stream_t *stream);
-/*
- * on-demand loading of audio/video/spu decoder plugins
- */
+/* demuxer helper functions from demux.c */
-video_decoder_t *get_video_decoder (xine_t *this, uint8_t stream_type);
-audio_decoder_t *get_audio_decoder (xine_t *this, uint8_t stream_type);
-spu_decoder_t *get_spu_decoder (xine_t *this, uint8_t stream_type);
+void xine_demux_flush_engine (xine_stream_t *stream);
+void xine_demux_control_newpts (xine_stream_t *stream, int64_t pts, uint32_t flags);
+void xine_demux_control_headers_done (xine_stream_t *stream);
+void xine_demux_control_start (xine_stream_t *stream);
+void xine_demux_control_end (xine_stream_t *stream, uint32_t flags);
/*
* plugin_loader functions
*
*/
+/* on-demand loading of audio/video/spu decoder plugins */
+
+video_decoder_t *get_video_decoder (xine_stream_t *stream, uint8_t stream_type);
+void free_video_decoder (xine_stream_t *stream, video_decoder_t *decoder);
+audio_decoder_t *get_audio_decoder (xine_stream_t *stream, uint8_t stream_type);
+void free_audio_decoder (xine_stream_t *stream, audio_decoder_t *decoder);
+spu_decoder_t *get_spu_decoder (xine_stream_t *stream, uint8_t stream_type);
+void free_spu_decoder (xine_stream_t *stream, spu_decoder_t *decoder);
+
/*
* load_video_output_plugin
*
@@ -327,13 +265,13 @@ xine_vo_driver_t *xine_load_video_output_plugin(xine_t *this,
xine_ao_driver_t *xine_load_audio_output_plugin (xine_t *self, char *id);
-void xine_set_speed (xine_t *this, int speed) ;
+void xine_set_speed (xine_stream_t *stream, int speed) ;
-void xine_select_spu_channel (xine_t *this, int channel) ;
+void xine_select_spu_channel (xine_stream_t *stream, int channel) ;
-int xine_get_audio_channel (xine_t *this) ;
+int xine_get_audio_channel (xine_stream_t *stream) ;
-int xine_get_spu_channel (xine_t *this) ;
+int xine_get_spu_channel (xine_stream_t *stream) ;
#ifdef __cplusplus
}
diff --git a/src/xine-engine/xine_plugin.h b/src/xine-engine/xine_plugin.h
index 99297cc7e..16845dbf0 100644
--- a/src/xine-engine/xine_plugin.h
+++ b/src/xine-engine/xine_plugin.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_plugin.h,v 1.3 2002/09/05 16:24:14 guenter Exp $
+ * $Id: xine_plugin.h,v 1.4 2002/10/14 15:47:46 guenter Exp $
*
* generic plugin definitions
*
@@ -26,7 +26,7 @@
#ifndef XINE_PLUGIN_H
#define XINE_PLUGIN_H
-#define PLUGIN_NONE 0
+#define PLUGIN_NONE 0
#define PLUGIN_INPUT 1
#define PLUGIN_DEMUX 2
#define PLUGIN_AUDIO_DECODER 3
@@ -42,7 +42,8 @@ typedef struct {
char *id; /* a name that identifies this plugin */
uint32_t version; /* version number, increased every release */
void *special_info; /* plugin-type specific, see structs below */
- void *(*init)(xine_t *, void *); /* used to get/initialize an instance*/
+ void *(*init)(xine_t *, void *); /* init the plugin class */
+ void *(*open)(void *, xine_stream_t *, const void *); /* create an instance*/
} plugin_info_t;