summaryrefslogtreecommitdiff
path: root/src/xine-engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-engine')
-rw-r--r--src/xine-engine/Makefile.am82
-rw-r--r--src/xine-engine/attributes.h27
-rw-r--r--src/xine-engine/audio_decoder.c194
-rw-r--r--src/xine-engine/audio_decoder.h66
-rw-r--r--src/xine-engine/buffer.c225
-rw-r--r--src/xine-engine/buffer.h147
-rw-r--r--src/xine-engine/configfile.c293
-rw-r--r--src/xine-engine/configfile.h101
-rw-r--r--src/xine-engine/cpu_accel.c110
-rw-r--r--src/xine-engine/cpu_accel.h514
-rw-r--r--src/xine-engine/load_plugins.c200
-rw-r--r--src/xine-engine/metronom.c298
-rw-r--r--src/xine-engine/metronom.h179
-rw-r--r--src/xine-engine/monitor.c84
-rw-r--r--src/xine-engine/monitor.h89
-rw-r--r--src/xine-engine/utils.c125
-rw-r--r--src/xine-engine/utils.h39
-rw-r--r--src/xine-engine/video_decoder.c180
-rw-r--r--src/xine-engine/video_decoder.h73
-rw-r--r--src/xine-engine/xine.c607
-rw-r--r--src/xine-engine/xine_internal.h76
21 files changed, 3709 insertions, 0 deletions
diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am
new file mode 100644
index 000000000..993659dc1
--- /dev/null
+++ b/src/xine-engine/Makefile.am
@@ -0,0 +1,82 @@
+##
+## Process this file with automake to produce Makefile.in
+##
+
+CFLAGS = @GLOBAL_CFLAGS@
+
+lib_LTLIBRARIES = libxine.la
+
+if HAVE_W32DLL
+W32_LIBS = $(top_srcdir)/src/libw32dll/libw32dll.la
+endif
+
+##libxine_la_SOURCES = xine.c buffer.c metronom.c configfile.c \
+## monitor.c utils.c audio_decoder.c video_decoder.c load_plugins.c
+libxine_la_SOURCES = metronom.c configfile.c monitor.c utils.c cpu_accel.c
+libxine_la_DEPENDENCIES = libsdeps
+libxine_la_LIBADD = \
+ $(top_srcdir)/src/demuxers/libdemux.la \
+ $(top_srcdir)/src/libmpeg2/libmpeg2.la \
+ $(top_srcdir)/src/libac3/libac3.la \
+ $(top_srcdir)/src/libmpg123/libmpg123.la \
+ $(W32_LIBS) \
+## $(top_srcdir)/src/libspudec/libspudec.la \
+ $(THREAD_LIBS) \
+ $(DYNAMIC_LD_LIBS)
+ -lXext -lm
+libxine_la_LDFLAGS = -version-info 5:0:5
+
+include_HEADERS = buffer.h metronom.h configfile.h \
+ monitor.h cpu_accel.h attributes.h utils.h audio_decoder.h \
+ video_decoder.h
+noinst_HEADERS = xine_internal.h
+
+cpu_accel.lo:
+ $(CC) -DHAVE_CONFIG_H $(INCLUDES) -pipe `echo "@DEBUG_CFLAGS@" | sed -e 's/\-DDEBUG//' -e 's/\-g//'` -fomit-frame-pointer -Wall -Wp,-MD,.deps/cpu_accel.P -c $(basename $@).c -o $@
+# echo timestamp > $(basename $@).o
+
+
+debug:
+ $(MAKE) CFLAGS="$(DEBUG_CFLAGS)"
+
+
+libsdeps:
+## @cd $(top_builddir)/src/demuxers && $(MAKE) libdemux.la
+## @cd $(top_builddir)/src/libmpeg2 && $(MAKE) libmpeg2.la
+## @cd $(top_builddir)/src/libac3 && $(MAKE) libac3.la
+## @cd $(top_builddir)/src/libmpg123 && $(MAKE) libmpg123.la
+##@W32DLL_DEP@ @cd $(top_builddir)/src/libw32dll && $(MAKE) libw32dll.la
+## @cd $(top_builddir)/src/libspudec && $(MAKE) libspudec.la
+
+
+##
+## Install header files (default=$includedir/xine)
+##
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)/xine
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p; \
+ done
+
+
+##
+## Remove them
+##
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/xine/$$p; \
+ done
+
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/xine-engine/attributes.h b/src/xine-engine/attributes.h
new file mode 100644
index 000000000..8ed7aef9e
--- /dev/null
+++ b/src/xine-engine/attributes.h
@@ -0,0 +1,27 @@
+/*
+ * attributes.h
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec 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.
+ *
+ * mpeg2dec 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
+ */
+
+//use gcc attribs to align critical data structures
+#ifdef ATTRIBUTE_ALIGNED_MAX
+#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align)))
+#else
+#define ATTR_ALIGN(align)
+#endif
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
new file mode 100644
index 000000000..f879093e0
--- /dev/null
+++ b/src/xine-engine/audio_decoder.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: audio_decoder.c,v 1.1 2001/04/18 22:36:01 f1rmb Exp $
+ *
+ *
+ * functions that implement audio decoding
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "audio_decoder.h"
+
+#define MAX_NUM_DECODERS 10
+
+typedef struct ad_globals_s {
+
+ pthread_t mAudioThread;
+
+ fifo_buffer_t *mBufAudio;
+
+ audio_decoder_t *mDecoders[MAX_NUM_DECODERS];
+ audio_decoder_t *mCurDecoder;
+
+ uint32_t mnCurPos;
+
+ ao_instance_t *mAudioOut
+
+ gui_status_callback_func_t gui_status_callback;
+
+ int mbStreamFinished;
+
+ pthread_mutex_t mXineLock;
+
+} ad_globals_t;
+
+static ad_globals_t gAD;
+
+
+void *audio_decoder_loop (void *dummy) {
+
+ buf_element_t *pBuf;
+ int bRunning = 1;
+
+ while (bRunning) {
+
+ pBuf = gAD.mBufAudio->fifo_buffer_get (gAD.mBufAudio);
+
+ if (gAD.mAudioOut) {
+
+ gAD.mnCurPos = pBuf->nInputPos;
+
+ /*
+ if (gXine.mnStatus == XINE_PLAY)
+ gXine.mStatusCallback (gXine.mnStatus);
+ */
+
+ switch (pBuf->nType) {
+
+ case BUF_STREAMSTART:
+ if (gAD.mCurDecoder) {
+ gAD.mCurDecoder->close ();
+ gAD.mCurDecoder = NULL;
+ }
+
+ pthread_mutex_lock (&gAD.mXineLock);
+ gAD.mbStreamFinished = 0;
+ pthread_mutex_unlock (&gAD.mXineLock);
+
+ break;
+
+ case BUF_AC3AUDIO:
+ case BUF_MPEGAUDIO:
+ case BUF_MSAUDIO:
+ case BUF_LINEARPCM:
+
+ decoder = gAD.mDecoders [pBuf->nType];
+
+ if (decoder) {
+ if (gAD.mCurDecoder != decoder) {
+
+ if (gAD.mCurDecoder)
+ gAD.mCurDecoder->close ();
+
+ gAD.mCurDecoder = decoder;
+ gAD.mCurDecoder->init (gAD.mVideoOut);
+
+ }
+
+ decoder->decode_data (pBuf);
+ }
+
+ break;
+
+ case BUF_STREAMEND:
+ if (gAD.mCurDecoder) {
+ gAD.mCurDecoder->close ();
+ gAD.mCurDecoder = NULL;
+ }
+
+ gAD.mbStreamFinished = 1;
+
+ pthread_mutex_lock (&gAD.mXineLock);
+
+ gVD.mbStreamFinished = 1;
+
+ if (video_decoder_is_stream_finished ()) {
+ pthread_mutex_unlock (&gAD.mXineLock);
+ xine_notify_stream_finished ();
+ } else
+ pthread_mutex_unlock (&gAD.mXineLock);
+
+ break;
+
+ case BUF_QUIT:
+ if (gAD.mCurDecoder) {
+ gAD.mCurDecoder->close ();
+ gAD.mCurDecoder = NULL;
+ }
+ bRunning = 0;
+ break;
+
+ }
+ }
+ pBuf->free_buffer (pBuf);
+ }
+
+ return NULL;
+}
+
+int audio_decoder_is_stream_finished () {
+ return gAD.mbStreamFinished ;
+}
+
+uint32_t audio_decoder_get_pos () {
+ return gAD.mnCurPos;
+}
+
+fifo_buffer_t *audio_decoder_init (ao_instance_t *audio_out,
+ pthread_mutex_t xine_lock) {
+
+ gAD.mAudioOut = audio_out;
+ gAD.mXineLock = xine_lock;
+
+ gAD.mCurDecoder = NULL;
+ for (i=0; i<MAX_NUM_DECODERS; i++)
+ gAD.mDecoders[i] = NULL;
+
+ gAD.mDecoders[BUF_AC3AUDIO] = init_audio_decoder_ac3dec ();
+ gAD.mDecoders[BUF_MPEGAUDIO] = init_audio_decoder_mpg123 ();
+ gAD.mDecoders[BUF_MSAUDIO] = init_audio_decoder_msaudio ();
+ gAD.mDecoders[BUF_LINEARPCM] = init_audio_decoder_linearpcm ();
+
+ gAD.mBufAudio = fifo_buffer_new ();
+
+ pthread_create (&gAD.mAudioThread, NULL, audio_decoder_loop, NULL) ;
+
+ printf ("audio_decoder_init: audio thread created\n");
+
+ return gAD.mBufAudio;
+}
+
+void audio_decoder_shutdown () {
+
+ buf_element_t *pBuf;
+
+ gAD.mBufAudio->fifo_buffer_clear(gAD.mBufAudio);
+
+ pBuf = gAD.mBufAudio->buffer_pool_alloc ();
+ pBuf->nType = BUF_QUIT;
+ gAD.mBufAudio->fifo_buffer_put (gAD.mBufAudio, pBuf);
+
+ pthread_join (gAD.mAudioThread, &p);
+}
+
+
diff --git a/src/xine-engine/audio_decoder.h b/src/xine-engine/audio_decoder.h
new file mode 100644
index 000000000..b7d6e4243
--- /dev/null
+++ b/src/xine-engine/audio_decoder.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: audio_decoder.h,v 1.1 2001/04/18 22:36:05 f1rmb Exp $
+ *
+ *
+ * functions that implement audio decoding
+ */
+
+#ifndef HAVE_VIDEO_DECODER_H
+#define VIDEO_DECODER_H
+
+#include "buffer.h"
+
+/*
+ * generic xine audio decoder plugin interface
+ */
+
+typedef struct audio_decoder_s
+{
+
+ /* get interface version */
+ int (*get_version) (void);
+
+ int (*can_handle) (int buf_type);
+
+ void (*init) (ao_instance_t *audio_out);
+
+ void (*decode_data) (buf_element_t *buf);
+
+ void (*close) (void);
+
+} audio_decoder_t;
+
+/*
+ * init audio decoders, allocate audio fifo,
+ * start audio decoder thread
+ */
+
+fifo_buffer_t *audio_decoder_init (ao_instance_t *audio_out,
+ pthread_mutex_t xine_lock) ;
+
+/*
+ * quit audio thread
+ */
+
+void audio_decoder_shutdown ();
+
+
+#endif
diff --git a/src/xine-engine/buffer.c b/src/xine-engine/buffer.c
new file mode 100644
index 000000000..c45a93cb6
--- /dev/null
+++ b/src/xine-engine/buffer.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: buffer.c,v 1.1 2001/04/18 22:36:01 f1rmb Exp $
+ *
+ *
+ * contents:
+ *
+ * buffer_entry structure - serves as a transport encapsulation
+ * of the mpeg audio/video data through xine
+ *
+ * free buffer pool management routines
+ *
+ * FIFO buffer structures/routines
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "buffer.h"
+#include "utils.h"
+
+/*
+ * global variables
+ */
+
+buf_element_t *gBufferPoolTop; /* a stack actually */
+pthread_mutex_t gBufferPoolMutex;
+pthread_cond_t gBufferPoolCondNotEmpty;
+int gBufferPoolNumFree;
+
+/*
+ * put a previously allocated buffer element back into the buffer pool
+ */
+static void buffer_pool_free (buf_element_t *pBufElement) {
+
+ pthread_mutex_lock (&gBufferPoolMutex);
+
+ pBufElement->next = gBufferPoolTop;
+ gBufferPoolTop = pBufElement;
+
+ gBufferPoolNumFree++;
+
+ pthread_cond_signal (&gBufferPoolCondNotEmpty);
+
+ pthread_mutex_unlock (&gBufferPoolMutex);
+}
+
+/*
+ * check if there are no more free elements
+ */
+static int buffer_pool_isempty (void) {
+ return gBufferPoolNumFree<7;
+}
+
+/*
+ * check if there are no more free elements
+ */
+static buf_element_t *buffer_pool_alloc (void) {
+
+ buf_element_t *pBuf;
+
+ pthread_mutex_lock (&gBufferPoolMutex);
+
+ while (!gBufferPoolTop) {
+ pthread_cond_wait (&gBufferPoolCondNotEmpty, &gBufferPoolMutex);
+ }
+
+ pBuf = gBufferPoolTop;
+ gBufferPoolTop = gBufferPoolTop->next;
+ gBufferPoolNumFree--;
+
+ pthread_mutex_unlock (&gBufferPoolMutex);
+
+ return pBuf;
+}
+
+/*
+ * append buffer element to fifo buffer
+ */
+static void fifo_buffer_put (fifo_buffer_t *pFifo, buf_element_t *pBufElement) {
+
+ pthread_mutex_lock (&pFifo->mMutex);
+
+ if (pFifo->mpLast)
+ pFifo->mpLast->next = pBufElement;
+ else
+ pFifo->mpFirst = pBufElement;
+
+ pFifo->mpLast = pBufElement;
+ pBufElement->next = NULL;
+
+ pthread_cond_signal (&pFifo->mNotEmpty);
+
+ pthread_mutex_unlock (&pFifo->mMutex);
+}
+
+/*
+ * get element from fifo buffer
+ */
+static buf_element_t *fifo_buffer_get (fifo_buffer_t *pFifo) {
+
+ buf_element_t *pBuf;
+
+ pthread_mutex_lock (&pFifo->mMutex);
+
+ while (pFifo->mpFirst==NULL) {
+ pthread_cond_wait (&pFifo->mNotEmpty, &pFifo->mMutex);
+ }
+
+ pBuf = pFifo->mpFirst;
+
+ pFifo->mpFirst = pFifo->mpFirst->next;
+ if (pFifo->mpFirst==NULL)
+ pFifo->mpLast = NULL;
+
+ pthread_mutex_unlock (&pFifo->mMutex);
+
+ return pBuf;
+}
+
+/*
+ * clear buffer (put all contained buffer elements back into buffer pool)
+ */
+static void fifo_buffer_clear (fifo_buffer_t *pFifo) {
+
+ buf_element_t *pBuf;
+
+ pthread_mutex_lock (&pFifo->mMutex);
+
+ while (pFifo->mpFirst != NULL) {
+
+ pBuf = pFifo->mpFirst;
+
+ pFifo->mpFirst = pFifo->mpFirst->next;
+ if (pFifo->mpFirst==NULL)
+ pFifo->mpLast = NULL;
+
+ buffer_pool_free (pBuf);
+ }
+
+ pthread_mutex_unlock (&pFifo->mMutex);
+}
+
+/*
+ * allocate and initialize new (empty) fifo buffer
+ */
+static fifo_buffer_t *fifo_buffer_new (void) {
+
+ fifo_buffer_t *pFifo;
+
+ pFifo = xmalloc (sizeof (fifo_buffer_t));
+
+ pFifo->mpFirst = NULL;
+ pFifo->mpLast = NULL;
+ pFifo->fifo_buffer_put = fifo_buffer_put;
+ pFifo->fifo_buffer_get = fifo_buffer_get;
+ pFifo->fifo_buffer_clear = fifo_buffer_clear;
+
+ pthread_mutex_init (&pFifo->mMutex, NULL);
+ pthread_cond_init (&pFifo->mNotEmpty, NULL);
+
+ return pFifo;
+}
+
+/*
+ * init buffer pool, allocate nNumBuffers of buf_size bytes each
+ */
+fifobuf_functions_t *buffer_pool_init (int nNumBuffers, uint32_t buf_size) {
+
+ int i;
+ const int alignment = 2048;
+ char *pMultiBuffer = NULL;
+
+ if ((buf_size % alignment) == 0) {
+ printf ("Allocating %d buffers of %ld bytes in one chunk (alignment = %d)\n", nNumBuffers, (long int)buf_size, alignment);
+ pMultiBuffer = xmalloc_aligned (alignment, nNumBuffers * buf_size);
+ }
+
+ gBufferPoolTop = NULL;
+
+ pthread_mutex_init (&gBufferPoolMutex, NULL);
+ pthread_cond_init (&gBufferPoolCondNotEmpty, NULL);
+
+ for (i = 0; i<nNumBuffers; i++) {
+ buf_element_t *pBuf;
+
+ pBuf = xmalloc (sizeof (buf_element_t));
+
+ if (pMultiBuffer != NULL) {
+ pBuf->pMem = pMultiBuffer;
+ pMultiBuffer += buf_size;
+ }
+ else
+ pBuf->pMem = malloc_aligned (buf_size, alignment);
+
+ pBuf->nMaxSize = buf_size;
+ pBuf->free_buffer = buffer_pool_free;
+
+ buffer_pool_free (pBuf);
+ }
+ gBufferPoolNumFree = nNumBuffers;
+
+ return &fifobuf_op;
+}
diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h
new file mode 100644
index 000000000..a57d219ba
--- /dev/null
+++ b/src/xine-engine/buffer.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: buffer.h,v 1.1 2001/04/18 22:36:05 f1rmb Exp $
+ *
+ *
+ * contents:
+ *
+ * buffer_entry structure - serves as a transport encapsulation
+ * of the mpeg audio/video data through xine
+ *
+ * free buffer pool management routines
+ *
+ * FIFO buffer structures/routines
+ *
+ */
+
+#ifndef HAVE_BUFFER_H
+#define HAVE_BUFFER_H
+
+#include <stdio.h>
+#include <pthread.h>
+#include <inttypes.h>
+
+/*
+ * buffer types
+ *
+ * a buffer type ID describes the contents of a buffer
+ * it consists of three fields:
+ *
+ * buf_type = 0xMMDDCCCC
+ *
+ * MM : major buffer type (CONTROL, VIDEO, AUDIO, SPU)
+ * DD : decoder selection (e.g. MPEG, OPENDIVX ... for VIDEO)
+ * CCCC : channel number or other subtype information for the decoder
+ */
+
+#define BUF_MAJOR_MASK 0xFF000000
+#define BUF_DECODER_MASK 0x00FF0000
+
+/* control buffer types */
+
+#define BUF_CONTROL_BASE 0x01000000
+#define BUF_CONTROL_START 0x01000000
+#define BUF_CONTROL_END 0x01000001
+#define BUF_CONTROL_QUIT 0x01000002
+
+/* video buffer types: */
+
+#define BUF_VIDEO_BASE 0x02000000
+#define BUF_VIDEO_MPEG 0x02000000
+#define BUF_VIDEO_OPENDIVX 0x02010000
+#define BUF_VIDEO_QUICKTIME 0x02020000
+#define BUF_VIDEO_AVI 0x02030000
+
+/* audio buffer types: */
+
+#define BUF_AUDIO_BASE 0x03000000
+#define BUF_AUDIO_AC3 0x03000000
+#define BUF_AUDIO_MPEG 0x03010000
+#define BUF_AUDIO_LPCM 0x03020000
+#define BUF_AUDIO_AVI 0x03030000
+
+/* spu buffer types: */
+
+#define BUF_SPU_BASE 0x04000000
+#define BUF_SPU_CLUT 0x04000000
+#define BUF_SPU_PACKAGE 0x04010000
+
+
+typedef struct buf_element_s buf_element_t;
+struct buf_element_s {
+ buf_element_t *next;
+
+ unsigned char *mem;
+ unsigned char *content; /* start of raw content in pMem (without header etc) */
+
+ uint32_t size ; /* size of _content_ */
+ uint32_t max_size;
+ uint32_t type;
+ uint32_t PTS, DTS;
+ off_t input_pos; /* remember where this buf came from in the input source */
+ int frame_end; /* avi */
+
+ void (*free_buffer) (buf_element_t *buf);
+
+} ;
+
+typedef struct fifo_buffer_s fifo_buffer_t;
+struct fifo_buffer_s
+{
+ buf_element_t *first, *last;
+
+ pthread_mutex_t mutex;
+ pthread_cond_t not_empty;
+
+ /*
+ * functions to access this fifo:
+ */
+
+ void (*put) (fifo_buffer_t *fifo, buf_element_t *buf);
+
+ buf_element_t *(*get) (fifo_buffer_t *fifo);
+
+ void (*clear) (fifo_buffer_t *fifo) ;
+
+ /*
+ * alloc buffer for this fifo from global buf pool
+ * you don't have to use this function to allocate a buffer,
+ * an input plugin can decide to implement it's own
+ * buffer allocation functions
+ */
+
+ buf_element_t *(*buffer_pool_alloc) (void);
+
+} ;
+
+/*
+ * allocate and initialize new (empty) fifo buffer
+ */
+
+fifo_buffer_t *fifo_buffer_new (void);
+
+/*
+ * init global buffer pool,
+ * allocate nNumBuffers of buf_size bytes each
+ */
+
+void buffer_pool_init (int num_buffers, uint32_t buf_size);
+
+#endif
diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c
new file mode 100644
index 000000000..1903db791
--- /dev/null
+++ b/src/xine-engine/configfile.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: configfile.c,v 1.1 2001/04/18 22:36:01 f1rmb Exp $
+ *
+ * config file management - implementation
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "configfile.h"
+#include "utils.h"
+
+typedef struct cfg_entry_s {
+ struct cfg_entry_s *next;
+ char *key, *value;
+} cfg_entry_t;
+
+struct cfg_data_s {
+ cfg_entry_t *gConfig, *gConfigLast;
+};
+
+
+
+/*
+ * internal utility functions
+ *******************************/
+
+void config_file_add (config_values_t *this, char *key, char *value) {
+
+ cfg_entry_t *entry;
+ int len;
+
+ entry = (cfg_entry_t *) xmalloc (sizeof (cfg_entry_t));
+
+ len = strlen (key);
+ entry->key = (char *) xmalloc (len+2);
+ strncpy (entry->key, key, len+1);
+
+ len = strlen (value);
+ entry->value = (char *) xmalloc (len+21);
+ strncpy (entry->value, value, len+1);
+
+ entry->next = NULL;
+
+ if (this->data->gConfigLast)
+ this->data->gConfigLast->next = entry;
+ else
+ this->data->gConfig = entry;
+
+ this->data->gConfigLast = entry;
+
+}
+
+
+
+
+cfg_entry_t *config_file_search (config_values_t *this, char *key) {
+ cfg_entry_t *entry;
+
+ entry = this->data->gConfig;
+
+ while (entry && strcmp (entry->key, key))
+ entry = entry->next;
+
+ return entry;
+}
+
+
+
+/*
+ * external interface
+ ***********************/
+
+static char *config_file_lookup_str (config_values_t *this,
+ char *key, char*str_default) {
+ cfg_entry_t *entry;
+
+ entry = config_file_search (this, key);
+
+ if (entry)
+ return entry->value;
+
+ config_file_add (this, key, str_default);
+
+ return str_default;
+}
+
+
+
+
+static int config_file_lookup_int (config_values_t *this,
+ char *key, int n_default) {
+
+ cfg_entry_t *entry;
+ char str[25];
+
+ entry = config_file_search (this, key);
+
+ if (entry) {
+ int n;
+
+ if (sscanf (entry->value, "%d", &n) == 1)
+ return n;
+ }
+
+ sprintf (str, "%d", n_default);
+
+ config_file_add (this, key, str);
+
+ return n_default;
+}
+
+
+
+
+static void config_file_set_int (config_values_t *this,
+ char *key, int value) {
+
+ cfg_entry_t *entry;
+
+ entry = config_file_search (this, key);
+
+ if (entry) {
+ sprintf (entry->value, "%d", value);
+ }
+ else {
+ char str[25];
+ sprintf (str, "%d", value);
+
+ config_file_add (this, key, str);
+ }
+}
+
+
+
+
+static void config_file_set_str (config_values_t *this,
+ char *key, char *value) {
+
+ cfg_entry_t *entry;
+
+ entry = config_file_search (this, key);
+
+ if (entry) {
+ int len;
+
+ free (entry->value);
+
+ len = strlen (value);
+ entry->value = (char *) xmalloc (len+20);
+ strncpy (entry->value, value, len);
+
+ }
+ else {
+ config_file_add (this, key, value);
+ }
+}
+
+
+
+
+static void config_file_save (config_values_t *this) {
+ FILE *f_config;
+ char filename[1024];
+
+ sprintf (filename, "%s/.xinerc", get_homedir());
+
+ f_config = fopen (filename, "w");
+
+ if (f_config) {
+
+ cfg_entry_t *entry;
+
+ fprintf (f_config, "#\n# xine config file\n#\n");
+
+ entry = this->data->gConfig;
+
+ while (entry) {
+ fprintf (f_config, "%s:%s\n",entry->key,entry->value);
+ entry = entry->next;
+ }
+
+ fclose (f_config);
+ }
+}
+
+
+
+
+static void config_file_read (config_values_t *this, char *filename){
+
+ FILE *f_config;
+
+ f_config = fopen (filename, "r");
+
+ if (f_config) {
+
+ char line[1024];
+ char *value;
+
+ while (fgets (line, 1023, f_config)) {
+ line[strlen(line)-1]= (char) 0; /* eliminate lf */
+
+ if (line[0] == '#')
+ continue;
+
+ if ((value = strchr (line, ':'))) {
+ *value = (char) 0;
+ value++;
+
+ config_file_add (this, line, value);
+ }
+
+ }
+
+ fclose (f_config);
+ }
+}
+
+
+
+
+config_values_t *config_file_init (char *filename) {
+
+ config_values_t *this;
+ cfg_data_t *data;
+
+ if ( (this = xmalloc(sizeof(config_values_t))) ) {
+ if ( (data = xmalloc(sizeof(cfg_data_t))) ) {
+ data->gConfig = NULL;
+ data->gConfigLast = NULL;
+ this->data = data;
+ config_file_read (this, filename);
+
+ }
+ else {
+ fprintf (stderr, "WARNING: could not allocate config data\n");
+ }
+ }
+ else {
+ fprintf (stderr, "WARNING: could not allocate config values list\n");
+ }
+
+ this->lookup_str = config_file_lookup_str;
+ this->lookup_int = config_file_lookup_int;
+ this->set_str = config_file_set_str;
+ this->set_int = config_file_set_int;
+ this->save = config_file_save;
+ this->read = config_file_read;
+
+ return this;
+}
+
+
+/*
+ * $Log: configfile.c,v $
+ * Revision 1.1 2001/04/18 22:36:01 f1rmb
+ * Initial revision
+ *
+ * Revision 1.8 2001/03/31 03:42:25 guenter
+ * more cleanups, started xv driver
+ *
+ * Revision 1.7 2001/03/28 12:30:25 siggi
+ * fixed init function
+ * added read function (multiple config files now supported)
+ *
+ * Revision 1.6 2001/03/27 17:12:49 siggi
+ * made config file handler a dynamic "object"
+ *
+ */
diff --git a/src/xine-engine/configfile.h b/src/xine-engine/configfile.h
new file mode 100644
index 000000000..1e5de7be9
--- /dev/null
+++ b/src/xine-engine/configfile.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: configfile.h,v 1.1 2001/04/18 22:36:05 f1rmb Exp $
+ *
+ * config file management
+ *
+ */
+
+
+#ifndef HAVE_CONFIGFILE_H
+#define HAVE_CONFIGFILE_H
+
+#include <inttypes.h>
+
+typedef struct config_values_s config_values_t;
+typedef struct cfg_data_s cfg_data_t;
+
+struct config_values_s {
+ /*
+ * lookup config values
+ */
+ char* (*lookup_str) (config_values_t *this,
+ char *key, char *str_default);
+
+ int (*lookup_int) (config_values_t *this,
+ char *key, int n_default);
+
+ /*
+ * set config values
+ */
+
+ void (*set_str) (config_values_t *this,
+ char *key, char *value) ;
+
+ void (*set_int) (config_values_t *this,
+ char *key, int value) ;
+
+ /*
+ * write config file to disk
+ */
+ void (*save) (config_values_t *this);
+
+ /*
+ * read config file from disk, ovverriding values in memory
+ * if you also want to clear values that are not in the file,
+ * use _init instead!
+ */
+ void (*read) (config_values_t *this, char *filename);
+
+ /*
+ * contains private data of this config file
+ */
+ cfg_data_t *data;
+};
+
+/*
+ * init internal data structures, read config file
+ * (if it exists)
+ */
+config_values_t *config_file_init (char *filename);
+
+
+#endif
+
+/*
+ * $Log: configfile.h,v $
+ * Revision 1.1 2001/04/18 22:36:05 f1rmb
+ * Initial revision
+ *
+ * Revision 1.6 2001/03/31 03:42:25 guenter
+ * more cleanups, started xv driver
+ *
+ * Revision 1.5 2001/03/28 12:30:25 siggi
+ * fixed init function
+ * added read function (multiple config files now supported)
+ *
+ * Revision 1.4 2001/03/27 21:49:02 siggi
+ * started touching demuxers
+ *
+ */
+
+
+
+
diff --git a/src/xine-engine/cpu_accel.c b/src/xine-engine/cpu_accel.c
new file mode 100644
index 000000000..bd3a55fc0
--- /dev/null
+++ b/src/xine-engine/cpu_accel.c
@@ -0,0 +1,110 @@
+/*
+ * cpu_accel.c
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec 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.
+ *
+ * mpeg2dec 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
+ */
+
+#include "config.h"
+
+#include <inttypes.h>
+
+#include "attributes.h"
+#include "cpu_accel.h"
+
+#ifdef ARCH_X86
+static uint32_t x86_accel (void)
+{
+ uint32_t eax, ebx, ecx, edx;
+ int AMD;
+ uint32_t caps;
+
+#define cpuid(op,eax,ebx,ecx,edx) \
+ asm ("cpuid" \
+ : "=a" (eax), \
+ "=b" (ebx), \
+ "=c" (ecx), \
+ "=d" (edx) \
+ : "a" (op) \
+ : "cc")
+
+ asm ("pushfl\n\t"
+ "popl %0\n\t"
+ "movl %0,%1\n\t"
+ "xorl $0x200000,%0\n\t"
+ "pushl %0\n\t"
+ "popfl\n\t"
+ "pushfl\n\t"
+ "popl %0"
+ : "=a" (eax),
+ "=b" (ebx)
+ :
+ : "cc");
+
+ if (eax == ebx) /* no cpuid */
+ return 0;
+
+ cpuid (0x00000000, eax, ebx, ecx, edx);
+ if (!eax) /* vendor string only */
+ return 0;
+
+ AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65);
+
+ cpuid (0x00000001, eax, ebx, ecx, edx);
+ if (! (edx & 0x00800000)) /* no MMX */
+ return 0;
+
+ caps = MM_ACCEL_X86_MMX;
+ if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */
+ caps = MM_ACCEL_X86_MMX | MM_ACCEL_X86_MMXEXT;
+
+ cpuid (0x80000000, eax, ebx, ecx, edx);
+ if (eax < 0x80000001) /* no extended capabilities */
+ return caps;
+
+ cpuid (0x80000001, eax, ebx, ecx, edx);
+
+ if (edx & 0x80000000)
+ caps |= MM_ACCEL_X86_3DNOW;
+
+ if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */
+ caps |= MM_ACCEL_X86_MMXEXT;
+
+ return caps;
+}
+#endif
+
+uint32_t mm_accel (void)
+{
+#ifdef ARCH_X86
+ static int got_accel = 0;
+ static uint32_t accel;
+
+ if (!got_accel) {
+ got_accel = 1;
+ accel = x86_accel ();
+ }
+
+ return accel;
+#else
+#ifdef HAVE_MLIB
+ return MM_ACCEL_MLIB;
+#else
+ return 0;
+#endif
+#endif
+}
diff --git a/src/xine-engine/cpu_accel.h b/src/xine-engine/cpu_accel.h
new file mode 100644
index 000000000..9583b6681
--- /dev/null
+++ b/src/xine-engine/cpu_accel.h
@@ -0,0 +1,514 @@
+/*
+ * cpu_accel.h - based on mmx.h, sse.h
+ * Copyright (C) 1997-1999 H. Dietz and R. Fisher
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec 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.
+ *
+ * mpeg2dec 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
+ *
+ * xine specific modifications 2001 by G. Bartsch
+ *
+ */
+
+/*
+ * The type of an value that fits in an MMX register (note that long
+ * long constant values MUST be suffixed by LL and unsigned long long
+ * values by ULL, lest they be truncated by the compiler)
+ */
+
+#ifndef _CPU_ACCEL_H
+#define _CPU_ACCEL_H
+
+#include "attributes.h"
+
+/* generic accelerations */
+#define MM_ACCEL_MLIB 0x00000001
+
+/* x86 accelerations */
+#define MM_ACCEL_X86_MMX 0x80000000
+#define MM_ACCEL_X86_3DNOW 0x40000000
+#define MM_ACCEL_X86_MMXEXT 0x20000000
+
+uint32_t mm_accel (void) ;
+
+#ifdef ARCH_X86
+
+typedef union {
+ long long q; /* Quadword (64-bit) value */
+ unsigned long long uq; /* Unsigned Quadword */
+ int d[2]; /* 2 Doubleword (32-bit) values */
+ unsigned int ud[2]; /* 2 Unsigned Doubleword */
+ short w[4]; /* 4 Word (16-bit) values */
+ unsigned short uw[4]; /* 4 Unsigned Word */
+ char b[8]; /* 8 Byte (8-bit) values */
+ unsigned char ub[8]; /* 8 Unsigned Byte */
+ float s[2]; /* Single-precision (32-bit) value */
+} ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */
+
+
+
+#define mmx_i2r(op,imm,reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define mmx_m2r(op,mem,reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define mmx_r2m(op,reg,mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ )
+
+#define mmx_r2r(op,regs,regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+
+#define emms() __asm__ __volatile__ ("emms")
+
+#define movd_m2r(var,reg) mmx_m2r (movd, var, reg)
+#define movd_r2m(reg,var) mmx_r2m (movd, reg, var)
+#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd)
+
+#define movq_m2r(var,reg) mmx_m2r (movq, var, reg)
+#define movq_r2m(reg,var) mmx_r2m (movq, reg, var)
+#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd)
+
+#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg)
+#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd)
+#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg)
+#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd)
+
+#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg)
+#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd)
+
+#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg)
+#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd)
+#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg)
+#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd)
+#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg)
+#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd)
+
+#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg)
+#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd)
+#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg)
+#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd)
+
+#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg)
+#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd)
+#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg)
+#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd)
+
+#define pand_m2r(var,reg) mmx_m2r (pand, var, reg)
+#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd)
+
+#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg)
+#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd)
+
+#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg)
+#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd)
+#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg)
+#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd)
+#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg)
+#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd)
+
+#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg)
+#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd)
+#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg)
+#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd)
+#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg)
+#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd)
+
+#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg)
+#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd)
+
+#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg)
+#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd)
+
+#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg)
+#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd)
+
+#define por_m2r(var,reg) mmx_m2r (por, var, reg)
+#define por_r2r(regs,regd) mmx_r2r (por, regs, regd)
+
+#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg)
+#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg)
+#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd)
+#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg)
+#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg)
+#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd)
+#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg)
+#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg)
+#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd)
+
+#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg)
+#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg)
+#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd)
+#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg)
+#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg)
+#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd)
+
+#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg)
+#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg)
+#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd)
+#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg)
+#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg)
+#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd)
+#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg)
+#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg)
+#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd)
+
+#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg)
+#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd)
+#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg)
+#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd)
+#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg)
+#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd)
+
+#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg)
+#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd)
+#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg)
+#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd)
+
+#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg)
+#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd)
+#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg)
+#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd)
+
+#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg)
+#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd)
+#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg)
+#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd)
+#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg)
+#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd)
+
+#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg)
+#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd)
+#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg)
+#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd)
+#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg)
+#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd)
+
+#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg)
+#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd)
+
+
+/* 3DNOW extensions */
+
+#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg)
+#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd)
+
+
+/* AMD MMX extensions - also available in intel SSE */
+
+
+#define mmx_m2ri(op,mem,reg,imm) \
+ __asm__ __volatile__ (#op " %1, %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem), "X" (imm))
+#define mmx_r2ri(op,regs,regd,imm) \
+ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define mmx_fetch(mem,hint) \
+ __asm__ __volatile__ ("prefetch" #hint " %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+
+#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg)
+
+#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var)
+
+#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg)
+#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd)
+#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg)
+#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd)
+
+#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm)
+
+#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm)
+
+#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg)
+#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd)
+
+#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg)
+#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd)
+
+#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg)
+#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd)
+
+#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg)
+#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd)
+
+#define pmovmskb(mmreg,reg) \
+ __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
+
+#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg)
+#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd)
+
+#define prefetcht0(mem) mmx_fetch (mem, t0)
+#define prefetcht1(mem) mmx_fetch (mem, t1)
+#define prefetcht2(mem) mmx_fetch (mem, t2)
+#define prefetchnta(mem) mmx_fetch (mem, nta)
+
+#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg)
+#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd)
+
+#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm)
+#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm)
+
+#define sfence() __asm__ __volatile__ ("sfence\n\t")
+
+typedef union {
+ float sf[4]; /* Single-precision (32-bit) value */
+} ATTR_ALIGN(16) sse_t; /* On a 16 byte (128-bit) boundary */
+
+
+#define sse_i2r(op, imm, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define sse_m2r(op, mem, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define sse_r2m(op, reg, mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ )
+
+#define sse_r2r(op, regs, regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+#define sse_r2ri(op, regs, regd, imm) \
+ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define sse_m2ri(op, mem, reg, subop) \
+ __asm__ __volatile__ (#op " %0, %%" #reg ", " #subop \
+ : /* nothing */ \
+ : "X" (mem))
+
+
+#define movaps_m2r(var, reg) sse_m2r(movaps, var, reg)
+#define movaps_r2m(reg, var) sse_r2m(movaps, reg, var)
+#define movaps_r2r(regs, regd) sse_r2r(movaps, regs, regd)
+
+#define movntps_r2m(xmmreg, var) sse_r2m(movntps, xmmreg, var)
+
+#define movups_m2r(var, reg) sse_m2r(movups, var, reg)
+#define movups_r2m(reg, var) sse_r2m(movups, reg, var)
+#define movups_r2r(regs, regd) sse_r2r(movups, regs, regd)
+
+#define movhlps_r2r(regs, regd) sse_r2r(movhlps, regs, regd)
+
+#define movlhps_r2r(regs, regd) sse_r2r(movlhps, regs, regd)
+
+#define movhps_m2r(var, reg) sse_m2r(movhps, var, reg)
+#define movhps_r2m(reg, var) sse_r2m(movhps, reg, var)
+
+#define movlps_m2r(var, reg) sse_m2r(movlps, var, reg)
+#define movlps_r2m(reg, var) sse_r2m(movlps, reg, var)
+
+#define movss_m2r(var, reg) sse_m2r(movss, var, reg)
+#define movss_r2m(reg, var) sse_r2m(movss, reg, var)
+#define movss_r2r(regs, regd) sse_r2r(movss, regs, regd)
+
+#define shufps_m2r(var, reg, index) sse_m2ri(shufps, var, reg, index)
+#define shufps_r2r(regs, regd, index) sse_r2ri(shufps, regs, regd, index)
+
+#define cvtpi2ps_m2r(var, xmmreg) sse_m2r(cvtpi2ps, var, xmmreg)
+#define cvtpi2ps_r2r(mmreg, xmmreg) sse_r2r(cvtpi2ps, mmreg, xmmreg)
+
+#define cvtps2pi_m2r(var, mmreg) sse_m2r(cvtps2pi, var, mmreg)
+#define cvtps2pi_r2r(xmmreg, mmreg) sse_r2r(cvtps2pi, mmreg, xmmreg)
+
+#define cvttps2pi_m2r(var, mmreg) sse_m2r(cvttps2pi, var, mmreg)
+#define cvttps2pi_r2r(xmmreg, mmreg) sse_r2r(cvttps2pi, mmreg, xmmreg)
+
+#define cvtsi2ss_m2r(var, xmmreg) sse_m2r(cvtsi2ss, var, xmmreg)
+#define cvtsi2ss_r2r(reg, xmmreg) sse_r2r(cvtsi2ss, reg, xmmreg)
+
+#define cvtss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg)
+#define cvtss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg)
+
+#define cvttss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg)
+#define cvttss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg)
+
+#define movmskps(xmmreg, reg) \
+ __asm__ __volatile__ ("movmskps %" #xmmreg ", %" #reg)
+
+#define addps_m2r(var, reg) sse_m2r(addps, var, reg)
+#define addps_r2r(regs, regd) sse_r2r(addps, regs, regd)
+
+#define addss_m2r(var, reg) sse_m2r(addss, var, reg)
+#define addss_r2r(regs, regd) sse_r2r(addss, regs, regd)
+
+#define subps_m2r(var, reg) sse_m2r(subps, var, reg)
+#define subps_r2r(regs, regd) sse_r2r(subps, regs, regd)
+
+#define subss_m2r(var, reg) sse_m2r(subss, var, reg)
+#define subss_r2r(regs, regd) sse_r2r(subss, regs, regd)
+
+#define mulps_m2r(var, reg) sse_m2r(mulps, var, reg)
+#define mulps_r2r(regs, regd) sse_r2r(mulps, regs, regd)
+
+#define mulss_m2r(var, reg) sse_m2r(mulss, var, reg)
+#define mulss_r2r(regs, regd) sse_r2r(mulss, regs, regd)
+
+#define divps_m2r(var, reg) sse_m2r(divps, var, reg)
+#define divps_r2r(regs, regd) sse_r2r(divps, regs, regd)
+
+#define divss_m2r(var, reg) sse_m2r(divss, var, reg)
+#define divss_r2r(regs, regd) sse_r2r(divss, regs, regd)
+
+#define rcpps_m2r(var, reg) sse_m2r(rcpps, var, reg)
+#define rcpps_r2r(regs, regd) sse_r2r(rcpps, regs, regd)
+
+#define rcpss_m2r(var, reg) sse_m2r(rcpss, var, reg)
+#define rcpss_r2r(regs, regd) sse_r2r(rcpss, regs, regd)
+
+#define rsqrtps_m2r(var, reg) sse_m2r(rsqrtps, var, reg)
+#define rsqrtps_r2r(regs, regd) sse_r2r(rsqrtps, regs, regd)
+
+#define rsqrtss_m2r(var, reg) sse_m2r(rsqrtss, var, reg)
+#define rsqrtss_r2r(regs, regd) sse_r2r(rsqrtss, regs, regd)
+
+#define sqrtps_m2r(var, reg) sse_m2r(sqrtps, var, reg)
+#define sqrtps_r2r(regs, regd) sse_r2r(sqrtps, regs, regd)
+
+#define sqrtss_m2r(var, reg) sse_m2r(sqrtss, var, reg)
+#define sqrtss_r2r(regs, regd) sse_r2r(sqrtss, regs, regd)
+
+#define andps_m2r(var, reg) sse_m2r(andps, var, reg)
+#define andps_r2r(regs, regd) sse_r2r(andps, regs, regd)
+
+#define andnps_m2r(var, reg) sse_m2r(andnps, var, reg)
+#define andnps_r2r(regs, regd) sse_r2r(andnps, regs, regd)
+
+#define orps_m2r(var, reg) sse_m2r(orps, var, reg)
+#define orps_r2r(regs, regd) sse_r2r(orps, regs, regd)
+
+#define xorps_m2r(var, reg) sse_m2r(xorps, var, reg)
+#define xorps_r2r(regs, regd) sse_r2r(xorps, regs, regd)
+
+#define maxps_m2r(var, reg) sse_m2r(maxps, var, reg)
+#define maxps_r2r(regs, regd) sse_r2r(maxps, regs, regd)
+
+#define maxss_m2r(var, reg) sse_m2r(maxss, var, reg)
+#define maxss_r2r(regs, regd) sse_r2r(maxss, regs, regd)
+
+#define minps_m2r(var, reg) sse_m2r(minps, var, reg)
+#define minps_r2r(regs, regd) sse_r2r(minps, regs, regd)
+
+#define minss_m2r(var, reg) sse_m2r(minss, var, reg)
+#define minss_r2r(regs, regd) sse_r2r(minss, regs, regd)
+
+#define cmpps_m2r(var, reg, op) sse_m2ri(cmpps, var, reg, op)
+#define cmpps_r2r(regs, regd, op) sse_r2ri(cmpps, regs, regd, op)
+
+#define cmpeqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 0)
+#define cmpeqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 0)
+
+#define cmpltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 1)
+#define cmpltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 1)
+
+#define cmpleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 2)
+#define cmpleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 2)
+
+#define cmpunordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 3)
+#define cmpunordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 3)
+
+#define cmpneqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 4)
+#define cmpneqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 4)
+
+#define cmpnltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 5)
+#define cmpnltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 5)
+
+#define cmpnleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 6)
+#define cmpnleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 6)
+
+#define cmpordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 7)
+#define cmpordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 7)
+
+#define cmpss_m2r(var, reg, op) sse_m2ri(cmpss, var, reg, op)
+#define cmpss_r2r(regs, regd, op) sse_r2ri(cmpss, regs, regd, op)
+
+#define cmpeqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 0)
+#define cmpeqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 0)
+
+#define cmpltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 1)
+#define cmpltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 1)
+
+#define cmpless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 2)
+#define cmpless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 2)
+
+#define cmpunordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 3)
+#define cmpunordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 3)
+
+#define cmpneqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 4)
+#define cmpneqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 4)
+
+#define cmpnltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 5)
+#define cmpnltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 5)
+
+#define cmpnless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 6)
+#define cmpnless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 6)
+
+#define cmpordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 7)
+#define cmpordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 7)
+
+#define comiss_m2r(var, reg) sse_m2r(comiss, var, reg)
+#define comiss_r2r(regs, regd) sse_r2r(comiss, regs, regd)
+
+#define ucomiss_m2r(var, reg) sse_m2r(ucomiss, var, reg)
+#define ucomiss_r2r(regs, regd) sse_r2r(ucomiss, regs, regd)
+
+#define unpcklps_m2r(var, reg) sse_m2r(unpcklps, var, reg)
+#define unpcklps_r2r(regs, regd) sse_r2r(unpcklps, regs, regd)
+
+#define unpckhps_m2r(var, reg) sse_m2r(unpckhps, var, reg)
+#define unpckhps_r2r(regs, regd) sse_r2r(unpckhps, regs, regd)
+
+#define fxrstor(mem) \
+ __asm__ __volatile__ ("fxrstor %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define fxsave(mem) \
+ __asm__ __volatile__ ("fxsave %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define stmxcsr(mem) \
+ __asm__ __volatile__ ("stmxcsr %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define ldmxcsr(mem) \
+ __asm__ __volatile__ ("ldmxcsr %0" \
+ : /* nothing */ \
+ : "X" (mem))
+#endif /*ARCH_X86 */
+
+#endif
+
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
new file mode 100644
index 000000000..4984566db
--- /dev/null
+++ b/src/xine-engine/load_plugins.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: load_plugins.c,v 1.1 2001/04/18 22:36:09 f1rmb Exp $
+ *
+ *
+ * Load input/demux/audio_out/video_out plugins
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <dlfcn.h>
+
+#include "xine.h"
+#include "xine_internal.h"
+#include "demuxers/demux.h"
+#include "input/input_plugin.h"
+#include "metronom.h"
+#include "configfile.h"
+#include "monitor.h"
+
+/* debugging purposes only */
+extern uint32_t xine_debug;
+
+/*
+ *
+ */
+void xine_load_demux_plugins (xine_t *this) {
+ DIR *dir;
+
+ this->demuxer_plugins[0] = *(init_demux_mpeg (xine_debug));
+ this->demuxer_plugins[1] = *(init_demux_mpeg_block (xine_debug));
+ this->demuxer_plugins[2] = *(init_demux_avi (xine_debug));
+ this->demuxer_plugins[3] = *(init_demux_mpeg_audio (xine_debug));
+ this->demuxer_plugins[4] = *(init_demux_mpeg_elem (xine_debug));
+ this->num_demuxer_plugins = 5;
+
+ dir = opendir (XINE_DEMUXDIR) ;
+
+ if (dir) {
+ struct dirent *pEntry;
+
+ while ((pEntry = readdir (dir)) != NULL) {
+ char str[1024];
+ void *plugin;
+
+ int nLen = strlen (pEntry->d_name);
+
+ if ((strncasecmp(pEntry->d_name, "demux_", 6) == 0) &&
+ ((pEntry->d_name[nLen-3]=='.')
+ && (pEntry->d_name[nLen-2]=='s')
+ && (pEntry->d_name[nLen-1]=='o'))) {
+
+ /*
+ * demux plugin found => load it
+ */
+
+ sprintf (str, "%s/%s", XINE_DEMUXDIR, pEntry->d_name);
+
+ if(!(plugin = dlopen (str, RTLD_LAZY))) {
+ fprintf(stderr, "%s(%d): %s doesn't seem to be installed (%s)\n",
+ __FILE__, __LINE__, str, dlerror());
+ exit(1);
+ }
+ else {
+ void *(*getinfo) (fifobuf_functions_t *, uint32_t);
+
+ if((getinfo = dlsym(plugin, "demux_plugin_getinfo")) != NULL) {
+ demux_functions_t *dxp;
+
+ dxp = (demux_functions_t *) getinfo(this->fifo_funcs, xine_debug);
+ dxp->handle = plugin;
+ dxp->filename = str;
+ this->demuxer_plugins[this->num_demuxer_plugins] = *dxp;
+
+
+ printf("demux plugin found : %s(%s)\n",
+ this->demuxer_plugins[this->num_demuxer_plugins].filename,
+ pEntry->d_name);
+
+ this->num_demuxer_plugins++;
+ }
+
+ if(this->num_demuxer_plugins > DEMUXER_PLUGIN_MAX) {
+ fprintf(stderr, "%s(%d): too many demux plugins installed, "
+ "exiting.\n", __FILE__, __LINE__);
+ exit(1);
+ }
+ }
+ }
+ }
+ }
+
+ if (this->num_demuxer_plugins == 5)
+ printf ("No extra demux plugins found in %s\n", XINE_DEMUXDIR);
+
+ /*
+ * init demuxer
+ */
+
+ this->cur_demuxer_plugin = NULL;
+}
+
+/*
+ *
+ */
+void xine_load_input_plugins (xine_t *this) {
+ DIR *dir;
+
+ this->num_input_plugins = 0;
+
+ dir = opendir (XINE_PLUGINDIR) ;
+
+ if (dir) {
+ struct dirent *pEntry;
+
+ while ((pEntry = readdir (dir)) != NULL) {
+
+ char str[1024];
+ void *plugin;
+
+ int nLen = strlen (pEntry->d_name);
+
+ if ((strncasecmp(pEntry->d_name, "input_", 6) == 0) &&
+ ((pEntry->d_name[nLen-3]=='.')
+ && (pEntry->d_name[nLen-2]=='s')
+ && (pEntry->d_name[nLen-1]=='o'))) {
+
+ /*
+ * input plugin found => load it
+ */
+
+ sprintf (str, "%s/%s", XINE_PLUGINDIR, pEntry->d_name);
+
+ if(!(plugin = dlopen (str, RTLD_LAZY))) {
+ fprintf(stderr, "%s(%d): %s doesn't seem to be installed (%s)\n",
+ __FILE__, __LINE__, str, dlerror());
+ exit(1);
+ }
+ else {
+ void *(*getinfo) (uint32_t);
+
+ if((getinfo = dlsym(plugin, "input_plugin_getinfo")) != NULL) {
+ input_plugin_t *ipp;
+
+ ipp = (input_plugin_t *) getinfo(xine_debug);
+ ipp->handle = plugin;
+ ipp->filename = str;
+ this->input_plugins[this->num_input_plugins] = *ipp;
+
+ this->input_plugins[this->num_input_plugins].init();
+
+ printf("input plugin found : %s(%s)\n",
+ this->input_plugins[this->num_input_plugins].filename,
+ pEntry->d_name);
+
+ this->num_input_plugins++;
+
+ }
+
+ if(this->num_input_plugins > INPUT_PLUGIN_MAX) {
+ fprintf(stderr, "%s(%d): too many input plugins installed, "
+ "exiting.\n", __FILE__, __LINE__);
+ exit(1);
+ }
+ }
+ }
+ }
+ }
+
+ if (this->num_input_plugins == 0) {
+ printf ("No input plugins found in %s! - "
+ "Did you install xine correctly??\n", XINE_PLUGINDIR);
+ exit (1);
+ }
+
+}
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
new file mode 100644
index 000000000..e71f2b8b6
--- /dev/null
+++ b/src/xine-engine/metronom.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: metronom.c,v 1.1 2001/04/18 22:36:04 f1rmb Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/time.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <math.h>
+
+#include "monitor.h"
+#include "xine.h"
+#include "xine_internal.h"
+#include "metronom.h"
+#include "utils.h"
+
+#define MAX_PTS_TOLERANCE 5000
+#define MAX_VIDEO_DELTA 1600
+#define AUDIO_SAMPLE_NUM 32768
+
+static void metronom_reset (metronom_t *this) {
+
+ this->video_vpts = 0;
+ this->audio_vpts = 0;
+
+ this->video_pts_delta = 0;
+ this->audio_pts_delta = 0;
+
+ this->last_video_pts = 0;
+ this->num_video_vpts_guessed = 1;
+ this->num_audio_samples_guessed = 1;
+
+ this->sync_pts = 0;
+ this->sync_vpts = 0;
+
+ this->av_offset = 0;
+
+ this->stopped = 1;
+}
+
+static void metronom_set_video_rate (metronom_t *this, uint32_t pts_per_frame) {
+ this->pts_per_frame = pts_per_frame;
+}
+
+static uint32_t metronom_get_video_rate (metronom_t *this) {
+ return this->pts_per_frame + this->video_pts_delta;
+}
+
+static void metronom_set_audio_rate (metronom_t *this, uint32_t pts_per_smpls) {
+ this->pts_per_smpls = pts_per_smpls;
+
+ xprintf (METRONOM | VERBOSE, "metronom: %d pts per %d samples\n", pts_per_smpls, AUDIO_SAMPLE_NUM);
+
+}
+
+static uint32_t metronom_got_spu_packet (metronom_t *this, uint32_t pts) {
+ /* FIXME: Nasty hack */
+
+ return this->sync_pts;
+}
+
+static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts) {
+
+ uint32_t vpts;
+
+ if (pts) {
+
+ /*
+ * calc delta to compensate wrong framerates
+ */
+
+ if (this->last_video_vpts && (pts>this->last_video_pts)) {
+ int32_t vpts_diff;
+ uint32_t synced_vpts ;
+ int32_t diff;
+
+ diff = pts - this->last_video_pts;
+ synced_vpts = this->last_video_vpts + diff;
+ vpts_diff = synced_vpts - this->video_vpts;
+
+ this->video_pts_delta += vpts_diff / (this->num_video_vpts_guessed);
+
+ if (abs(this->video_pts_delta) >= MAX_VIDEO_DELTA)
+ this->video_pts_delta = 0;
+
+ this->num_video_vpts_guessed = 0;
+ /* printf ("delta: %d\n", this->video_pts_delta); */
+ }
+
+ /*
+ * sync if necessary and possible
+ */
+
+ if (this->sync_vpts && (pts>this->sync_pts)) {
+
+ int32_t vpts_diff;
+ uint32_t synced_vpts ;
+ int32_t diff;
+
+ diff = pts - this->sync_pts;
+ synced_vpts = this->sync_vpts + diff;
+ vpts_diff = synced_vpts - this->video_vpts;
+
+ xprintf (METRONOM | VERBOSE, "metronom: video calced vpts : %d <=> synced vpts : %d (diff: %d, delta: %d)\n",
+ this->video_vpts, synced_vpts, vpts_diff, this->video_pts_delta);
+
+ if (abs(vpts_diff)>MAX_PTS_TOLERANCE) {
+ if (synced_vpts>this->video_vpts) {
+ this->video_vpts = synced_vpts;
+ }
+ } else
+ xprintf (METRONOM | VERBOSE, "metronom: video tolerating diff\n");
+
+ } else
+ xprintf (METRONOM | VERBOSE, "metronom: video not synced on this one\n");
+
+ this->sync_pts = pts;
+ this->sync_vpts = this->video_vpts;
+ this->last_video_vpts = this->video_vpts;
+ this->last_video_pts = pts;
+ }
+
+ vpts = this->video_vpts;
+ this->video_vpts += this->pts_per_frame + this->video_pts_delta;
+ this->num_video_vpts_guessed++ ;
+
+ xprintf (METRONOM | VERBOSE, "metronom: video vpts for %10d : %10d\n", pts, vpts);
+
+ return vpts + this->av_offset;
+}
+
+
+static uint32_t metronom_got_audio_samples (metronom_t *this, uint32_t pts, uint32_t nsamples) {
+
+ uint32_t vpts;
+
+ xprintf (METRONOM | VERBOSE, "metronom: got %d audio samples (pts=%d)\n",
+ nsamples,pts);
+
+ if (pts) {
+ int32_t diff;
+
+ diff = pts - this->sync_pts;
+
+ if (this->sync_vpts && (pts>this->sync_pts)) {
+
+ int32_t vpts_diff;
+ uint32_t synced_vpts = this->sync_vpts + diff;
+
+ vpts_diff = synced_vpts - this->audio_vpts;
+
+ xprintf (METRONOM | VERBOSE, "metronom: audio calced vpts : %d <=> synced vpts : %d (diff: %d, delta: %d)\n",
+ this->audio_vpts, synced_vpts, vpts_diff, this->audio_pts_delta);
+ if (abs(vpts_diff)>5000) {
+
+ /* calc delta for wrong samplerates */
+
+ this->audio_pts_delta += vpts_diff*AUDIO_SAMPLE_NUM / (this->num_audio_samples_guessed);
+
+ if (abs(this->audio_pts_delta) >= 10000)
+ this->audio_pts_delta = 0;
+
+ if (synced_vpts>this->audio_vpts)
+ this->audio_vpts = synced_vpts;
+
+ } else
+ xprintf (METRONOM | VERBOSE, "metronom: audio tolerating diff\n");
+
+ } else
+ xprintf (METRONOM | VERBOSE, "metronom: audio not synced on this one\n");
+
+ this->sync_pts = pts;
+ this->sync_vpts = this->audio_vpts;
+ this->num_audio_samples_guessed = 0;
+ }
+
+ vpts = this->audio_vpts;
+ this->audio_vpts += nsamples * (this->audio_pts_delta + this->pts_per_smpls) / AUDIO_SAMPLE_NUM;
+ this->num_audio_samples_guessed += nsamples;
+
+ xprintf (METRONOM | VERBOSE, "metronom: audio vpts for %10d : %10d\n", pts, vpts);
+
+ return vpts;
+}
+
+static void metronom_set_av_offset (metronom_t *this, int32_t pts) {
+ this->av_offset = pts;
+ printf ("metronom: av_offset=%d pts\n", pts);
+}
+
+static int32_t metronom_get_av_offset (metronom_t *this) {
+ return this->av_offset;
+}
+
+
+
+/*
+ * ****************************************
+ * master clock feature
+ * ****************************************
+ */
+
+
+static void metronom_start_clock (metronom_t *this, uint32_t pts) {
+ gettimeofday(&this->start_time, NULL);
+ this->last_pts = this->start_pts = pts;
+ this->stopped = 0;
+}
+
+
+static uint32_t metronom_get_current_time (metronom_t *this) {
+
+ uint32_t pts;
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ pts = (tv.tv_sec - this->start_time.tv_sec) * 90000;
+ pts += (tv.tv_usec - this->start_time.tv_usec) / 10 * 9 / 10;
+ pts += this->start_pts;
+
+ if (this->stopped || (this->last_pts > pts)) {
+ //printf("tm_current_pts(): timer STOPPED!\n");
+ pts = this->last_pts;
+ }
+
+ return pts;
+}
+
+
+static void metronom_stop_clock(metronom_t *this) {
+ this->stopped = 1;
+ this->last_pts = this->get_current_time(this);
+}
+
+
+static void metronom_resume_clock(metronom_t *this) {
+ this->start_clock(this, this->last_pts);
+}
+
+
+
+static void metronom_adjust_clock(metronom_t *this, uint32_t desired_pts)
+{
+ int delta;
+
+ /* FIXME: this should be softer than a brute force warp... */
+ delta = desired_pts;
+ delta -= this->get_current_time(this);
+ this->start_pts += delta;
+ /* printf("adjusting start_pts to %d\n", this->start_pts); */
+}
+
+metronom_t * metronom_init () {
+
+ metronom_t *this = xmalloc (sizeof (metronom_t));
+
+ this->reset = metronom_reset;
+ this->set_video_rate = metronom_set_video_rate;
+ this->get_video_rate = metronom_get_video_rate;
+ this->set_audio_rate = metronom_set_audio_rate;
+ this->got_video_frame = metronom_got_video_frame;
+ this->got_audio_samples = metronom_got_audio_samples;
+ this->got_spu_packet = metronom_got_spu_packet;
+ this->set_av_offset = metronom_set_av_offset;
+ this->get_av_offset = metronom_get_av_offset;
+ this->start_clock = metronom_start_clock;
+ this->stop_clock = metronom_stop_clock;
+ this->resume_clock = metronom_resume_clock;
+ this->get_current_time = metronom_get_current_time;
+ this->adjust_clock = metronom_adjust_clock;
+
+ this->reset (this);
+
+ return this;
+}
+
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
new file mode 100644
index 000000000..a16b9ef20
--- /dev/null
+++ b/src/xine-engine/metronom.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: metronom.h,v 1.1 2001/04/18 22:36:07 f1rmb Exp $
+ *
+ * metronom: general pts => virtual calculation/assoc
+ *
+ * virtual pts: unit 1/90000 sec, always increasing
+ * can be used for synchronization
+ * video/audio frame with same pts also have same vpts
+ * but pts is likely to differ from vpts
+ *
+ */
+
+
+#ifndef HAVE_METRONOM_H
+#define HAVE_METRONOM_H
+
+#include <inttypes.h>
+#include <sys/time.h>
+
+typedef struct metronom_s metronom_t ;
+
+struct metronom_s {
+
+ /*
+ * clear all cached data, reset current vpts ... called if new input
+ * file is reached
+ */
+
+ void (*reset) (metronom_t *this);
+
+ /*
+ * called by video output driver to inform metronom about current framerate
+ *
+ * parameter pts_per_frame : frame display duration in 1/90000 sec
+ */
+ void (*set_video_rate) (metronom_t *this, uint32_t pts_per_frame);
+
+ /*
+ * return current video rate (including delta corrections)
+ */
+
+ uint32_t (*get_video_rate) (metronom_t *this);
+
+ /*
+ * called by audio output driver to inform metronom about current audio
+ * bitrate
+ *
+ * parameter pts_per_smpls : 1/90000 sec per 65536 samples
+ */
+ void (*set_audio_rate) (metronom_t *this, uint32_t pts_per_smpls);
+
+ /*
+ * called by video output driver for *every* frame
+ *
+ * parameter pts: pts for frame if known, 0 otherwise
+ *
+ * return value: virtual pts for frame
+ *
+ */
+
+ uint32_t (*got_video_frame) (metronom_t *this, uint32_t pts);
+
+ /*
+ * called by audio output driver whenever audio samples are delivered to it
+ *
+ * parameter pts : pts for audio data if known, 0 otherwise
+ * nsamples : number of samples delivered
+ *
+ * return value: virtual pts for audio data
+ *
+ */
+
+ uint32_t (*got_audio_samples) (metronom_t *this, uint32_t pts, uint32_t nsamples);
+
+ /*
+ * called by SPU decoder whenever a packet is delivered to it
+ *
+ * parameter pts : pts for SPU packet if known, 0 otherwise
+ *
+ * return value: virtual pts for SPU packet
+ *
+ */
+
+ uint32_t (*got_spu_packet) (metronom_t *this, uint32_t pts);
+
+ /*
+ * manually correct audio <-> video sync
+ */
+ void (*set_av_offset) (metronom_t *this, int32_t pts);
+
+ int32_t (*get_av_offset) (metronom_t *this);
+
+ /*
+ * ****************************************
+ * master clock functions
+ * ****************************************
+ */
+
+ /*
+ * start metronom clock (no clock reset)
+ */
+ void (*start_clock) (metronom_t *this, uint32_t pts);
+
+
+ /*
+ * stop metronom clock
+ */
+ void (*stop_clock) (metronom_t *this);
+
+
+ /*
+ * resume clock from where it was stopped
+ */
+ void (*resume_clock) (metronom_t *this);
+
+
+ /*
+ * get current clock value in vpts
+ */
+ uint32_t (*get_current_time) (metronom_t *this);
+
+
+ /*
+ * adjust master clock to external timer (e.g. audio hardware)
+ */
+ void (*adjust_clock) (metronom_t *this, uint32_t desired_pts);
+
+ /*
+ * metronom internal stuff
+ */
+
+ uint32_t pts_per_frame;
+ uint32_t pts_per_smpls;
+
+ int32_t audio_pts_delta;
+
+ uint32_t video_vpts;
+ uint32_t audio_vpts;
+
+ uint32_t sync_pts;
+ uint32_t sync_vpts;
+
+ /* video delta for wrong framerates */
+ uint32_t last_video_pts;
+ uint32_t last_video_vpts;
+ int num_video_vpts_guessed;
+ int32_t video_pts_delta;
+
+ int num_audio_samples_guessed;
+
+ int32_t av_offset;
+
+ struct timeval start_time;
+ uint32_t start_pts, last_pts;
+ int stopped ;
+};
+
+metronom_t *metronom_init ();
+
+#endif
+
diff --git a/src/xine-engine/monitor.c b/src/xine-engine/monitor.c
new file mode 100644
index 000000000..6fb23340e
--- /dev/null
+++ b/src/xine-engine/monitor.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: monitor.c,v 1.1 2001/04/18 22:36:04 f1rmb Exp $
+ *
+ * debug print and profiling functions - implementation
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "monitor.h"
+#include <stdio.h>
+
+#define MAX_ID 5
+
+#ifdef DEBUG
+
+long long int profiler_times[MAX_ID+1] ;
+long long int profiler_start[MAX_ID+1] ;
+char * profiler_label[MAX_ID+1] ;
+
+void profiler_init () {
+ int i;
+ for (i=0; i<MAX_ID; i++) {
+ profiler_times[i] = 0;
+ profiler_start[i] = 0;
+ profiler_label[i] = "??";
+ }
+}
+
+void profiler_set_label (int id, char *label) {
+ profiler_label[id] = label;
+}
+
+#ifdef ARCH_X86
+__inline__ unsigned long long int rdtsc()
+{
+ unsigned long long int x;
+ __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
+ return x;
+}
+#endif
+
+void profiler_start_count (int id) {
+#ifdef ARCH_X86
+ profiler_start[id] = rdtsc();
+#endif
+}
+
+void profiler_stop_count (int id) {
+#ifdef ARCH_X86
+ profiler_times[id] += rdtsc() - profiler_start[id];
+#endif
+}
+
+void profiler_print_results () {
+ int i;
+
+ printf ("\n\nPerformance analysis (cpu cycles):\n\n");
+ for (i=0; i<MAX_ID; i++) {
+ printf ("%d:\t%s\t%12lld\n", i, profiler_label[i], profiler_times[i]);
+ }
+}
+
+#endif
diff --git a/src/xine-engine/monitor.h b/src/xine-engine/monitor.h
new file mode 100644
index 000000000..e338be535
--- /dev/null
+++ b/src/xine-engine/monitor.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: monitor.h,v 1.1 2001/04/18 22:36:07 f1rmb Exp $
+ *
+ * debug print and profiling functions
+ *
+ */
+
+#ifndef HAVE_MONITOR_H
+#define HAVE_MONITOR_H
+
+#include <inttypes.h>
+
+extern uint32_t xine_debug;
+
+#define VERBOSE (xine_debug & 0x8000>>1)
+#define METRONOM (xine_debug & 0x8000>>2)
+#define AUDIO (xine_debug & 0x8000>>3)
+#define DEMUX (xine_debug & 0x8000>>4)
+#define INPUT (xine_debug & 0x8000>>5)
+#define VIDEO (xine_debug & 0x8000>>6)
+#define VPTS (xine_debug & 0x8000>>7)
+#define MPEG (xine_debug & 0x8000>>8)
+#define VAVI (xine_debug & 0x8000>>9)
+#define AC3 (xine_debug & 0x8000>>10)
+#define LOOP (xine_debug & 0x8000>>11)
+#define GUI (xine_debug & 0x8000>>12)
+
+#define perr(FMT,ARGS...) {fprintf(stderr, FMT, ##ARGS);fflush(stderr);}
+
+#ifdef DEBUG
+
+/*
+ * Debug stuff
+ */
+
+//#define perr(FMT,ARGS...) {fprintf(stderr, FMT, ##ARGS);fflush(stderr);}
+
+#define xprintf(LVL, FMT, ARGS...) { \
+ if(LVL) { \
+ printf(FMT, ##ARGS); \
+ } \
+ }
+/*
+ * profiling
+ */
+
+void profiler_init ();
+
+void profiler_set_label (int id, char *label);
+
+void profiler_start_count (int id);
+
+void profiler_stop_count (int id);
+
+void profiler_print_results ();
+
+#else /* no DEBUG, release version */
+
+//#define perr(FMT,ARGS...)
+
+#define xprintf(LVL, FMT, ARGS...)
+
+#define profiler_init()
+#define profiler_set_label(id, label)
+#define profiler_start_count(id)
+#define profiler_stop_count(id)
+#define profiler_print_results()
+
+#endif /* DEBUG*/
+
+#endif /* HAVE_MONITOR_H */
diff --git a/src/xine-engine/utils.c b/src/xine-engine/utils.c
new file mode 100644
index 000000000..3c6c0f532
--- /dev/null
+++ b/src/xine-engine/utils.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: utils.c,v 1.1 2001/04/18 22:36:04 f1rmb Exp $
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/types.h>
+
+/*
+ *
+ */
+void *xmalloc(size_t size) {
+ void *ptrmalloc, *ptrmemset;
+
+ if((ptrmalloc = malloc(size)) == NULL) {
+ fprintf(stderr, "%s: malloc() failed: %s.\n",
+ __FUNCTION__, strerror(errno));
+ return NULL;
+ }
+
+ if((ptrmemset = memset(ptrmalloc, 0, size)) == NULL) {
+ fprintf(stderr, "%s: memset() failed: %s.\n",
+ __FUNCTION__, strerror(errno));
+ return NULL;
+ }
+
+ return ptrmemset;
+}
+
+/*
+ *
+ */
+void *xmalloc_aligned (size_t alignment, size_t size) {
+ void *pMem;
+
+ pMem = xmalloc (size+alignment);
+
+ while ((int) pMem % alignment)
+ pMem++;
+
+ return pMem;
+}
+
+/*
+ *
+ */
+const char *get_homedir(void) {
+ struct passwd *pw = NULL;
+ char *homedir = NULL;
+#ifdef HAVE_GETPWUID_R
+ int ret;
+ struct passwd pwd;
+ char *buffer = NULL;
+ int bufsize = 128;
+
+ buffer = (char *) xmalloc(bufsize);
+
+ if((ret = getpwuid_r(getuid(), &pwd, buffer, bufsize, &pw)) < 0) {
+#else
+ if((pw = getpwuid(getuid())) == NULL) {
+#endif
+ if((homedir = getenv("HOME")) == NULL) {
+ fprintf(stderr, "Unable to get home directory, set it to /tmp.\n");
+ homedir = strdup("/tmp");
+ }
+ }
+ else {
+ if(pw)
+ homedir = strdup(pw->pw_dir);
+ }
+
+
+#ifdef HAVE_GETPWUID_R
+ if(buffer)
+ free(buffer);
+#endif
+
+ return homedir;
+}
+
+/*
+ *
+ */
+char *chomp(char *str) {
+ char *pbuf;
+
+ pbuf = str;
+
+ while(*pbuf != '\0') pbuf++;
+
+ while(pbuf > str) {
+ if(*pbuf == '\r' || *pbuf == '\n' || *pbuf == '"') pbuf = '\0';
+ pbuf--;
+ }
+
+ while(*pbuf == '=' || *pbuf == '"') pbuf++;
+
+ return pbuf;
+}
diff --git a/src/xine-engine/utils.h b/src/xine-engine/utils.h
new file mode 100644
index 000000000..d68cd0999
--- /dev/null
+++ b/src/xine-engine/utils.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: utils.h,v 1.1 2001/04/18 22:36:09 f1rmb Exp $
+ *
+ */
+#ifndef HAVE_UTILS_H
+#define HAVE_UTILS_H
+
+void *xmalloc(size_t size);
+
+void *xmalloc_aligned(size_t alignment, size_t size);
+
+const char *get_homedir(void);
+
+/*
+ * Clean a string (remove spaces and '=' at the begin,
+ * and '\n', '\r' and spaces at the end.
+ */
+
+char *chomp (char *str);
+
+#endif
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
new file mode 100644
index 000000000..a3f5532ce
--- /dev/null
+++ b/src/xine-engine/video_decoder.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: video_decoder.c,v 1.1 2001/04/18 22:36:04 f1rmb Exp $
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xine.h"
+#include "xine_internal.h"
+#include "video_out/video_out.h"
+#include "video_decoder.h"
+
+#define MAX_NUM_DECODERS 10
+
+typedef struct vd_globals_s {
+
+ pthread_t mVideoThread;
+
+ fifo_buffer_t *mBufVideo;
+
+ video_decoder_t *mDecoders[MAX_NUM_DECODERS];
+ video_decoder_t *mCurDecoder;
+
+ uint32_t mnCurInputPos;
+
+ vo_instance_t *mVideoOut;
+
+ gui_status_callback_func_t gui_status_callback;
+
+ int mbStreamFinished;
+
+ pthread_mutex_t mXineLock;
+
+} vd_globals_t;
+
+static vd_globals_t gVD;
+
+void *video_decoder_loop () {
+
+ buf_element_t *pBuf;
+ int bRunning = 1;
+
+ while (bRunning) {
+
+ pBuf = gVD.mBufVideo->fifo_buffer_get (gVD.mBufVideo);
+
+ gVD.mnCurInputPos = pBuf->nInputPos;
+
+ switch (pBuf->nType) {
+ case BUF_STREAMSTART:
+ if (gVD.mCurDecoder) {
+ gVD.mCurDecoder->close ();
+ gVD.mCurDecoder = NULL;
+ }
+
+ pthread_mutex_lock (&gVD.mXineLock);
+ gVD.mbStreamFinished = 0;
+ pthread_mutex_unlock (&gVD.mXineLock);
+
+ break;
+
+ case BUF_MPEGVIDEO:
+ case BUF_AVIVIDEO:
+
+ decoder = gVD.mDecoders [pBuf->nType];
+
+ if (decoder) {
+ if (gVD.mCurDecoder != decoder) {
+
+ if (gVD.mCurDecoder)
+ gVD.mCurDecoder->close ();
+
+ gVD.mCurDecoder = decoder;
+ gVD.mCurDecoder->init (gVD.mVideoOut);
+
+ }
+
+ decoder->decode_data (pBuf);
+ }
+
+ break;
+
+ case BUF_STREAMEND:
+ if (gVD.mCurDecoder) {
+ gVD.mCurDecoder->close ();
+ gVD.mCurDecoder = NULL;
+ }
+
+ gVD.mbStreamFinished = 1;
+
+ pthread_mutex_lock (&gVD.mXineLock);
+
+ gVD.mbVideoFinished = 1;
+
+ if (audio_decoder_is_stream_finished ()) {
+ pthread_mutex_unlock (&gVD.mXineLock);
+ xine_notify_stream_finished ();
+ } else
+ pthread_mutex_unlock (&gVD.mXineLock);
+
+ break;
+
+ case BUF_QUIT:
+ if (gVD.mCurDecoder) {
+ gVD.mCurDecoder->close ();
+ gVD.mCurDecoder = NULL;
+ }
+ bRunning = 0;
+ break;
+
+ }
+
+ pBuf->free_buffer (pBuf);
+ }
+
+ return NULL;
+}
+
+int video_decoder_is_stream_finished () {
+ return gVD.mbStreamFinished ;
+}
+
+uint32_t video_decoder_get_pos () {
+ return gVD.mnCurPos;
+}
+
+fifo_buffer_t *video_decoder_init (vo_instance_t *video_out,
+ pthread_mutex_t xine_lock) {
+
+ gVD.mVideoOut = video_out;
+ gVD.mXineLock = xine_lock;
+
+ gVD.mCurDecoder = NULL;
+ for (i=0; i<MAX_NUM_DECODERS; i++)
+ gVD.mDecoders[i] = NULL;
+
+ gVD.mDecoders[BUF_MPEGVIDEO] = init_video_decoder_mpeg2dec ();
+ gVD.mDecoders[BUF_AVIVIDEO] = init_video_decoder_avi ();
+
+ gVD.mBufVideo = fifo_buffer_new ();
+
+ pthread_create (&gVD.mVideoThread, NULL, video_decoder_loop, NULL) ;
+
+ printf ("video_decoder_init: video thread created\n");
+
+ return gVD.mBufVideo;
+}
+
+void video_decoder_shutdown () {
+
+ buf_element_t *pBuf;
+
+ gVD.mBufVideo->fifo_buffer_clear(gVD.mBufVideo);
+
+ pBuf = gVD.mBufVideo->buffer_pool_alloc ();
+ pBuf->nType = BUF_QUIT;
+ gVD.mBufVideo->fifo_buffer_put (gVD.mBufVideo, pBuf);
+
+ pthread_join (gVD.mVideoThread, &p);
+}
diff --git a/src/xine-engine/video_decoder.h b/src/xine-engine/video_decoder.h
new file mode 100644
index 000000000..ee9abfe33
--- /dev/null
+++ b/src/xine-engine/video_decoder.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: video_decoder.h,v 1.1 2001/04/18 22:36:09 f1rmb Exp $
+ *
+ *
+ * functions that implement video decoding
+ */
+
+#ifndef HAVE_VIDEO_DECODER_H
+#define VIDEO_DECODER_H
+
+#include <pthread.h>
+#include "buffer.h"
+#include "video_out.h"
+
+/*
+ * generic xine video decoder plugin interface
+ */
+
+typedef struct video_decoder_s
+{
+
+ /* get interface version */
+ int (*get_version) (void);
+
+ int (*can_handle) (int buf_type);
+
+ void (*init) (vo_instance_t *video_out);
+
+ void (*decode_data) (buf_element_t *buf);
+
+ void (*release_img_buffers) (void);
+
+ void (*close) (void);
+
+} video_decoder_t;
+
+/*
+ * init video decoders, allocate video fifo,
+ * start video decoder thread
+ */
+
+fifo_buffer_t *video_decoder_init (vo_instance_t *video_out,
+ pthread_mutex_t xine_lock) ;
+
+/*
+ * quit video thread
+ */
+
+void video_decoder_shutdown ();
+
+uint32_t video_decoder_get_pos ();
+
+int video_decoder_is_stream_finished ();
+
+#endif
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
new file mode 100644
index 000000000..9093e50ec
--- /dev/null
+++ b/src/xine-engine/xine.c
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: xine.c,v 1.1 2001/04/18 22:36:05 f1rmb Exp $
+ *
+ * top-level xine functions
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <pthread.h>
+#if defined (__linux__)
+#include <endian.h>
+#elif defined (__FreeBSD__)
+#include <machine/endian.h>
+#endif
+
+#include "xine.h"
+#include "xine_internal.h"
+#include "audio_out.h"
+#include "video_out.h"
+#include "demuxers/demux.h"
+#include "buffer.h"
+#include "libac3/ac3.h"
+#include "libmpg123/mpg123.h"
+#include "libmpg123/mpglib.h"
+#include "libmpeg2/mpeg2.h"
+#ifdef ARCH_X86
+#include "libw32dll/w32codec.h"
+#endif
+#include "libspudec/spudec.h"
+#include "input/input_plugin.h"
+#include "metronom.h"
+#include "configfile.h"
+#include "monitor.h"
+#include "video_decoder.h"
+#include "audio_decoder.h"
+
+/* debugging purposes only */
+uint32_t xine_debug;
+
+/*
+#define TEST_FILE
+*/
+#ifdef TEST_FILE
+int gTestFile=-1;
+#endif
+
+/*
+ * xine global variables
+ */
+
+void xine_notify_stream_finished (xine_t *this) {
+ printf ("xine_notify_stream_finished\n");
+
+ xine_stop (this);
+
+ this->status_callback (this->status);
+}
+
+/*
+ *
+ */
+void *xine_spu_loop (xine_t *this, void *dummy) {
+
+ buf_element_t *pBuf;
+ int bRunning = 1;
+
+ while (bRunning) {
+
+ pBuf = this->fifo_funcs->fifo_buffer_get (this->spu_fifo);
+
+ switch (pBuf->nType) {
+ case BUF_QUIT:
+ bRunning = 0;
+ break;
+ case BUF_RESET:
+ spudec_reset ();
+ break;
+ case BUF_SPU:
+ spudec_decode(pBuf->pContent, pBuf->nSize, pBuf->nPTS);
+ break;
+ }
+ this->fifo_funcs->buffer_pool_free (pBuf);
+ }
+
+ return NULL;
+}
+
+/*
+ *
+ */
+void xine_stop (xine_t *this) {
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ if (!this->cur_input_plugin)
+ return;
+
+ this->mnStatus = XINE_STOP;
+
+ if(this->cur_demuxer_plugin) {
+ this->cur_demuxer_plugin->demux_stop ();
+ this->cur_demuxer_plugin = NULL;
+ }
+
+ // FIXME
+ this->fifo_funcs->fifo_buffer_clear(this->mBufVideo);
+ this->fifo_funcs->fifo_buffer_clear(this->mBufAudio);
+ this->fifo_funcs->fifo_buffer_clear(this->spu_fifo);
+
+ if (gAudioOut)
+ gAudioOut->close ();
+
+ metronom_reset();
+ metronom_stop_clock ();
+
+ vo_reset();
+
+ this->cur_input_plugin->close();
+ this->cur_input_plugin = NULL;
+
+ pthread_mutex_unlock (&this->xine_lock);
+}
+
+/*
+ * *****
+ * Demuxers probing stuff
+ */
+static int try_demux_with_stages(xine_t *this, const char *MRL,
+ int stage1, int stage2) {
+ int s = 0, i;
+ int stages[3] = {
+ stage1, stage2, -1
+ };
+
+ if(stages[0] == -1) {
+ fprintf(stderr, "%s(%d) wrong first stage = %d !!\n",
+ __FUNCTION__, __LINE__, stage1);
+ return 0;
+ }
+
+ while(stages[s] != -1) {
+ for(i = 0; i < this->num_demuxer_plugins; i++) {
+ if(this->demuxer_plugins[i].open(this->cur_input_plugin,
+ MRL, stages[s]) == DEMUX_CAN_HANDLE) {
+
+ this->cur_demuxer_plugin = &this->demux_plugins[i];
+
+ xprintf(VERBOSE|DEMUX,"demuxer '%s' handle in stage '%s'.\n",
+ this->demux_plugins[i].get_identifier(),
+ (stages[s] == STAGE_BY_CONTENT) ? "STAGE_BY_CONTENT"
+ : ((stages[s] == STAGE_BY_EXTENSION) ? "STAGE_BY_EXTENSION"
+ : "UNKNOWN"));
+ return 1;
+ }
+#ifdef DEBUG
+ else
+ xprintf(VERBOSE|DEMUX, "demuxer '%s' cannot handle in stage '%s'.\n",
+ this->demuxer_plugins[i].get_identifier(),
+ (stages[s] == STAGE_BY_CONTENT) ? "STAGE_BY_CONTENT"
+ : ((stages[s] == STAGE_BY_EXTENSION) ? "STAGE_BY_EXTENSION"
+ : "UNKNOWN"));
+#endif
+ }
+ s++;
+ }
+
+ return 0;
+}
+/*
+ * Try to find a demuxer which handle the MRL stream
+ */
+static int find_demuxer(xine_t *this, const char *MRL) {
+
+ this->cur_demuxer_plugin = NULL;
+
+ switch(this->demux_strategy) {
+
+ case DEMUX_DEFAULT_STRATEGY:
+ if(try_demux_with_stages(this, MRL, STAGE_BY_CONTENT, STAGE_BY_EXTENSION))
+ return 1;
+ break;
+
+ case DEMUX_REVERT_STRATEGY:
+ if(try_demux_with_stages(this, MRL, STAGE_BY_EXTENSION, STAGE_BY_CONTENT))
+ return 1;
+ break;
+
+ case DEMUX_CONTENT_STRATEGY:
+ if(try_demux_with_stages(this, MRL, STAGE_BY_CONTENT, -1))
+ return 1;
+ break;
+
+ case DEMUX_EXTENSION_STRATEGY:
+ if(try_demux_with_stages(this, MRL, STAGE_BY_EXTENSION, -1))
+ return 1;
+ break;
+
+ }
+
+ return 0;
+}
+
+/*
+ *
+ */
+static void xine_play_internal (xine_t *this, char *MRL,
+ int spos, off_t pos) {
+
+ double share ;
+ off_t len;
+ int i;
+
+ xprintf (VERBOSE|LOOP, "xine open %s, start pos = %d\n",MRL, spos);
+
+ if (this->status == XINE_PAUSE) {
+ xine_pause();
+ return;
+ }
+
+ if (this->status != XINE_STOP) {
+ xine_stop ();
+ }
+
+ /*
+ * find input plugin
+ */
+
+ this->cur_input_plugin = NULL;
+
+ for (i = 0; i < this->num_input_plugins; i++) {
+ if (this->input_plugins[i].open(MRL)) {
+ this->cur_input_plugin = &this->input_plugins[i];
+ break;
+ }
+ }
+
+ if (!this->cur_input_plugin) {
+ perror ("open input source");
+ this->cur_demuxer_plugin = NULL;
+ return;
+ }
+
+ /*
+ * find demuxer plugin
+ */
+
+ if(!find_demuxer(this, MRL)) {
+ printf ("error: couldn't find demuxer for >%s<\n", MRL);
+ return;
+ }
+
+ vo_set_logo_mode (0);
+
+ /*
+ * Init SPU decoder with colour lookup table.
+ */
+
+ if(this->cur_input_plugin->get_clut)
+ spudec_init(this->cur_input_plugin->get_clut());
+ else
+ spudec_init(NULL);
+
+ /*
+ * metronom
+ */
+
+ metronom_reset();
+
+ /*
+ * start demuxer
+ */
+
+ if (spos) {
+ len = this->cur_input_plugin->get_length ();
+ share = (double) spos / 65535;
+ pos = (off_t) (share * len) ;
+ }
+
+ this->cur_demuxer_plugin->demux_select_audio_channel (this->audio_channel);
+ this->cur_demuxer_plugin->demux_select_spu_channel (this->spu_channel);
+ this->cur_demuxer_plugin->demux_start (this->cur_input_plugin,
+ this->mBufVideo, //FIXME
+ this->mBufAudio,
+ this->spu_fifo, pos);
+
+ this->status = XINE_PLAY;
+ this->cur_input_pos = pos;
+
+ /*
+ * remember MRL
+ */
+
+ strncpy (this->cur_mrl, MRL, 1024);
+
+ /*
+ * start clock
+ */
+
+ metronom_start_clock (0);
+}
+
+/*
+ *
+ */
+void xine_play (xine_t *this, char *MRL, int spos) {
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ if (this->status != XINE_PLAY)
+ xine_play_internal (this, MRL, spos, (off_t) 0);
+
+ pthread_mutex_unlock (&this->xine_lock);
+}
+
+/*
+ *
+ */
+static int xine_eject (xine_t *this, char *MRL) {
+ int i;
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ if(this->cur_input_plugin == NULL) {
+
+ for (i = 0; i < this->num_input_plugins; i++) {
+ if (this->input_pluginss[i].open(MRL)) {
+ this->cur_input_plugin = &this->input_plugins[i];
+ this->cur_input_plugin->close();
+ break;
+ }
+ }
+ }
+
+ if (this->status == XINE_STOP
+ && this->cur_input_plugin && this->cur_input_plugin->eject_media) {
+
+ pthread_mutex_unlock (&this->xine_lock);
+
+ return this->cur_input_plugin->eject_media ();
+ }
+
+ pthread_mutex_unlock (&this->xine_lock);
+ return 0;
+}
+
+/*
+ *
+ */
+void xine_exit (xine_t *this) {
+
+ void *p;
+ buf_element_t *pBuf;
+
+ /*
+ * stop decoder threads
+ */
+
+ if (this->cur_input_plugin)
+ this->cur_input_plugin->demux_stop ();
+
+ this->fifo_funcs->fifo_buffer_clear(this->spu_fifo);
+
+ audio_decoder_shutdown ();
+ video_decoder_shutdown ();
+
+ this->status = XINE_QUIT;
+
+ config_file_save ();
+}
+
+/*
+ *
+ */
+static void xine_pause (xine_t *this) {
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ if (this->status == XINE_PAUSE) {
+
+ xprintf (VERBOSE, "xine play %s from %Ld\n",
+ this->cur_mrl, this->cur_input_pos);
+
+ this->status = XINE_STOP;
+
+ xine_play_internal (this, this->cur_mrl, 0, this->cur_input_pos);
+ /* this->mnPausePos = 0; */
+
+ } else if (this->status == XINE_PLAY) {
+
+ if (!this->cur_input_plugin) {
+ pthread_mutex_unlock (&this->xine_lock);
+ return;
+ }
+
+ this->status = XINE_PAUSE;
+
+ this->cur_demuxer_plugin->demux_stop ();
+ this->cur_demuxer_plugin = NULL;
+
+ //FIXME
+ this->fifo_funcs->fifo_buffer_clear(this->mBufVideo);
+ this->fifo_funcs->fifo_buffer_clear(this->mBufAudio);
+ this->fifo_funcs->fifo_buffer_clear(this->spu_fifo);
+
+ if (gAudioOut)
+ gAudioOut->close ();
+
+ metronom_reset();
+ metronom_stop_clock ();
+
+ vo_reset ();
+
+ this->cur_input_plugin->close();
+ }
+
+ pthread_mutex_unlock (&this->xine_lock);
+}
+
+/*
+ *
+ */
+xine_t *xine_init (vo_instance_t *vo, ao_instance_t *ao,
+ gui_status_callback_func_t gui_status_callback,
+ int demux_strategy, uint32_t debug_lvl) {
+
+ xine_t *this = xmalloc (sizeof (xine_t));
+ int err;
+
+ this->status_callback = gui_status_callback;
+ this->demux_strategy = demux_strategy;
+ xine_debug = debug_lvl;
+
+#ifdef TEST_FILE
+ gTestFile = open ("/tmp/test.mp3", O_WRONLY | O_CREAT, 0644);
+#endif
+
+ /*
+ * init lock
+ */
+
+ pthread_mutex_init (&this->xine_lock, NULL);
+
+ /*
+ * Init buffers
+ */
+
+ this->fifo_funcs = buffer_pool_init (2000, 4096);
+ this->spu_fifo = this->fifo_funcs->fifo_buffer_new ();
+
+ /*
+ * init demuxer
+ */
+
+ xine_load_demux_plugins();
+
+ this->audio_channel = 0;
+ this->spu_channel = -1;
+ this->cur_input_pos = 0;
+
+ printf ("xine_init: demuxer initialized\n");
+
+ /*
+ * init and start decoder threads
+ */
+
+ this->mBufVideo = video_decoder_init (vo);
+
+ this->mBufAudio = audio_decoder_init (ao);
+
+ /*
+ * init SPU decoder, start SPU thread
+ */
+
+ spudec_init(NULL);
+
+ if((err = pthread_create (&this->spu_thread, NULL,
+ xine_spu_loop, NULL)) != 0) {
+ fprintf(stderr, "pthread_create failed: return code %d.\n", err);
+ exit(1);
+ }
+ else
+ printf ("xine_init: SPU thread created\n");
+
+ /*
+ * load input plugins
+ */
+
+ xine_load_input_plugins ();
+
+ printf ("xine_init: plugins loaded\n");
+
+ return this;
+}
+
+/*
+ *
+ */
+int xine_get_audio_channel (xine_t *this) {
+
+ return this->audio_channel;
+}
+
+/*
+ *
+ */
+void xine_select_audio_channel (xine_t *this, int nChannel) {
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ this->audio_channel = nChannel;
+
+ if (this->cur_demuxer_plugin) {
+ this->cur_demuxer_plugin->demux_select_audio_channel (this->audio_channel);
+ }
+
+ pthread_mutex_unlock (&this->xine_lock);
+}
+
+/*
+ *
+ */
+int xine_get_spu_channel (xine_t *this) {
+
+ return this->spu_channel;
+}
+
+/*
+ *
+ */
+void xine_select_spu_channel (xine_t *this, int nChannel) {
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ this->spu_channel = (nChannel >= -1 ? nChannel : -1);
+
+ if (this->cur_demuxer_plugin)
+ this->cur_demuxer_plugin->demux_select_spu_channel (this->spu_channel);
+
+ pthread_mutex_unlock (&this->xine_lock);
+}
+
+/*
+ *
+ */
+input_plugin_t* xine_get_input_plugin_list (xine_t *this, int *nInputPlugins) {
+
+ *nInputPlugins = this->num_input_plugins;
+ return this->input_plugins;
+}
+
+/*
+ *
+ */
+int xine_get_current_position (xine_t *this) {
+
+ off_t len;
+ double share;
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ if (!this->cur_input_plugin) {
+ xprintf (VERBOSE|INPUT, "xine_get_current_position: no input source\n");
+ pthread_mutex_unlock (&this->xine_lock);
+ return 0;
+ }
+
+ /* pos = this->mCurInput->seek (0, SEEK_CUR); */
+ len = this->cur_input_plugin->get_length ();
+
+ share = (double) this->cur_input_pos / (double) len * 65535;
+
+ pthread_mutex_unlock (&this->xine_lock);
+
+ return (int) share;
+}
+
+/*
+ *
+ */
+int xine_get_status(xine_t *this) {
+
+ return this->status;
+}
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
new file mode 100644
index 000000000..c097158af
--- /dev/null
+++ b/src/xine-engine/xine_internal.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * 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
+ *
+ * $Id: xine_internal.h,v 1.1 2001/04/18 22:36:09 f1rmb Exp $
+ *
+ */
+
+#ifndef HAVE_XINE_INTERNAL_H
+#define HAVE_XINE_INTERNAL_H
+
+#include <inttypes.h>
+#include "xine.h"
+#include "input/input_plugin.h"
+#include "demuxers/demux.h"
+#include "video_out.h"
+#include "audio_out.h"
+#include "metronom.h"
+
+#define INPUT_PLUGIN_MAX 50
+#define DEMUXER_PLUGIN_MAX 50
+
+typedef struct xine_s {
+
+ /* private : */
+
+ metronom_t *metronom;
+
+ input_plugin_t input_plugins[INPUT_PLUGIN_MAX];
+ int num_input_plugins;
+ input_plugin_t *cur_input_plugin;
+
+ demux_plugin_t demuxer_plugins[DEMUXER_PLUGIN_MAX];
+ int num_demuxer_plugins;
+ demux_plugin_t *cur_demuxer_plugin;
+ int demux_stragegy;
+
+ int status;
+ off_t cur_input_pos;
+ char cur_mrl[1024];
+
+ fifo_buffer_t *spu_fifo;
+
+ int audio_channel;
+ int spu_channel;
+
+ gui_status_callback_func_t status_callback;
+
+ /* Lock for xine player functions */
+ pthread_mutex_t xine_lock;
+
+} xine_t;
+
+/*
+ * Load input/demux/audio_out/video_out plugins
+ * prototypes of load_plugins.c functions.
+ */
+void xine_load_demux_plugins (xine_t *this);
+void xine_load_input_plugins (xine_t *this);
+
+#endif