summaryrefslogtreecommitdiff
path: root/src/xine-engine
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2002-10-14 15:46:48 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2002-10-14 15:46:48 +0000
commitbcaee71a3a763a545e1f8457aca26dc679462677 (patch)
tree191c500351cb4073c6d998e6112a6b68f19790f4 /src/xine-engine
parentde10300bdc6457c36598f4287d42c4a5b2e82d71 (diff)
downloadxine-lib-bcaee71a3a763a545e1f8457aca26dc679462677.tar.gz
xine-lib-bcaee71a3a763a545e1f8457aca26dc679462677.tar.bz2
introduction of xine_stream_t and async xine events - all still in developement
CVS patchset: 2828 CVS date: 2002/10/14 15:46:48
Diffstat (limited to 'src/xine-engine')
-rw-r--r--src/xine-engine/Makefile.am2
-rw-r--r--src/xine-engine/audio_decoder.c232
-rw-r--r--src/xine-engine/audio_decoder.h80
-rw-r--r--src/xine-engine/audio_out.c28
-rw-r--r--src/xine-engine/audio_out.h27
-rw-r--r--src/xine-engine/demux.c70
-rw-r--r--src/xine-engine/events.c239
-rw-r--r--src/xine-engine/events.h177
-rw-r--r--src/xine-engine/load_plugins.c486
-rw-r--r--src/xine-engine/metronom.c8
-rw-r--r--src/xine-engine/metronom.h15
-rw-r--r--src/xine-engine/plugin_catalog.h32
-rw-r--r--src/xine-engine/video_decoder.c244
-rw-r--r--src/xine-engine/video_decoder.h86
-rw-r--r--src/xine-engine/video_out.c27
-rw-r--r--src/xine-engine/video_out.h7
-rw-r--r--src/xine-engine/video_overlay.h7
-rw-r--r--src/xine-engine/xine.c991
-rw-r--r--src/xine-engine/xine_interface.c59
-rw-r--r--src/xine-engine/xine_internal.h270
-rw-r--r--src/xine-engine/xine_plugin.h7
21 files changed, 1553 insertions, 1541 deletions
diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am
index 59e3c0899..6eb07a850 100644
--- a/src/xine-engine/Makefile.am
+++ b/src/xine-engine/Makefile.am
@@ -24,7 +24,7 @@ libxine_la_LDFLAGS = \
include_HEADERS = buffer.h metronom.h configfile.h vo_scale.h \
audio_out.h resample.h video_out.h xine_internal.h spu_decoder.h \
lrb.h video_overlay.h osd.h scratch.h xine_plugin.h xineintl.h \
- plugin_catalog.h
+ plugin_catalog.h audio_decoder.h video_decoder.h
noinst_HEADERS = bswap.h nvtvd.h
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index 9ad8ddfdc..892fdbf8d 100644
--- a/src/xine-engine/audio_decoder.c
+++ b/src/xine-engine/audio_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_decoder.c,v 1.84 2002/09/18 00:51:34 guenter Exp $
+ * $Id: audio_decoder.c,v 1.85 2002/10/14 15:47:23 guenter Exp $
*
*
* functions that implement audio decoding
@@ -40,10 +40,10 @@
#define LOG
*/
-void *audio_decoder_loop (void *this_gen) {
+void *audio_decoder_loop (void *stream_gen) {
buf_element_t *buf;
- xine_t *this = (xine_t *) this_gen;
+ xine_stream_t *stream = (xine_stream_t *) stream_gen;
int running = 1;
audio_decoder_t *decoder;
static int prof_audio_decode = -1;
@@ -58,7 +58,7 @@ void *audio_decoder_loop (void *this_gen) {
printf ("audio_loop: waiting for package...\n");
#endif
- buf = this->audio_fifo->get (this->audio_fifo);
+ buf = stream->audio_fifo->get (stream->audio_fifo);
#ifdef LOG
@@ -67,75 +67,79 @@ void *audio_decoder_loop (void *this_gen) {
#endif
if (buf->input_pos)
- this->cur_input_pos = buf->input_pos;
+ stream->input_pos = buf->input_pos;
if (buf->input_length)
- this->cur_input_length = buf->input_length;
+ stream->input_length = buf->input_length;
if (buf->input_time) {
- this->cur_input_time = buf->input_time;
- pthread_mutex_lock (&this->osd_lock);
- if( this->curtime_needed_for_osd && !(--this->curtime_needed_for_osd) )
- xine_internal_osd (this, ">",90000);
- pthread_mutex_unlock (&this->osd_lock);
+ stream->input_time = buf->input_time;
}
switch (buf->type) {
+ case BUF_CONTROL_HEADERS_DONE:
+ pthread_mutex_lock (&stream->counter_lock);
+ stream->header_count_audio++;
+ pthread_cond_broadcast (&stream->counter_changed);
+ pthread_mutex_unlock (&stream->counter_lock);
+ break;
+
case BUF_CONTROL_START:
- if (this->cur_audio_decoder_plugin) {
- this->cur_audio_decoder_plugin->close (this->cur_audio_decoder_plugin);
- this->cur_audio_decoder_plugin = NULL;
- this->audio_track_map_entries = 0;
- this->audio_type = 0;
+ if (stream->audio_decoder_plugin) {
+ free_audio_decoder (stream, stream->audio_decoder_plugin);
+ stream->audio_decoder_plugin = NULL;
+ stream->audio_track_map_entries = 0;
+ stream->audio_type = 0;
}
- pthread_mutex_lock (&this->finished_lock);
- this->audio_finished = 0;
- pthread_mutex_unlock (&this->finished_lock);
-
- this->metronom->handle_audio_discontinuity (this->metronom, DISC_STREAMSTART, 0);
+ stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_STREAMSTART, 0);
break;
case BUF_CONTROL_END:
- if (this->cur_audio_decoder_plugin) {
- this->cur_audio_decoder_plugin->close (this->cur_audio_decoder_plugin);
- this->cur_audio_decoder_plugin = NULL;
- this->audio_track_map_entries = 0;
- this->audio_type = 0;
+ if (stream->audio_decoder_plugin) {
+ free_audio_decoder (stream, stream->audio_decoder_plugin);
+ stream->audio_decoder_plugin = NULL;
+ stream->audio_track_map_entries = 0;
+ stream->audio_type = 0;
}
+
+ /* wait for video to reach this marker, if necessary */
- pthread_mutex_lock (&this->finished_lock);
+ pthread_mutex_lock (&stream->counter_lock);
- if (!this->audio_finished ) {
- this->audio_finished = 1;
-
- if (this->video_finished) {
- if( this->playing_logo )
- buf->decoder_flags = 0;
- this->playing_logo = 0;
-
- if( buf->decoder_flags & BUF_FLAG_END_STREAM )
- xine_notify_stream_finished (this);
- }
- }
+ stream->finished_count_audio++;
- pthread_mutex_unlock (&this->finished_lock);
+ printf ("audio_decoder: reached end marker # %d\n",
+ stream->finished_count_audio);
- this->audio_channel_auto = -1;
+ pthread_cond_broadcast (&stream->counter_changed);
- /* future magic - coming soon
- lrb_flush (this->audio_temp);
- */
+ if (stream->stream_info[XINE_STREAM_INFO_HAS_AUDIO]) {
+
+ while (stream->finished_count_video < stream->finished_count_audio) {
+ pthread_cond_wait (&stream->counter_changed, &stream->counter_lock);
+ }
+ }
+
+ pthread_mutex_unlock (&stream->counter_lock);
+
+ if (!stream->stream_info[XINE_STREAM_INFO_HAS_VIDEO]) {
+ /* set engine status, send frontend notification event */
+ xine_handle_stream_end (stream,
+ buf->decoder_flags & BUF_FLAG_END_STREAM);
+ }
+
+ stream->audio_channel_auto = -1;
break;
case BUF_CONTROL_QUIT:
- if (this->cur_audio_decoder_plugin) {
- this->cur_audio_decoder_plugin->close (this->cur_audio_decoder_plugin);
- this->cur_audio_decoder_plugin = NULL;
- this->audio_track_map_entries = 0;
- this->audio_type = 0;
+ if (stream->audio_decoder_plugin) {
+ free_audio_decoder (stream, stream->audio_decoder_plugin);
+ stream->audio_decoder_plugin = NULL;
+ stream->audio_track_map_entries = 0;
+ stream->audio_type = 0;
}
running = 0;
break;
@@ -144,21 +148,21 @@ void *audio_decoder_loop (void *this_gen) {
break;
case BUF_CONTROL_RESET_DECODER:
- if (this->cur_audio_decoder_plugin)
- this->cur_audio_decoder_plugin->reset (this->cur_audio_decoder_plugin);
- if (this->audio_out)
- this->audio_out->control(this->audio_out, AO_CTRL_FLUSH_BUFFERS);
+ if (stream->audio_decoder_plugin)
+ stream->audio_decoder_plugin->reset (stream->audio_decoder_plugin);
+ if (stream->audio_out)
+ stream->audio_out->control(stream->audio_out, AO_CTRL_FLUSH_BUFFERS);
break;
case BUF_CONTROL_DISCONTINUITY:
- this->metronom->handle_audio_discontinuity (this->metronom, DISC_RELATIVE, buf->disc_off);
+ stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_RELATIVE, buf->disc_off);
break;
case BUF_CONTROL_NEWPTS:
if (buf->decoder_flags && BUF_FLAG_SEEK) {
- this->metronom->handle_audio_discontinuity (this->metronom, DISC_STREAMSEEK, buf->disc_off);
+ stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_STREAMSEEK, buf->disc_off);
} else {
- this->metronom->handle_audio_discontinuity (this->metronom, DISC_ABSOLUTE, buf->disc_off);
+ stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_ABSOLUTE, buf->disc_off);
}
break;
@@ -166,7 +170,7 @@ void *audio_decoder_loop (void *this_gen) {
{
printf ("audio_decoder: suggested switching to stream_id %02x\n",
buf->decoder_info[0]);
- this->audio_channel_auto = buf->decoder_info[0] & 0xff;
+ stream->audio_channel_auto = buf->decoder_info[0] & 0xff;
}
break;
@@ -182,83 +186,79 @@ void *audio_decoder_loop (void *this_gen) {
/*
printf("audio_decoder: buf_type=%08x auto=%08x user=%08x\n",
buf->type,
- this->audio_channel_auto,
- this->audio_channel_user);
+ stream->audio_channel_auto,
+ stream->audio_channel_user);
*/
/* update track map */
i = 0;
- while ( (i<this->audio_track_map_entries) && (this->audio_track_map[i]<buf->type) )
+ while ( (i<stream->audio_track_map_entries) && (stream->audio_track_map[i]<buf->type) )
i++;
- if ( (i==this->audio_track_map_entries) || (this->audio_track_map[i] != buf->type) ) {
+ if ( (i==stream->audio_track_map_entries) || (stream->audio_track_map[i] != buf->type) ) {
- j = this->audio_track_map_entries;
+ j = stream->audio_track_map_entries;
while (j>i) {
- this->audio_track_map[j] = this->audio_track_map[j-1];
+ stream->audio_track_map[j] = stream->audio_track_map[j-1];
j--;
}
- this->audio_track_map[i] = buf->type;
- this->audio_track_map_entries++;
+ stream->audio_track_map[i] = buf->type;
+ stream->audio_track_map_entries++;
}
/* find out which audio type to decode */
- if (this->audio_channel_user > -2) {
+ if (stream->audio_channel_user > -2) {
- if (this->audio_channel_user == -1) {
+ if (stream->audio_channel_user == -1) {
/* auto */
- if (this->audio_channel_auto>=0) {
+ if (stream->audio_channel_auto>=0) {
- if ((buf->type & 0xFF) == this->audio_channel_auto) {
+ if ((buf->type & 0xFF) == stream->audio_channel_auto) {
audio_type = buf->type;
} else
audio_type = -1;
} else
- audio_type = this->audio_track_map[0];
+ audio_type = stream->audio_track_map[0];
} else {
- if (this->audio_channel_user <= this->audio_track_map_entries)
- audio_type = this->audio_track_map[this->audio_channel_user];
+ if (stream->audio_channel_user <= stream->audio_track_map_entries)
+ audio_type = stream->audio_track_map[stream->audio_channel_user];
else
audio_type = -1;
}
- /* now, decode this buffer if it's the right audio type */
+ /* now, decode stream buffer if it's the right audio type */
if (buf->type == audio_type) {
int streamtype = (buf->type>>16) & 0xFF;
- decoder = get_audio_decoder (this, streamtype);
+ decoder = get_audio_decoder (stream, streamtype);
/* close old decoder of audio type has changed */
- if (audio_type != this->audio_type) {
+ if (audio_type != stream->audio_type) {
- if (this->cur_audio_decoder_plugin) {
- this->cur_audio_decoder_plugin->close (this->cur_audio_decoder_plugin);
- this->cur_audio_decoder_plugin = NULL;
+ if (stream->audio_decoder_plugin) {
+ free_audio_decoder (stream, stream->audio_decoder_plugin);
+ stream->audio_decoder_plugin = NULL;
}
if (decoder) {
xine_event_t event;
- this->meta_info[XINE_META_INFO_AUDIOCODEC]
- = strdup (decoder->get_identifier());
- xine_report_codec( this, XINE_CODEC_AUDIO, 0, buf->type, 1);
-
- this->cur_audio_decoder_plugin = decoder;
- this->cur_audio_decoder_plugin->init (this->cur_audio_decoder_plugin, this->audio_out);
+ stream->audio_decoder_plugin = decoder;
- this->audio_type = audio_type;
+ stream->audio_type = audio_type;
- event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
- xine_send_event(this, &event);
+ event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
+ event.data_length = 0;
+ xine_event_send(stream, &event);
}
}
@@ -267,15 +267,16 @@ void *audio_decoder_loop (void *this_gen) {
if (decoder)
decoder->decode_data (decoder, buf);
else if( buf->type != buftype_unknown ) {
- xine_log (this, XINE_LOG_MSG, "audio_decoder: no plugin available to handle '%s'\n",
+ xine_log (stream->xine, XINE_LOG_MSG,
+ "audio_decoder: no plugin available to handle '%s'\n",
buf_audio_name( buf->type ) );
- xine_report_codec( this, XINE_CODEC_AUDIO, 0, buf->type, 0);
buftype_unknown = buf->type;
}
}
}
} else if( buf->type != buftype_unknown ) {
- xine_log (this, XINE_LOG_MSG, "audio_decoder: unknown buffer type: %08x\n",
+ xine_log (stream->xine, XINE_LOG_MSG,
+ "audio_decoder: unknown buffer type: %08x\n",
buf->type );
buftype_unknown = buf->type;
}
@@ -289,15 +290,14 @@ void *audio_decoder_loop (void *this_gen) {
pthread_exit(NULL);
}
-void audio_decoder_init (xine_t *this) {
+void audio_decoder_init (xine_stream_t *stream) {
pthread_attr_t pth_attrs;
struct sched_param pth_params;
int err;
- if (this->audio_out == NULL) {
- this->audio_finished = 1;
- this->audio_fifo = NULL;
+ if (stream->audio_out == NULL) {
+ stream->audio_fifo = NULL;
return;
}
@@ -308,14 +308,14 @@ void audio_decoder_init (xine_t *this) {
* We provide buffers of 8k size instead of 2k for demuxers sending
* larger chunks.
*/
- this->audio_fifo = fifo_buffer_new (230, 8192);
- this->audio_channel_user = -1;
- this->audio_channel_auto = 0;
- this->audio_track_map_entries = 0;
- this->audio_type = 0;
+ stream->audio_fifo = fifo_buffer_new (230, 8192);
+ stream->audio_channel_user = -1;
+ stream->audio_channel_auto = 0;
+ stream->audio_track_map_entries = 0;
+ stream->audio_type = 0;
/* future magic - coming soon
- this->audio_temp = lrb_new (100, this->audio_fifo);
+ stream->audio_temp = lrb_new (100, stream->audio_fifo);
*/
pthread_attr_init(&pth_attrs);
@@ -324,41 +324,41 @@ void audio_decoder_init (xine_t *this) {
pthread_attr_setschedparam(&pth_attrs, &pth_params);
pthread_attr_setscope(&pth_attrs, PTHREAD_SCOPE_SYSTEM);
- if ((err = pthread_create (&this->audio_thread,
- &pth_attrs, audio_decoder_loop, this)) != 0) {
+ if ((err = pthread_create (&stream->audio_thread,
+ &pth_attrs, audio_decoder_loop, stream)) != 0) {
fprintf (stderr, "audio_decoder: can't create new thread (%s)\n",
strerror(err));
abort();
}
}
-void audio_decoder_shutdown (xine_t *this) {
+void audio_decoder_shutdown (xine_stream_t *stream) {
buf_element_t *buf;
void *p;
- if (this->audio_fifo) {
- /* this->audio_fifo->clear(this->audio_fifo); */
+ if (stream->audio_fifo) {
+ /* stream->audio_fifo->clear(stream->audio_fifo); */
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_QUIT;
- this->audio_fifo->put (this->audio_fifo, buf);
+ stream->audio_fifo->put (stream->audio_fifo, buf);
- pthread_join (this->audio_thread, &p);
+ pthread_join (stream->audio_thread, &p);
}
- if(this->audio_out) {
- this->audio_out->exit (this->audio_out);
- this->audio_out = NULL;
+ if(stream->audio_out) {
+ stream->audio_out->exit (stream->audio_out);
+ stream->audio_out = NULL;
}
- if (this->audio_fifo) {
- this->audio_fifo->dispose (this->audio_fifo);
- this->audio_fifo = NULL;
+ if (stream->audio_fifo) {
+ stream->audio_fifo->dispose (stream->audio_fifo);
+ stream->audio_fifo = NULL;
}
}
-int xine_get_audio_channel (xine_t *this) {
+int xine_get_audio_channel (xine_stream_t *stream) {
- return this->audio_type & 0xFFFF;
+ return stream->audio_type & 0xFFFF;
}
diff --git a/src/xine-engine/audio_decoder.h b/src/xine-engine/audio_decoder.h
new file mode 100644
index 000000000..dd5fcc591
--- /dev/null
+++ b/src/xine-engine/audio_decoder.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2000-2002 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: audio_decoder.h,v 1.3 2002/10/14 15:47:25 guenter Exp $
+ *
+ * xine audio decoder plugin interface
+ *
+ */
+
+#ifndef HAVE_AUDIO_DECODER_H
+#define HAVE_AUDIO_DECODER_H
+
+#include <inttypes.h>
+#include "buffer.h"
+
+#define AUDIO_DECODER_IFACE_VERSION 10
+
+/*
+ * generic xine audio decoder plugin interface
+ */
+
+typedef struct audio_decoder_class_s audio_decoder_class_t;
+
+struct audio_decoder_class_s {
+
+ /*
+ * return short, human readable identifier for this plugin class
+ */
+ char* (*get_identifier) (audio_decoder_class_t *this);
+
+ /*
+ * return human readable (verbose = 1 line) description for
+ * this plugin class
+ */
+ char* (*get_description) (audio_decoder_class_t *this);
+};
+
+
+typedef struct audio_decoder_s audio_decoder_t;
+
+struct audio_decoder_s {
+
+ /*
+ * decode data from buf and feed decoded samples to
+ * audio output
+ */
+ void (*decode_data) (audio_decoder_t *this, buf_element_t *buf);
+
+ /*
+ * reset decoder after engine flush (prepare for new
+ * audio data not related to recently decoded data)
+ */
+ void (*reset) (audio_decoder_t *this);
+
+ /*
+ * close down, free all resources
+ */
+ void (*dispose) (audio_decoder_t *this);
+
+ void *node; /* used by plugin loader */
+
+};
+
+#endif
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 5e2da61f9..e0c371629 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -17,7 +17,7 @@
* along with self program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.c,v 1.69 2002/10/12 19:20:02 jkeil Exp $
+ * $Id: audio_out.c,v 1.70 2002/10/14 15:47:25 guenter Exp $
*
* 22-8-2001 James imported some useful AC3 sections from the previous alsa driver.
* (c) 2001 Andy Lo A Foe <andy@alsaplayer.org>
@@ -581,28 +581,28 @@ static int ao_open(ao_instance_t *this,
switch (mode) {
case AO_CAP_MODE_MONO:
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 1;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 1;
break;
case AO_CAP_MODE_STEREO:
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 2;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 2;
break;
case AO_CAP_MODE_4CHANNEL:
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 4;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 4;
break;
case AO_CAP_MODE_5CHANNEL:
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 5;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 5;
break;
case AO_CAP_MODE_5_1CHANNEL:
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 6;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 6;
break;
case AO_CAP_MODE_A52:
case AO_CAP_MODE_AC5:
default:
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 255; /* unknown */
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 255; /* unknown */
}
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = bits;
- this->xine->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] = rate;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = bits;
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] = rate;
this->input.mode = mode;
this->input.rate = rate;
@@ -861,9 +861,10 @@ static int ao_control (ao_instance_t *this, int cmd, ...) {
return rval;
}
-ao_instance_t *ao_new_instance (xine_ao_driver_t *driver, xine_t *xine) {
+ao_instance_t *ao_new_instance (xine_ao_driver_t *driver,
+ xine_stream_t *stream) {
- config_values_t *config = xine->config;
+ config_values_t *config = stream->xine->config;
ao_instance_t *this;
int i;
static char *resample_modes[] = {"auto", "off", "on", NULL};
@@ -871,8 +872,9 @@ ao_instance_t *ao_new_instance (xine_ao_driver_t *driver, xine_t *xine) {
this = xine_xmalloc (sizeof (ao_instance_t)) ;
this->driver = driver;
- this->metronom = xine->metronom;
- this->xine = xine;
+ this->metronom = stream->metronom;
+ this->xine = stream->xine;
+ this->stream = stream;
pthread_mutex_init( &this->driver_lock, NULL );
this->open = ao_open;
diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h
index e43d5f3a4..68e0ca750 100644
--- a/src/xine-engine/audio_out.h
+++ b/src/xine-engine/audio_out.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.h,v 1.34 2002/09/18 00:51:34 guenter Exp $
+ * $Id: audio_out.h,v 1.35 2002/10/14 15:47:27 guenter Exp $
*/
#ifndef HAVE_AUDIO_OUT_H
#define HAVE_AUDIO_OUT_H
@@ -124,6 +124,8 @@ struct xine_ao_driver_s {
* See AO_CTRL_* below.
*/
int (*control) (xine_ao_driver_t *this, int cmd, /* arg */ ...);
+
+ void *node;
};
/*
@@ -203,9 +205,10 @@ struct ao_instance_s {
/* private stuff */
xine_ao_driver_t *driver;
- pthread_mutex_t driver_lock;
- metronom_t *metronom;
- xine_t *xine;
+ pthread_mutex_t driver_lock;
+ metronom_t *metronom;
+ xine_stream_t *stream;
+ xine_t *xine;
int audio_loop_running;
int audio_paused;
@@ -231,20 +234,12 @@ struct ao_instance_s {
int64_t passthrough_offset;
};
-/* This initiates the audio_out sync routines
+/*
+ * this initiates the audio_out sync routines
* found in ./src/xine-engine/audio_out.c
*/
-ao_instance_t *ao_new_instance (xine_ao_driver_t *driver, xine_t *xine) ;
-/*
- * to build a dynamic audio output plugin,
- * you have to implement these driver:
- *
- *
- * xine_ao_driver_t *init_audio_out_plugin (config_values_t *config)
- *
- * init this plugin, check if device is available
- *
- */
+ao_instance_t *ao_new_instance (xine_ao_driver_t *driver,
+ xine_stream_t *stream) ;
/*
* audio output modes + capabilities
diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c
index 008f6ca1d..8453bf91f 100644
--- a/src/xine-engine/demux.c
+++ b/src/xine-engine/demux.c
@@ -32,92 +32,92 @@
* indication must be sent. relative discontinuities are likely
* to cause "jumps" on metronom.
*/
-void xine_demux_flush_engine (xine_t *this) {
+void xine_demux_flush_engine (xine_stream_t *stream) {
buf_element_t *buf;
- this->video_fifo->clear(this->video_fifo);
+ stream->video_fifo->clear(stream->video_fifo);
- if( this->audio_fifo )
- this->audio_fifo->clear(this->audio_fifo);
+ if( stream->audio_fifo )
+ stream->audio_fifo->clear(stream->audio_fifo);
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
buf->type = BUF_CONTROL_RESET_DECODER;
- this->video_fifo->put (this->video_fifo, buf);
+ stream->video_fifo->put (stream->video_fifo, buf);
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ if(stream->audio_fifo) {
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_RESET_DECODER;
- this->audio_fifo->put (this->audio_fifo, buf);
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
- this->metronom->adjust_clock(this->metronom,
- this->metronom->get_current_time(this->metronom) + 30 * 90000 );
+ stream->metronom->adjust_clock(stream->metronom,
+ stream->metronom->get_current_time(stream->metronom) + 30 * 90000 );
}
-void xine_demux_control_newpts( xine_t *this, int64_t pts, uint32_t flags ) {
+void xine_demux_control_newpts( xine_stream_t *stream, int64_t pts, uint32_t flags ) {
buf_element_t *buf;
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
buf->type = BUF_CONTROL_NEWPTS;
buf->decoder_flags = flags;
buf->disc_off = pts;
- this->video_fifo->put (this->video_fifo, buf);
+ stream->video_fifo->put (stream->video_fifo, buf);
- if (this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ if (stream->audio_fifo) {
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_NEWPTS;
buf->decoder_flags = flags;
buf->disc_off = pts;
- this->audio_fifo->put (this->audio_fifo, buf);
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
}
-void xine_demux_control_headers_done (xine_t *this) {
+void xine_demux_control_headers_done (xine_stream_t *stream) {
buf_element_t *buf;
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
buf->type = BUF_CONTROL_HEADERS_DONE;
- this->video_fifo->put (this->video_fifo, buf);
+ stream->video_fifo->put (stream->video_fifo, buf);
- if (this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ if (stream->audio_fifo) {
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_HEADERS_DONE;
- this->audio_fifo->put (this->audio_fifo, buf);
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
}
-void xine_demux_control_start( xine_t *this ) {
+void xine_demux_control_start( xine_stream_t *stream ) {
buf_element_t *buf;
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
buf->type = BUF_CONTROL_START;
- this->video_fifo->put (this->video_fifo, buf);
+ stream->video_fifo->put (stream->video_fifo, buf);
- if (this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ if (stream->audio_fifo) {
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_START;
- this->audio_fifo->put (this->audio_fifo, buf);
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
}
-void xine_demux_control_end( xine_t *this, uint32_t flags ) {
+void xine_demux_control_end( xine_stream_t *stream, uint32_t flags ) {
buf_element_t *buf;
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
buf->type = BUF_CONTROL_END;
buf->decoder_flags = flags;
- this->video_fifo->put (this->video_fifo, buf);
+ stream->video_fifo->put (stream->video_fifo, buf);
- if (this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ if (stream->audio_fifo) {
+ buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_END;
buf->decoder_flags = flags;
- this->audio_fifo->put (this->audio_fifo, buf);
+ stream->audio_fifo->put (stream->audio_fifo, buf);
}
}
diff --git a/src/xine-engine/events.c b/src/xine-engine/events.c
index c41486550..1e2c11965 100644
--- a/src/xine-engine/events.c
+++ b/src/xine-engine/events.c
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2000-2001 the xine project
+ * Copyright (C) 2000-2002 the xine project
*
- * This file is part of xine, a unix video player.
+ * This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id:
+ * $Id: events.c,v 1.10 2002/10/14 15:47:33 guenter Exp $
*
* Event handling functions
*
@@ -29,88 +29,185 @@
#include "xine_internal.h"
-int xine_register_event_listener (xine_t *this,
- xine_event_listener_cb_t listener,
- void *user_data) {
- /* Ensure the listener is non-NULL */
- if(listener == NULL) {
- return 0;
+xine_event_t *xine_event_get (xine_event_queue_t *queue) {
+
+ xine_event_t *event;
+
+ pthread_mutex_lock (&queue->lock);
+
+ event = (xine_event_t *) xine_list_first_content (queue->events);
+ if (event)
+ xine_list_delete_current (queue->events);
+
+ pthread_mutex_unlock (&queue->lock);
+
+ return event;
+}
+
+xine_event_t *xine_event_wait (xine_event_queue_t *queue) {
+
+ xine_event_t *event;
+
+ pthread_mutex_lock (&queue->lock);
+
+ while (!(event = (xine_event_t *) xine_list_first_content (queue->events))) {
+ pthread_cond_wait (&queue->new_event, &queue->lock);
}
- pthread_mutex_lock(&this->event_lock);
- /* Check we hava a slot free */
- if(this->num_event_listeners < XINE_MAX_EVENT_LISTENERS) {
+ xine_list_delete_current (queue->events);
+
+ pthread_mutex_unlock (&queue->lock);
+
+ return event;
+}
+
+void xine_event_free (xine_event_t *event) {
+ free (event->data);
+ free (event);
+}
+
+void xine_event_send (xine_stream_t *stream, const xine_event_t *event) {
+
+ xine_event_queue_t *queue;
+
+ pthread_mutex_lock (&stream->event_queues_lock);
+
+ queue = (xine_event_queue_t *)xine_list_first_content (stream->event_queues);
+
+ while (queue) {
+
+ xine_event_t *cevent;
+
+ cevent = malloc (sizeof (xine_event_t));
+ cevent->type = event->type;
+ cevent->stream = event->stream;
+ cevent->data_length = event->data_length;
+ cevent->data = malloc (event->data_length);
+ memcpy (cevent->data, event->data, event->data_length);
- this->event_listeners[this->num_event_listeners] = listener;
- this->event_listener_user_data[this->num_event_listeners] = user_data;
+ pthread_mutex_lock (&queue->lock);
+ xine_list_append_content (queue->events, cevent);
+ pthread_cond_signal (&queue->new_event);
+ pthread_mutex_unlock (&queue->lock);
+
+ queue=(xine_event_queue_t *)xine_list_next_content (stream->event_queues);
+ }
+
+ pthread_mutex_unlock (&stream->event_queues_lock);
+}
+
+
+xine_event_queue_t *xine_event_new_queue (xine_stream_t *stream) {
+
+ xine_event_queue_t *queue;
- this->num_event_listeners++;
+ queue = malloc (sizeof (xine_event_queue_t));
- pthread_mutex_unlock(&this->event_lock);
- return 1;
- }
+ pthread_mutex_init (&queue->lock, NULL);
+ pthread_cond_init (&queue->new_event, NULL);
+ queue->events = xine_list_new ();
+ queue->stream = stream;
- pthread_mutex_unlock(&this->event_lock);
- return 0;
+ pthread_mutex_lock (&stream->event_queues_lock);
+ xine_list_append_content (stream->event_queues, queue);
+ pthread_mutex_unlock (&stream->event_queues_lock);
+
+ return queue;
}
-void xine_send_event(xine_t *this, xine_event_t *event) {
- uint16_t i;
+void xine_event_dispose_queue (xine_event_queue_t *queue) {
+
+ xine_stream_t *stream = queue->stream;
+ xine_event_t *event;
+ xine_event_t qevent;
+ xine_event_queue_t *q;
+
+ pthread_mutex_lock (&stream->event_queues_lock);
+
+ q = (xine_event_queue_t *) xine_list_first_content (stream->event_queues);
+
+ while (q && (q != queue))
+ q = (xine_event_queue_t *) xine_list_next_content (stream->event_queues);
+
+ if (!q) {
+ printf ("events: tried to dispose queue which is not in list\n");
+
+ pthread_mutex_unlock (&stream->event_queues_lock);
+ return;
+ }
+
+ xine_list_delete_current (stream->event_queues);
+ pthread_mutex_unlock (&stream->event_queues_lock);
+
+ /*
+ * send quit event
+ */
- pthread_mutex_lock(&this->event_lock);
- while (this->event_pending[event->type])
- /* there is already one event of that type around */
- pthread_cond_wait(&this->event_handled, &this->event_lock);
- this->event_pending[event->type] = 1;
- pthread_mutex_unlock(&this->event_lock);
+ qevent.type = XINE_EVENT_QUIT;
+ qevent.data_length = 0;
+
+ pthread_mutex_lock (&queue->lock);
+ xine_list_append_content (queue->events, &event);
+ pthread_cond_signal (&queue->new_event);
+ pthread_mutex_unlock (&queue->lock);
+
+ /*
+ * join listener thread, if any
+ */
- /* Iterate through all event handlers */
- for(i=0; i < this->num_event_listeners; i++) {
- (this->event_listeners[i]) ((void *)this->event_listener_user_data[i], event);
+ if (queue->listener_thread) {
+ void *p;
+ pthread_join (*queue->listener_thread, &p);
}
- this->event_pending[event->type] = 0;
- pthread_cond_signal(&this->event_handled);
+ /*
+ * clean up pending events
+ */
+
+ while ( (event = xine_event_get (queue)) ) {
+ xine_event_free (event);
+ }
+
+ free (queue);
}
-int xine_remove_event_listener(xine_t *this,
- xine_event_listener_cb_t listener) {
- uint16_t i, found, pending;
-
- found = 1;
-
- pthread_mutex_lock(&this->event_lock);
- /* wait for any pending events */
- do {
- pending = 0;
- for (i = 0; i < XINE_MAX_EVENT_TYPES; i++)
- pending += this->event_pending[i];
- if (pending)
- pthread_cond_wait(&this->event_handled, &this->event_lock);
- } while (pending);
-
- i = 0;
- /* Attempt to find the listener */
- while((found == 1) && (i < this->num_event_listeners)) {
- if(this->event_listeners[i] == listener) {
- /* Set found flag */
- found = 0;
-
- this->event_listeners[i] = NULL;
-
- /* If possible, move the last listener to the hole thats left */
- if(this->num_event_listeners > 1) {
- this->event_listeners[i] = this->event_listeners[this->num_event_listeners - 1];
- this->event_listener_user_data[i] = this->event_listener_user_data[this->num_event_listeners - 1];
- this->event_listeners[this->num_event_listeners - 1] = NULL;
- }
-
- this->num_event_listeners --;
- }
-
- i++;
+
+static void *listener_loop (void *queue_gen) {
+
+ xine_event_queue_t *queue = (xine_event_queue_t *) queue_gen;
+ int running = 1;
+
+ while (running) {
+
+ xine_event_t *event;
+
+ event = xine_event_wait (queue);
+
+ if (event->type == XINE_EVENT_QUIT)
+ running = 0;
+ else
+ queue->callback (queue->user_data, event);
+
+ xine_event_free (event);
}
- pthread_mutex_unlock(&this->event_lock);
- return found;
+ pthread_exit(NULL);
+}
+
+
+void xine_event_create_listener_thread (xine_event_queue_t *queue,
+ xine_event_listener_cb_t callback,
+ void *user_data) {
+ int err;
+
+ queue->listener_thread = malloc (sizeof (pthread_t));
+ queue->callback = callback;
+ queue->user_data = user_data;
+
+ if ((err = pthread_create (queue->listener_thread,
+ NULL, listener_loop, queue)) != 0) {
+ fprintf (stderr, "events: can't create new thread (%s)\n",
+ strerror(err));
+ abort();
+ }
}
diff --git a/src/xine-engine/events.h b/src/xine-engine/events.h
deleted file mode 100644
index b96416694..000000000
--- a/src/xine-engine/events.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2000-2001 the xine project
- *
- * Copyright (C) Rich Wareham <richwareham@users.sourceforge.net> - July 2001
- *
- * This file is part of xine, a unix video player.
- *
- * xine is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * xine is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- */
-
-#ifndef HAVE_EVENTS_H
-#define HAVE_EVENTS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <inttypes.h>
-
-/*
- * This file defines types for many events which can be sent in xine.
- */
-
-/* event types */
-
-#define XINE_EVENT_MOUSE_BUTTON 1
-#define XINE_EVENT_MOUSE_MOVE 2
-#define XINE_EVENT_SPU_BUTTON 3
-#define XINE_EVENT_SPU_CLUT 4
-#define XINE_EVENT_UI_CHANNELS_CHANGED 5 /* inform ui that new channel info is available */
-#define XINE_EVENT_UI_SET_TITLE 6 /* request title display change in ui */
-#define XINE_EVENT_INPUT_MENU1 7
-#define XINE_EVENT_INPUT_MENU2 8
-#define XINE_EVENT_INPUT_MENU3 9
-#define XINE_EVENT_INPUT_UP 10
-#define XINE_EVENT_INPUT_DOWN 11
-#define XINE_EVENT_INPUT_LEFT 12
-#define XINE_EVENT_INPUT_RIGHT 13
-#define XINE_EVENT_INPUT_SELECT 14
-#define XINE_EVENT_PLAYBACK_FINISHED 15
-#define XINE_EVENT_BRANCHED 16
-#define XINE_EVENT_NEED_NEXT_MRL 17
-#define XINE_EVENT_INPUT_NEXT 18
-#define XINE_EVENT_INPUT_PREVIOUS 19
-#define XINE_EVENT_INPUT_ANGLE_NEXT 20
-#define XINE_EVENT_INPUT_ANGLE_PREVIOUS 21
-#define XINE_EVENT_SPU_FORCEDISPLAY 22
-#define XINE_EVENT_FRAME_CHANGE 23
-#define XINE_EVENT_CLOSED_CAPTION 24
-#define XINE_EVENT_INPUT_BUTTON_FORCE 25
-#define XINE_EVENT_INPUT_MENU4 26
-#define XINE_EVENT_INPUT_MENU5 27
-#define XINE_EVENT_INPUT_MENU6 28
-#define XINE_EVENT_INPUT_MENU7 29
-
-#define XINE_EVENT_INPUT_NUMBER_0 30
-#define XINE_EVENT_INPUT_NUMBER_1 31
-#define XINE_EVENT_INPUT_NUMBER_2 32
-#define XINE_EVENT_INPUT_NUMBER_3 33
-#define XINE_EVENT_INPUT_NUMBER_4 34
-#define XINE_EVENT_INPUT_NUMBER_5 35
-#define XINE_EVENT_INPUT_NUMBER_6 36
-#define XINE_EVENT_INPUT_NUMBER_7 37
-#define XINE_EVENT_INPUT_NUMBER_8 38
-#define XINE_EVENT_INPUT_NUMBER_9 39
-#define XINE_EVENT_INPUT_NUMBER_10_ADD 40
-
-#define XINE_EVENT_ASPECT_CHANGE 41 /* Generally should be viewed as a hint to the GUI */
-#define XINE_EVENT_OUTPUT_VIDEO 42
-#define XINE_EVENT_OUTPUT_NO_VIDEO 43
-
-
-/*
- * generic event type.
- */
-typedef struct {
- uint32_t type; /* The event type (determines remainder of struct) */
-
- /* Event dependent data goes after this. */
-} xine_event_t;
-
-/*
- * input events
- */
-typedef struct {
- xine_event_t event;
- uint8_t button; /* Generally 1 = left, 2 = mid, 3 = right */
- uint16_t x,y; /* In Image space */
-} xine_input_event_t;
-
-/*
- * Menu events
- */
-typedef struct {
- xine_event_t event;
- uint8_t button; /* Generally 1 = left, 2 = mid, 3 = right */
- uint16_t status; /* 0:no status, 1:selected, 2:actioned */
- uint8_t command[8]; /* DVD virtual machine command. */
-} xine_menu_event_t;
-
-/*
- * SPU event - send control events to the spu decoder
- */
-typedef struct {
- xine_event_t event;
- void *data;
-} xine_spu_event_t;
-
-/*
- * UI event - send information to/from UI.
- */
-
-typedef struct {
- xine_event_t event;
- void *data;
- uint32_t data_len;
- int handled;
-} xine_ui_event_t;
-
-/*
- * next_mrl
- */
-typedef struct {
- xine_event_t event;
- char *mrl;
- int handled;
-} xine_next_mrl_event_t;
-
-/*
- * notify frame change
- */
-typedef struct {
- xine_event_t event;
- int width;
- int height;
- int aspect;
-} xine_frame_change_event_t;
-
-/*
- * closed caption
- */
-typedef struct {
- xine_event_t event;
- uint8_t *buffer;
- uint32_t buf_len;
- int64_t pts;
- uint32_t scr;
-} xine_closed_caption_event_t;
-
-/*
- * Aspect ratio change (suggested)
- */
-typedef struct {
- xine_event_t event;
- int ratio_code;
- int scale_permission;
-} xine_aspect_ratio_event_t;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAVE_EVENTS_H */
-
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index e248a2777..0bc17c9ff 100644
--- a/src/xine-engine/load_plugins.c
+++ b/src/xine-engine/load_plugins.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: load_plugins.c,v 1.98 2002/09/22 14:29:40 mroi Exp $
+ * $Id: load_plugins.c,v 1.99 2002/10/14 15:47:37 guenter Exp $
*
*
* Load input/demux/audio_out/video_out/codec plugins
@@ -135,11 +135,13 @@ static void _insert_plugin (xine_t *this,
}
entry = xine_xmalloc(sizeof(plugin_node_t));
- entry->filename = _strclone(filename);
- entry->info = xine_xmalloc(sizeof(plugin_info_t));
- *(entry->info) = *info;
- entry->info->id = _strclone(info->id);
- entry->info->init = NULL;
+ entry->filename = _strclone(filename);
+ entry->info = xine_xmalloc(sizeof(plugin_info_t));
+ *(entry->info) = *info;
+ entry->info->id = _strclone(info->id);
+ entry->info->init = NULL;
+ entry->plugin_class = NULL;
+ entry->ref = 0;
switch (info->type){
@@ -188,7 +190,7 @@ static void _insert_plugin (xine_t *this,
}
-static plugin_catalog_t *_empty_catalog(void){
+static plugin_catalog_t *_new_catalog(void){
plugin_catalog_t *catalog;
@@ -201,6 +203,8 @@ static plugin_catalog_t *_empty_catalog(void){
catalog->aout = xine_list_new();
catalog->vout = xine_list_new();
+ pthread_mutex_init (&catalog->lock, NULL);
+
return catalog;
}
@@ -328,9 +332,9 @@ static void collect_plugins(xine_t *this, char *path){
* generic 2nd stage plugin loader
*/
-static void *_load_plugin(xine_t *this,
- char *filename, plugin_info_t *target,
- void *data) {
+static void *_load_plugin_class(xine_t *this,
+ char *filename, plugin_info_t *target,
+ void *data) {
void *lib;
@@ -385,7 +389,7 @@ static void load_plugins(xine_t *this) {
node->info->id, node->filename);
#endif
- node->plugin = _load_plugin(this, node->filename, node->info, NULL);
+ node->plugin_class = _load_plugin_class (this, node->filename, node->info, NULL);
node = xine_list_next_content (this->plugin_catalog->input);
}
@@ -402,7 +406,7 @@ static void load_plugins(xine_t *this) {
node->info->id, node->filename);
#endif
- node->plugin = _load_plugin(this, node->filename, node->info, NULL);
+ node->plugin_class = _load_plugin_class (this, node->filename, node->info, NULL);
node = xine_list_next_content (this->plugin_catalog->demux);
}
@@ -585,7 +589,7 @@ void scan_plugins (xine_t *this) {
abort();
}
- this->plugin_catalog = _empty_catalog();
+ this->plugin_catalog = _new_catalog();
/* TODO: add more plugin dir(s), maybe ~/.xine/plugins or /usr/local/... */
collect_plugins(this, XINE_PLUGINDIR);
@@ -594,7 +598,108 @@ void scan_plugins (xine_t *this) {
map_decoders (this);
}
-static const char **_xine_get_featured_input_plugin_ids(xine_t *this, int feature) {
+/*
+ * input / demuxer plugin loading
+ */
+
+input_plugin_t *find_input_plugin (xine_stream_t *stream, const char *mrl) {
+
+ xine_t *xine = stream->xine;
+ plugin_catalog_t *catalog = xine->plugin_catalog;
+ plugin_node_t *node;
+
+ pthread_mutex_lock (&catalog->lock);
+
+ node = xine_list_first_content (catalog->input);
+ while (node) {
+ input_plugin_t *plugin;
+
+ if ((plugin = node->info->open (node->plugin_class, stream, mrl))) {
+ pthread_mutex_unlock (&catalog->lock);
+ return plugin;
+ }
+
+ node = xine_list_next_content (stream->xine->plugin_catalog->input);
+ }
+
+ pthread_mutex_unlock (&catalog->lock);
+
+ return NULL;
+}
+
+static demux_plugin_t *probe_demux (xine_stream_t *stream, int method1, int method2,
+ input_plugin_t *input) {
+
+ int i;
+ int methods[3];
+ xine_t *xine = stream->xine;
+ plugin_catalog_t *catalog = xine->plugin_catalog;
+
+ methods[0] = method1;
+ methods[1] = method2;
+ methods[2] = -1;
+
+ if (methods[0] == -1) {
+ printf ("load_plugins: probe_demux method1 = %d is not allowed \n", method1);
+ abort();
+ }
+
+ i = 0;
+ while (methods[i] != -1) {
+
+ plugin_node_t *node;
+
+ stream->content_detection_method = methods[i];
+
+ pthread_mutex_lock (&catalog->lock);
+
+ node = xine_list_first_content (catalog->demux);
+
+ while (node) {
+ demux_plugin_t *plugin;
+
+ if ((plugin = node->info->open (node->plugin_class, stream, input))) {
+ pthread_mutex_unlock (&catalog->lock);
+ return plugin;
+ }
+
+ node = xine_list_next_content (stream->xine->plugin_catalog->demux);
+ }
+
+ pthread_mutex_unlock (&catalog->lock);
+
+ i++;
+ }
+
+ return NULL;
+}
+
+demux_plugin_t *find_demux_plugin (xine_stream_t *stream, input_plugin_t *input) {
+
+ switch (stream->xine->demux_strategy) {
+
+ case XINE_DEMUX_DEFAULT_STRATEGY:
+ return probe_demux (stream, METHOD_BY_CONTENT, METHOD_BY_EXTENSION, input);
+
+ case XINE_DEMUX_REVERT_STRATEGY:
+ return probe_demux (stream, METHOD_BY_EXTENSION, METHOD_BY_CONTENT, input);
+
+ case XINE_DEMUX_CONTENT_STRATEGY:
+ return probe_demux (stream, METHOD_BY_CONTENT, -1, input);
+
+ case XINE_DEMUX_EXTENSION_STRATEGY:
+ return probe_demux (stream, METHOD_BY_EXTENSION, -1, input);
+
+ default:
+ printf ("load_plugins: unknown content detection strategy %d\n",
+ stream->xine->demux_strategy);
+ abort();
+ }
+
+ return NULL;
+}
+
+const char *const *xine_get_autoplay_input_plugin_ids(xine_t *this) {
plugin_catalog_t *catalog;
int i;
@@ -602,13 +707,15 @@ static const char **_xine_get_featured_input_plugin_ids(xine_t *this, int featur
catalog = this->plugin_catalog;
+ pthread_mutex_lock (&catalog->lock);
+
i = 0;
node = xine_list_first_content (catalog->input);
while (node) {
- input_plugin_t *ip;
+ input_class_t *ic;
- ip = (input_plugin_t *) node->plugin;
- if (ip->get_capabilities(ip) & feature) {
+ ic = (input_class_t *) node->plugin_class;
+ if (ic->get_autoplay_list) {
catalog->ids[i] = node->info->id;
@@ -619,20 +726,45 @@ static const char **_xine_get_featured_input_plugin_ids(xine_t *this, int featur
catalog->ids[i] = NULL;
+ pthread_mutex_unlock (&catalog->lock);
+
return catalog->ids;
}
-const char *const *xine_get_autoplay_input_plugin_ids(xine_t *this) {
+const char *const *xine_get_browsable_input_plugin_ids(xine_t *this) {
- return (_xine_get_featured_input_plugin_ids(this, INPUT_CAP_AUTOPLAY));
-}
-const char *const *xine_get_browsable_input_plugin_ids(xine_t *this) {
+ plugin_catalog_t *catalog;
+ int i;
+ plugin_node_t *node;
+
+ catalog = this->plugin_catalog;
- return (_xine_get_featured_input_plugin_ids(this, INPUT_CAP_GET_DIR));
+ pthread_mutex_lock (&catalog->lock);
+
+ i = 0;
+ node = xine_list_first_content (catalog->input);
+ while (node) {
+ input_class_t *ic;
+
+ ic = (input_class_t *) node->plugin_class;
+ if (ic->get_dir) {
+
+ catalog->ids[i] = node->info->id;
+
+ i++;
+ }
+ node = xine_list_next_content (catalog->input);
+ }
+
+ catalog->ids[i] = NULL;
+
+ pthread_mutex_unlock (&catalog->lock);
+
+ return catalog->ids;
}
-const char *xine_get_input_plugin_description(xine_t *this, const char *plugin_id) {
+const char *xine_get_input_plugin_description (xine_t *this, const char *plugin_id) {
plugin_catalog_t *catalog;
plugin_node_t *node;
@@ -644,9 +776,9 @@ const char *xine_get_input_plugin_description(xine_t *this, const char *plugin_i
if (!strcasecmp (node->info->id, plugin_id)) {
- input_plugin_t *ip = (input_plugin_t *) node->plugin;
+ input_class_t *ic = (input_class_t *) node->plugin_class;
- return ip->get_description(ip);
+ return ic->get_description(ic);
}
node = xine_list_next_content (catalog->input);
}
@@ -657,32 +789,61 @@ const char *xine_get_input_plugin_description(xine_t *this, const char *plugin_i
* video out plugins section
*/
+static xine_vo_driver_t *_load_video_driver (xine_t *this, plugin_node_t *node,
+ void *data) {
+
+ xine_vo_driver_t *driver;
+
+ if (!node->plugin_class)
+ node->plugin_class = _load_plugin_class (this, node->filename, node->info, data);
+
+ if (!node->plugin_class)
+ return NULL;
+
+ driver = (xine_vo_driver_t *) node->info->open (node->plugin_class, NULL, data);
+
+ if (driver) {
+ driver->node = node;
+ node->ref ++;
+ } else {
+
+ /* FIXME
+ if (!node->ref)
+ unload class
+ */
+ }
+
+ return driver;
+}
+
xine_vo_driver_t *xine_open_video_driver (xine_t *this,
- const char *id,
- int visual_type, void *visual) {
+ const char *id,
+ int visual_type, void *visual) {
plugin_node_t *node;
xine_vo_driver_t *driver;
vo_info_t *vo_info;
+ plugin_catalog_t *catalog = this->plugin_catalog;
driver = NULL;
- node = xine_list_first_content (this->plugin_catalog->vout);
+ pthread_mutex_lock (&catalog->lock);
+
+ node = xine_list_first_content (catalog->vout);
while (node) {
vo_info = node->info->special_info;
if (vo_info->visual_type == visual_type) {
if (id) {
if (!strcasecmp (node->info->id, id)) {
- driver = (xine_vo_driver_t*)_load_plugin (this, node->filename,
- node->info, visual);
+ driver = _load_video_driver (this, node, visual);
break;
}
} else {
- driver = (xine_vo_driver_t*)_load_plugin (this, node->filename,
- node->info, visual);
+ driver = _load_video_driver (this, node, visual);
+
if (driver) {
xine_cfg_entry_t entry;
@@ -699,12 +860,14 @@ xine_vo_driver_t *xine_open_video_driver (xine_t *this,
}
}
- node = xine_list_next_content (this->plugin_catalog->vout);
+ node = xine_list_next_content (catalog->vout);
}
if (!driver)
printf ("load_plugins: failed to load video output plugin <%s>\n", id);
+ pthread_mutex_unlock (&catalog->lock);
+
return driver;
}
@@ -720,6 +883,8 @@ const char *const *xine_list_audio_output_plugins (xine_t *this) {
catalog = this->plugin_catalog;
+ pthread_mutex_lock (&catalog->lock);
+
i = 0;
node = xine_list_first_content (catalog->aout);
while (node) {
@@ -733,6 +898,8 @@ const char *const *xine_list_audio_output_plugins (xine_t *this) {
catalog->ids[i] = NULL;
+ pthread_mutex_unlock (&catalog->lock);
+
return catalog->ids;
}
@@ -744,6 +911,8 @@ const char *const *xine_list_video_output_plugins (xine_t *this) {
catalog = this->plugin_catalog;
+ pthread_mutex_lock (&catalog->lock);
+
i = 0;
node = xine_list_first_content (catalog->vout);
while (node) {
@@ -757,15 +926,47 @@ const char *const *xine_list_video_output_plugins (xine_t *this) {
catalog->ids[i] = NULL;
+ pthread_mutex_unlock (&catalog->lock);
+
return catalog->ids;
}
+static xine_ao_driver_t *_load_audio_driver (xine_t *this, plugin_node_t *node,
+ void *data) {
+
+ xine_ao_driver_t *driver;
+
+ if (!node->plugin_class)
+ node->plugin_class = _load_plugin_class (this, node->filename, node->info, data);
+
+ if (!node->plugin_class)
+ return NULL;
+
+ driver = (xine_ao_driver_t *) node->info->open (node->plugin_class, NULL, data);
+
+ if (driver) {
+ driver->node = node;
+ node->ref ++;
+ } else {
+
+ /* FIXME
+ if (!node->ref)
+ unload class
+ */
+ }
+
+ return driver;
+}
+
xine_ao_driver_t *xine_open_audio_driver (xine_t *this, const char *id,
- void *data) {
+ void *data) {
plugin_node_t *node;
xine_ao_driver_t *driver;
ao_info_t *ao_info;
+ plugin_catalog_t *catalog = this->plugin_catalog;
+
+ pthread_mutex_lock (&catalog->lock);
driver = NULL;
@@ -776,11 +977,11 @@ xine_ao_driver_t *xine_open_audio_driver (xine_t *this, const char *id,
if (id) {
if (!strcasecmp(node->info->id, id)) {
- driver = (xine_ao_driver_t*)_load_plugin(this, node->filename, node->info, data);
+ driver = _load_audio_driver (this, node, data);
break;
}
} else {
- driver = (xine_ao_driver_t*)_load_plugin (this, node->filename, node->info, data);
+ driver = _load_audio_driver (this, node, data);
if (driver) {
xine_cfg_entry_t entry;
@@ -805,9 +1006,19 @@ xine_ao_driver_t *xine_open_audio_driver (xine_t *this, const char *id,
else
printf ("load_plugins: audio output auto-probing didn't find any usable audio driver.\n");
}
+
+ pthread_mutex_unlock (&catalog->lock);
+
return driver;
}
+void xine_close_audio_driver (xine_t *this, xine_ao_driver_t *driver) {
+
+ /* FIXME : implement */
+
+}
+
+
/*
* get autoplay mrl list from input plugin
*/
@@ -825,14 +1036,12 @@ char **xine_get_autoplay_mrls (xine_t *this, const char *plugin_id,
if (!strcasecmp (node->info->id, plugin_id)) {
- input_plugin_t *ip = (input_plugin_t *) node->plugin;
+ input_class_t *ic = (input_class_t *) node->plugin_class;
- if (!( ip->get_capabilities(ip) & INPUT_CAP_AUTOPLAY))
+ if (!ic->get_autoplay_list)
return NULL;
- /* this->cur_input_plugin = ip; FIXME: needed? */
-
- return ip->get_autoplay_list (ip, num_mrls);
+ return ic->get_autoplay_list (ic, num_mrls);
}
node = xine_list_next_content (catalog->input);
}
@@ -855,117 +1064,223 @@ xine_mrl_t **xine_get_browse_mrls (xine_t *this, const char *plugin_id,
if (!strcasecmp (node->info->id, plugin_id)) {
- input_plugin_t *ip = (input_plugin_t *) node->plugin;
+ input_class_t *ic = (input_class_t *) node->plugin_class;
- if (!( ip->get_capabilities(ip) & INPUT_CAP_GET_DIR))
+ if (!ic->get_dir)
return NULL;
- return ip->get_dir (ip, start_mrl, num_mrls);
+ return ic->get_dir (ic, start_mrl, num_mrls);
}
node = xine_list_next_content (catalog->input);
}
return NULL;
}
-video_decoder_t *get_video_decoder (xine_t *this, uint8_t stream_type) {
+video_decoder_t *get_video_decoder (xine_stream_t *stream, uint8_t stream_type) {
- plugin_node_t *node;
- int i, j;
+ plugin_node_t *node;
+ int i, j;
+ plugin_catalog_t *catalog = stream->xine->plugin_catalog;
#ifdef LOG
printf ("load_plugins: looking for video decoder for streamtype %02x\n",
stream_type);
#endif
+ pthread_mutex_lock (&catalog->lock);
+
for (i = 0; i < PLUGINS_PER_TYPE; i++) {
- node = this->plugin_catalog->video_decoder_map[stream_type][i];
+
+ video_decoder_t *vd=NULL;
+
+ node = catalog->video_decoder_map[stream_type][i];
- if (!node)
+ if (!node) {
+ pthread_mutex_unlock (&catalog->lock);
return NULL;
+ }
- if (!node->plugin)
- node->plugin = _load_plugin(this, node->filename, node->info, NULL);
+ if (!node->plugin_class)
+ node->plugin_class = _load_plugin_class (stream->xine, node->filename,
+ node->info, NULL);
- if (node->plugin)
- return node->plugin;
- else {
+ if (!node->plugin_class) {
/* remove non working plugin from catalog */
for (j = i + 1; j < PLUGINS_PER_TYPE; j++)
- this->plugin_catalog->video_decoder_map[stream_type][j - 1] =
- this->plugin_catalog->video_decoder_map[stream_type][j];
- this->plugin_catalog->video_decoder_map[stream_type][PLUGINS_PER_TYPE] = NULL;
+ catalog->video_decoder_map[stream_type][j - 1] =
+ catalog->video_decoder_map[stream_type][j];
+ catalog->video_decoder_map[stream_type][PLUGINS_PER_TYPE] = NULL;
i--;
+ pthread_mutex_unlock (&catalog->lock);
+ return NULL;
}
+
+ vd = (video_decoder_t *) node->info->open (node->plugin_class, stream, NULL);
+
+ if (vd) {
+ vd->node = node;
+ node->ref ++;
+ }
+
+ pthread_mutex_unlock (&catalog->lock);
+ return vd;
}
+
+ pthread_mutex_unlock (&catalog->lock);
return NULL;
}
-audio_decoder_t *get_audio_decoder (xine_t *this, uint8_t stream_type) {
+void free_video_decoder (xine_stream_t *stream, video_decoder_t *vd) {
+ plugin_catalog_t *catalog = stream->xine->plugin_catalog;
+ plugin_node_t *node = vd->node;
+
+ pthread_mutex_lock (&catalog->lock);
+
+ vd->dispose (vd);
+
+ node->ref--;
+ /* FIXME: unload plugin if no-longer used */
+
+ pthread_mutex_unlock (&catalog->lock);
+}
+
+
+audio_decoder_t *get_audio_decoder (xine_stream_t *stream, uint8_t stream_type) {
- plugin_node_t *node;
- int i, j;
+ plugin_node_t *node;
+ int i, j;
+ plugin_catalog_t *catalog = stream->xine->plugin_catalog;
#ifdef LOG
printf ("load_plugins: looking for audio decoder for streamtype %02x\n",
stream_type);
#endif
+ pthread_mutex_lock (&catalog->lock);
+
for (i = 0; i < PLUGINS_PER_TYPE; i++) {
- node = this->plugin_catalog->audio_decoder_map[stream_type][i];
- if (!node)
+ audio_decoder_t *ad;
+
+ node = catalog->audio_decoder_map[stream_type][i];
+
+ if (!node) {
+ pthread_mutex_unlock (&catalog->lock);
return NULL;
+ }
- if (!node->plugin)
- node->plugin = _load_plugin(this, node->filename, node->info, NULL);
+ if (!node->plugin_class)
+ node->plugin_class = _load_plugin_class (stream->xine, node->filename,
+ node->info, NULL);
- if (node->plugin)
- return node->plugin;
- else {
+ if (!node->plugin_class) {
/* remove non working plugin from catalog */
for (j = i + 1; j < PLUGINS_PER_TYPE; j++)
- this->plugin_catalog->audio_decoder_map[stream_type][j - 1] =
- this->plugin_catalog->audio_decoder_map[stream_type][j];
- this->plugin_catalog->audio_decoder_map[stream_type][PLUGINS_PER_TYPE] = NULL;
+ catalog->audio_decoder_map[stream_type][j - 1] =
+ catalog->audio_decoder_map[stream_type][j];
+ catalog->audio_decoder_map[stream_type][PLUGINS_PER_TYPE] = NULL;
i--;
+ pthread_mutex_unlock (&catalog->lock);
+ return NULL;
+ }
+
+ ad = (audio_decoder_t *) node->info->open (node->plugin_class, stream, NULL);
+
+ if (ad) {
+ ad->node = node;
+ node->ref ++;
}
+
+ pthread_mutex_unlock (&catalog->lock);
+ return ad;
}
+
+ pthread_mutex_unlock (&catalog->lock);
return NULL;
}
-spu_decoder_t *get_spu_decoder (xine_t *this, uint8_t stream_type) {
+void free_audio_decoder (xine_stream_t *stream, audio_decoder_t *ad) {
+ plugin_catalog_t *catalog = stream->xine->plugin_catalog;
+ plugin_node_t *node = ad->node;
+
+ pthread_mutex_lock (&catalog->lock);
+
+ ad->dispose (ad);
- plugin_node_t *node;
- int i, j;
+ node->ref--;
+ /* FIXME: unload plugin if no-longer used */
+
+ pthread_mutex_unlock (&catalog->lock);
+}
+
+
+spu_decoder_t *get_spu_decoder (xine_stream_t *stream, uint8_t stream_type) {
+
+ plugin_node_t *node;
+ int i, j;
+ plugin_catalog_t *catalog = stream->xine->plugin_catalog;
#ifdef LOG
printf ("load_plugins: looking for spu decoder for streamtype %02x\n",
stream_type);
#endif
+ pthread_mutex_lock (&catalog->lock);
+
for (i = 0; i < PLUGINS_PER_TYPE; i++) {
- node = this->plugin_catalog->spu_decoder_map[stream_type][i];
+ spu_decoder_t *sd;
+
+ node = catalog->spu_decoder_map[stream_type][i];
- if (!node)
+ if (!node) {
+ pthread_mutex_unlock (&catalog->lock);
return NULL;
+ }
- if (!node->plugin)
- node->plugin = _load_plugin(this, node->filename, node->info, NULL);
+ if (!node->plugin_class)
+ node->plugin_class = _load_plugin_class (stream->xine, node->filename,
+ node->info, NULL);
- if (node->plugin)
- return node->plugin;
- else {
+ if (!node->plugin_class) {
/* remove non working plugin from catalog */
for (j = i + 1; j < PLUGINS_PER_TYPE; j++)
- this->plugin_catalog->spu_decoder_map[stream_type][j - 1] =
- this->plugin_catalog->spu_decoder_map[stream_type][j];
- this->plugin_catalog->spu_decoder_map[stream_type][PLUGINS_PER_TYPE] = NULL;
+ catalog->spu_decoder_map[stream_type][j - 1] =
+ catalog->spu_decoder_map[stream_type][j];
+ catalog->spu_decoder_map[stream_type][PLUGINS_PER_TYPE] = NULL;
i--;
+ pthread_mutex_unlock (&catalog->lock);
+ return NULL;
+ }
+
+ sd = (spu_decoder_t *) node->info->open (node->plugin_class, stream, NULL);
+
+ if (sd) {
+ sd->node = node;
+ node->ref ++;
}
+
+ pthread_mutex_unlock (&catalog->lock);
+ return sd;
}
+
+ pthread_mutex_unlock (&catalog->lock);
return NULL;
}
+void free_spu_decoder (xine_stream_t *stream, spu_decoder_t *sd) {
+ plugin_catalog_t *catalog = stream->xine->plugin_catalog;
+ plugin_node_t *node = sd->node;
+
+ pthread_mutex_lock (&catalog->lock);
+
+ sd->dispose (sd);
+
+ node->ref--;
+ /* FIXME: unload plugin if no-longer used */
+
+ pthread_mutex_unlock (&catalog->lock);
+}
+
/*
* dispose all currently loaded plugins (shutdown)
@@ -973,7 +1288,9 @@ spu_decoder_t *get_spu_decoder (xine_t *this, uint8_t stream_type) {
void dispose_plugins (xine_t *this) {
- /* FIXME: adapt old code */
+/* FIXME */
+
+#if 0
plugin_node_t *node;
node = xine_list_first_content (this->plugin_catalog->demux);
@@ -996,7 +1313,6 @@ void dispose_plugins (xine_t *this) {
node = xine_list_next_content (this->plugin_catalog->input);
}
-#if 0
for (i = 0; i < this->num_audio_decoders_loaded; i++)
this->audio_decoders_loaded[i]->dispose (this->audio_decoders_loaded[i]);
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index d189142c0..de31f1916 100644
--- a/src/xine-engine/metronom.c
+++ b/src/xine-engine/metronom.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: metronom.c,v 1.93 2002/09/05 22:29:17 mroi Exp $
+ * $Id: metronom.c,v 1.94 2002/10/14 15:47:38 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -657,7 +657,7 @@ static int metronom_sync_loop (metronom_t *this) {
scr_plugin_t** scr;
int64_t pts;
- while (((xine_t*)this->xine)->status != XINE_STATUS_QUIT) {
+ while (this->stream->status != XINE_STATUS_QUIT) {
pts = this->scr_master->get_current(this->scr_master);
for (scr = this->scr_list; scr < this->scr_list+MAX_SCR_PROVIDERS; scr++)
@@ -699,12 +699,12 @@ static void metronom_exit (metronom_t *this) {
}
-metronom_t * metronom_init (int have_audio, void *xine) {
+metronom_t * metronom_init (int have_audio, xine_stream_t *stream) {
metronom_t *this = xine_xmalloc (sizeof (metronom_t));
int err;
- this->xine = xine;
+ this->stream = stream;
this->set_audio_rate = metronom_set_audio_rate;
this->got_video_frame = metronom_got_video_frame;
this->got_audio_samples = metronom_got_audio_samples;
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
index 3fb081b37..77ec59614 100644
--- a/src/xine-engine/metronom.h
+++ b/src/xine-engine/metronom.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: metronom.h,v 1.36 2002/09/05 22:29:17 mroi Exp $
+ * $Id: metronom.h,v 1.37 2002/10/14 15:47:39 guenter Exp $
*
* metronom: general pts => virtual calculation/assoc
*
@@ -51,6 +51,7 @@ extern "C" {
#include <sys/time.h>
#include <pthread.h>
#include "video_out.h"
+#include "xine.h"
typedef struct metronom_s metronom_t ;
typedef struct scr_plugin_s scr_plugin_t;
@@ -64,11 +65,6 @@ typedef struct scr_plugin_s scr_plugin_t;
struct metronom_s {
/*
- * pointer to current xine object. a void pointer is used to avoid type declaration clash.
- */
- void *xine;
-
- /*
* called by audio output driver to inform metronom about current audio
* samplerate
*
@@ -206,6 +202,11 @@ struct metronom_s {
void (*exit) (metronom_t *this);
/*
+ * pointer to current xine stream object.
+ */
+ xine_stream_t *stream;
+
+ /*
* metronom internal stuff
*/
@@ -247,7 +248,7 @@ struct metronom_s {
int force_audio_jump;
};
-metronom_t *metronom_init (int have_audio, void *xine);
+metronom_t *metronom_init (int have_audio, xine_stream_t *stream);
/*
* metronom options
diff --git a/src/xine-engine/plugin_catalog.h b/src/xine-engine/plugin_catalog.h
index 9e166d813..fd0581488 100644
--- a/src/xine-engine/plugin_catalog.h
+++ b/src/xine-engine/plugin_catalog.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: plugin_catalog.h,v 1.5 2002/09/09 13:57:13 mroi Exp $
+ * $Id: plugin_catalog.h,v 1.6 2002/10/14 15:47:39 guenter Exp $
*
* xine-internal header: Definitions for plugin lists
*
@@ -36,26 +36,28 @@
#define PLUGINS_PER_TYPE 10
typedef struct {
- char *filename;
- plugin_info_t *info;
- void *plugin;
+ char *filename;
+ plugin_info_t *info;
+ void *plugin_class;
+ int ref; /* count instances created of this plugin */
} plugin_node_t ;
struct plugin_catalog_s {
- xine_list_t *input;
- xine_list_t *demux;
- xine_list_t *spu;
- xine_list_t *audio;
- xine_list_t *video;
- xine_list_t *aout;
- xine_list_t *vout;
+ xine_list_t *input;
+ xine_list_t *demux;
+ xine_list_t *spu;
+ xine_list_t *audio;
+ xine_list_t *video;
+ xine_list_t *aout;
+ xine_list_t *vout;
- plugin_node_t *audio_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE];
- plugin_node_t *video_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE];
- plugin_node_t *spu_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE];
+ plugin_node_t *audio_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE];
+ plugin_node_t *video_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE];
+ plugin_node_t *spu_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE];
- const char *ids[PLUGIN_MAX];
+ const char *ids[PLUGIN_MAX];
+ pthread_mutex_t lock;
};
typedef struct plugin_catalog_s plugin_catalog_t;
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index c910101f4..0464a9e69 100644
--- a/src/xine-engine/video_decoder.c
+++ b/src/xine-engine/video_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_decoder.c,v 1.99 2002/09/18 15:37:43 mroi Exp $
+ * $Id: video_decoder.c,v 1.100 2002/10/14 15:47:40 guenter Exp $
*
*/
@@ -37,28 +37,28 @@
#define VIDEO_DECODER_LOG
*/
-static spu_decoder_t* update_spu_decoder(xine_t *this, int type) {
+static spu_decoder_t* update_spu_decoder (xine_stream_t *this, int type) {
int streamtype = (type>>16) & 0xFF;
spu_decoder_t *spu_decoder = get_spu_decoder (this, streamtype);
- if (spu_decoder && this->cur_spu_decoder_plugin != spu_decoder) {
+ if (spu_decoder && this->spu_decoder_plugin != spu_decoder) {
- if (this->cur_spu_decoder_plugin)
- this->cur_spu_decoder_plugin->close (this->cur_spu_decoder_plugin);
+ if (this->spu_decoder_plugin)
+ this->spu_decoder_plugin->close (this->spu_decoder_plugin);
- this->cur_spu_decoder_plugin = spu_decoder;
+ this->spu_decoder_plugin = spu_decoder;
- this->cur_spu_decoder_plugin->init (this->cur_spu_decoder_plugin,
+ this->spu_decoder_plugin->init (this->spu_decoder_plugin,
this->video_out);
}
return spu_decoder;
}
-void *video_decoder_loop (void *this_gen) {
+void *video_decoder_loop (void *stream_gen) {
buf_element_t *buf;
- xine_t *this = (xine_t *) this_gen;
+ xine_stream_t *stream = (xine_stream_t *) stream_gen;
int running = 1;
int streamtype;
video_decoder_t *decoder;
@@ -78,18 +78,14 @@ void *video_decoder_loop (void *this_gen) {
printf ("video_decoder: getting buffer...\n");
#endif
- buf = this->video_fifo->get (this->video_fifo);
+ buf = stream->video_fifo->get (stream->video_fifo);
if (buf->input_pos)
- this->cur_input_pos = buf->input_pos;
+ stream->input_pos = buf->input_pos;
if (buf->input_length)
- this->cur_input_length = buf->input_length;
+ stream->input_length = buf->input_length;
if (buf->input_time) {
- this->cur_input_time = buf->input_time;
- pthread_mutex_lock (&this->osd_lock);
- if( this->curtime_needed_for_osd && !(--this->curtime_needed_for_osd) )
- xine_internal_osd (this, ">",90000);
- pthread_mutex_unlock (&this->osd_lock);
+ stream->input_time = buf->input_time;
}
#ifdef VIDEO_DECODER_LOG
@@ -98,28 +94,26 @@ void *video_decoder_loop (void *this_gen) {
switch (buf->type & 0xffff0000) {
case BUF_CONTROL_HEADERS_DONE:
- this->header_sent_counter++;
+ pthread_mutex_lock (&stream->counter_lock);
+ stream->header_count_video++;
+ pthread_cond_broadcast (&stream->counter_changed);
+ pthread_mutex_unlock (&stream->counter_lock);
break;
case BUF_CONTROL_START:
- if (this->cur_video_decoder_plugin) {
- this->cur_video_decoder_plugin->close (this->cur_video_decoder_plugin);
- this->cur_video_decoder_plugin = NULL;
+ if (stream->video_decoder_plugin) {
+ free_video_decoder (stream, stream->video_decoder_plugin);
+ stream->video_decoder_plugin = NULL;
}
- if (this->cur_spu_decoder_plugin) {
- this->cur_spu_decoder_plugin->close (this->cur_spu_decoder_plugin);
- this->cur_spu_decoder_plugin = NULL;
+ if (stream->spu_decoder_plugin) {
+ free_spu_decoder (stream, stream->spu_decoder_plugin);
+ stream->spu_decoder_plugin = NULL;
}
- pthread_mutex_lock (&this->finished_lock);
- this->video_finished = 0;
- this->spu_finished = 0;
-
- pthread_mutex_unlock (&this->finished_lock);
-
- this->metronom->handle_video_discontinuity (this->metronom, DISC_STREAMSTART, 0);
+ stream->metronom->handle_video_discontinuity (stream->metronom,
+ DISC_STREAMSTART, 0);
break;
case BUF_SPU_SUBP_CONTROL:
@@ -129,7 +123,7 @@ void *video_decoder_loop (void *this_gen) {
case BUF_SPU_NAV:
xine_profiler_start_count (prof_spu_decode);
- spu_decoder = update_spu_decoder(this, buf->type);
+ spu_decoder = update_spu_decoder(stream, buf->type);
if (spu_decoder) {
spu_decoder->decode_data (spu_decoder, buf);
@@ -140,120 +134,122 @@ void *video_decoder_loop (void *this_gen) {
case BUF_CONTROL_SPU_CHANNEL:
{
- xine_ui_event_t ui_event;
+ xine_event_t ui_event;
/* We use widescreen spu as the auto selection, because widescreen
* display is common. SPU decoders can choose differently if it suits
* them. */
- this->spu_channel_auto = buf->decoder_info[0];
- this->spu_channel_letterbox = buf->decoder_info[1];
- this->spu_channel_pan_scan = buf->decoder_info[2];
- if (this->spu_channel_user == -1)
- this->spu_channel = this->spu_channel_auto;
+ stream->spu_channel_auto = buf->decoder_info[0];
+ stream->spu_channel_letterbox = buf->decoder_info[1];
+ stream->spu_channel_pan_scan = buf->decoder_info[2];
+ if (stream->spu_channel_user == -1)
+ stream->spu_channel = stream->spu_channel_auto;
/* Inform UI of SPU channel changes */
- ui_event.event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
- ui_event.data = NULL;
- xine_send_event(this, &ui_event.event);
-
+ ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
+ ui_event.data_length = 0;
+
+ xine_event_send (stream, &ui_event);
}
break;
case BUF_CONTROL_END:
- if (this->cur_video_decoder_plugin) {
- this->cur_video_decoder_plugin->close (this->cur_video_decoder_plugin);
- this->cur_video_decoder_plugin = NULL;
+ if (stream->video_decoder_plugin) {
+ free_video_decoder (stream, stream->video_decoder_plugin);
+ stream->video_decoder_plugin = NULL;
}
- if (this->cur_spu_decoder_plugin) {
- this->cur_spu_decoder_plugin->close (this->cur_spu_decoder_plugin);
- this->cur_spu_decoder_plugin = NULL;
+ if (stream->spu_decoder_plugin) {
+ free_spu_decoder (stream, stream->spu_decoder_plugin);
+ stream->spu_decoder_plugin = NULL;
}
- pthread_mutex_lock (&this->finished_lock);
- this->spu_finished = 1;
-
- if (!this->video_finished ) {
- this->video_finished = 1;
-
- if (this->audio_finished) {
- if( this->playing_logo )
- buf->decoder_flags = 0;
- this->playing_logo = 0;
-
- if( buf->decoder_flags & BUF_FLAG_END_STREAM )
- xine_notify_stream_finished (this);
- }
+
+ /* wait for audio to reach this marker, if necessary */
+
+ pthread_mutex_lock (&stream->counter_lock);
+
+ stream->finished_count_video++;
+
+ printf ("video_decoder: reached end marker # %d\n",
+ stream->finished_count_video);
+
+ pthread_cond_broadcast (&stream->counter_changed);
+
+ if (stream->stream_info[XINE_STREAM_INFO_HAS_VIDEO]
+ && stream->audio_fifo) {
+
+ while (stream->finished_count_video > stream->finished_count_audio) {
+ pthread_cond_wait (&stream->counter_changed, &stream->counter_lock);
+ }
}
+
+ pthread_mutex_unlock (&stream->counter_lock);
- pthread_mutex_unlock (&this->finished_lock);
+ if (stream->stream_info[XINE_STREAM_INFO_HAS_VIDEO]) {
+ /* set engine status, send frontend notification event */
+ xine_handle_stream_end (stream,
+ buf->decoder_flags & BUF_FLAG_END_STREAM);
+ }
break;
case BUF_CONTROL_QUIT:
- if (this->cur_video_decoder_plugin) {
- this->cur_video_decoder_plugin->close (this->cur_video_decoder_plugin);
- this->cur_video_decoder_plugin = NULL;
+ if (stream->video_decoder_plugin) {
+ free_video_decoder (stream, stream->video_decoder_plugin);
+ stream->video_decoder_plugin = NULL;
}
- if (this->cur_spu_decoder_plugin) {
- this->cur_spu_decoder_plugin->close (this->cur_spu_decoder_plugin);
- this->cur_spu_decoder_plugin = NULL;
+ if (stream->spu_decoder_plugin) {
+ free_spu_decoder (stream, stream->spu_decoder_plugin);
+ stream->spu_decoder_plugin = NULL;
}
running = 0;
break;
case BUF_CONTROL_RESET_DECODER:
- if (this->cur_video_decoder_plugin) {
- this->cur_video_decoder_plugin->reset (this->cur_video_decoder_plugin);
+ if (stream->video_decoder_plugin) {
+ stream->video_decoder_plugin->reset (stream->video_decoder_plugin);
}
- if (this->cur_spu_decoder_plugin) {
- this->cur_spu_decoder_plugin->reset (this->cur_spu_decoder_plugin);
+ if (stream->spu_decoder_plugin) {
+ stream->spu_decoder_plugin->reset (stream->spu_decoder_plugin);
}
break;
case BUF_CONTROL_DISCONTINUITY:
printf ("video_decoder: discontinuity ahead\n");
- this->video_in_discontinuity = 1;
+ stream->video_in_discontinuity = 1;
- this->metronom->handle_video_discontinuity (this->metronom, DISC_RELATIVE, buf->disc_off);
+ stream->metronom->handle_video_discontinuity (stream->metronom, DISC_RELATIVE, buf->disc_off);
- this->video_in_discontinuity = 0;
+ stream->video_in_discontinuity = 0;
break;
case BUF_CONTROL_NEWPTS:
printf ("video_decoder: new pts %lld\n", buf->disc_off);
- this->video_in_discontinuity = 1;
+ stream->video_in_discontinuity = 1;
if (buf->decoder_flags & BUF_FLAG_SEEK) {
- this->metronom->handle_video_discontinuity (this->metronom, DISC_STREAMSEEK, buf->disc_off);
+ stream->metronom->handle_video_discontinuity (stream->metronom, DISC_STREAMSEEK, buf->disc_off);
} else {
- this->metronom->handle_video_discontinuity (this->metronom, DISC_ABSOLUTE, buf->disc_off);
+ stream->metronom->handle_video_discontinuity (stream->metronom, DISC_ABSOLUTE, buf->disc_off);
}
- this->video_in_discontinuity = 0;
+ stream->video_in_discontinuity = 0;
break;
case BUF_CONTROL_AUDIO_CHANNEL:
{
- xine_ui_event_t ui_event;
+ xine_event_t ui_event;
/* Inform UI of AUDIO channel changes */
- ui_event.event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
- ui_event.data = NULL;
- xine_send_event(this, &ui_event.event);
+ ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
+ ui_event.data_length = 0;
+ xine_event_send (stream, &ui_event);
}
break;
case BUF_CONTROL_NOP:
- /* Inform UI of NO_VIDEO usage */
- if(buf->decoder_flags & BUF_FLAG_NO_VIDEO) {
- xine_ui_event_t ui_event;
-
- ui_event.event.type = XINE_EVENT_OUTPUT_NO_VIDEO;
- ui_event.data = this->cur_input_plugin->get_mrl(this->cur_input_plugin);
- xine_send_event(this, &ui_event.event);
- }
break;
default:
@@ -268,44 +264,32 @@ void *video_decoder_loop (void *this_gen) {
streamtype = (buf->type>>16) & 0xFF;
- decoder = get_video_decoder (this, streamtype);
+ decoder = get_video_decoder (stream, streamtype);
if (decoder) {
- if (this->cur_video_decoder_plugin != decoder) {
- xine_ui_event_t ui_event;
+ if (stream->video_decoder_plugin != decoder) {
- if (this->cur_video_decoder_plugin) {
- this->cur_video_decoder_plugin->close (this->cur_video_decoder_plugin);
- printf ("video_decoder: closing old decoder >%s<\n",this->cur_video_decoder_plugin->get_identifier());
+ if (stream->video_decoder_plugin) {
+ free_video_decoder (stream, stream->video_decoder_plugin);
}
- this->cur_video_decoder_plugin = decoder;
- this->cur_video_decoder_plugin->init (this->cur_video_decoder_plugin, this->video_out);
-
- this->meta_info[XINE_META_INFO_VIDEOCODEC]
- = strdup (decoder->get_identifier());
-
- xine_report_codec( this, XINE_CODEC_VIDEO, 0, buf->type, 1);
-
- ui_event.event.type = XINE_EVENT_OUTPUT_VIDEO;
- ui_event.data = this->cur_input_plugin->get_mrl(this->cur_input_plugin);
- xine_send_event(this, &ui_event.event);
-
+ stream->video_decoder_plugin = decoder;
}
- decoder->decode_data (this->cur_video_decoder_plugin, buf);
+ decoder->decode_data (stream->video_decoder_plugin, buf);
- } else if( buf->type != buftype_unknown ) {
- xine_log (this, XINE_LOG_MSG, "video_decoder: no plugin available to handle '%s'\n",
- buf_video_name( buf->type ) );
- xine_report_codec( this, XINE_CODEC_VIDEO, 0, buf->type, 0);
- buftype_unknown = buf->type;
- }
- } else if( buf->type != buftype_unknown ) {
- xine_log (this, XINE_LOG_MSG, "video_decoder: unknown buffer type: %08x\n",
- buf->type );
+ } else if (buf->type != buftype_unknown) {
+ xine_log (stream->xine, XINE_LOG_MSG,
+ "video_decoder: no plugin available to handle '%s'\n",
+ buf_video_name( buf->type ) );
buftype_unknown = buf->type;
+ }
+ } else if (buf->type != buftype_unknown) {
+ xine_log (stream->xine, XINE_LOG_MSG,
+ "video_decoder: unknown buffer type: %08x\n",
+ buf->type );
+ buftype_unknown = buf->type;
}
xine_profiler_stop_count (prof_video_decode);
@@ -320,7 +304,7 @@ void *video_decoder_loop (void *this_gen) {
pthread_exit(NULL);
}
-void video_decoder_init (xine_t *this) {
+void video_decoder_init (xine_stream_t *stream) {
pthread_attr_t pth_attrs;
struct sched_param pth_params;
@@ -333,7 +317,7 @@ void video_decoder_init (xine_t *this) {
* We provide buffers of 8k size instead of 2k for demuxers sending
* larger chunks.
*/
- this->video_fifo = fifo_buffer_new (500, 8192);
+ stream->video_fifo = fifo_buffer_new (500, 8192);
pthread_attr_init(&pth_attrs);
pthread_attr_getschedparam(&pth_attrs, &pth_params);
@@ -341,32 +325,32 @@ void video_decoder_init (xine_t *this) {
pthread_attr_setschedparam(&pth_attrs, &pth_params);
pthread_attr_setscope(&pth_attrs, PTHREAD_SCOPE_SYSTEM);
- if ((err = pthread_create (&this->video_thread,
- &pth_attrs, video_decoder_loop, this)) != 0) {
+ if ((err = pthread_create (&stream->video_thread,
+ &pth_attrs, video_decoder_loop, stream)) != 0) {
fprintf (stderr, "video_decoder: can't create new thread (%s)\n",
strerror(err));
abort();
}
- this->video_in_discontinuity = 0;
+ stream->video_in_discontinuity = 0;
}
-void video_decoder_shutdown (xine_t *this) {
+void video_decoder_shutdown (xine_stream_t *stream) {
buf_element_t *buf;
void *p;
printf ("video_decoder: shutdown...\n");
- /* this->video_fifo->clear(this->video_fifo); */
+ /* stream->video_fifo->clear(stream->video_fifo); */
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
printf ("video_decoder: shutdown...2\n");
buf->type = BUF_CONTROL_QUIT;
- this->video_fifo->put (this->video_fifo, buf);
+ stream->video_fifo->put (stream->video_fifo, buf);
printf ("video_decoder: shutdown...3\n");
- pthread_join (this->video_thread, &p);
+ pthread_join (stream->video_thread, &p);
printf ("video_decoder: shutdown...4\n");
}
diff --git a/src/xine-engine/video_decoder.h b/src/xine-engine/video_decoder.h
new file mode 100644
index 000000000..5fbcfb4d9
--- /dev/null
+++ b/src/xine-engine/video_decoder.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2000-2002 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: video_decoder.h,v 1.3 2002/10/14 15:47:40 guenter Exp $
+ *
+ * xine video decoder plugin interface
+ *
+ */
+
+#ifndef HAVE_VIDEO_DECODER_H
+#define HAVE_VIDEO_DECODER_H
+
+#include <inttypes.h>
+#include "buffer.h"
+
+#define VIDEO_DECODER_IFACE_VERSION 11
+
+/*
+ * generic xine video decoder plugin interface
+ */
+
+typedef struct video_decoder_class_s video_decoder_class_t;
+
+struct video_decoder_class_s {
+
+ /*
+ * return short, human readable identifier for this plugin class
+ */
+ char* (*get_identifier) (video_decoder_class_t *this);
+
+ /*
+ * return human readable (verbose = 1 line) description for
+ * this plugin class
+ */
+ char* (*get_description) (video_decoder_class_t *this);
+};
+
+
+typedef struct video_decoder_s video_decoder_t;
+
+struct video_decoder_s {
+
+ /*
+ * decode data from buf and feed decoded frames to
+ * video output
+ */
+ void (*decode_data) (video_decoder_t *this, buf_element_t *buf);
+
+ /*
+ * reset decoder after engine flush (prepare for new
+ * video data not related to recently decoded data)
+ */
+ void (*reset) (video_decoder_t *this);
+
+ /*
+ * flush out any frames that are still stored in the decoder
+ */
+ void (*flush) (video_decoder_t *this);
+
+ /*
+ * close down, free all resources
+ */
+ void (*dispose) (video_decoder_t *this);
+
+
+ void *node; /*used by plugin loader */
+
+};
+
+#endif
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index 5a9d91fca..879059fb8 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out.c,v 1.104 2002/09/09 03:06:14 miguelfreitas Exp $
+ * $Id: video_out.c,v 1.105 2002/10/14 15:47:41 guenter Exp $
*
* frame allocation / queuing / scheduling / output functions
*/
@@ -54,6 +54,7 @@ typedef struct {
xine_vo_driver_t *driver;
metronom_t *metronom;
xine_t *xine;
+ xine_stream_t *stream;
img_buf_fifo_t *free_img_buf_queue;
img_buf_fifo_t *display_img_buf_queue;
@@ -550,11 +551,11 @@ static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts) {
*/
pthread_mutex_lock( &this->free_img_buf_queue->mutex );
if (img && !img->next &&
- (this->xine->video_fifo->size(this->xine->video_fifo) < 10
- || this->xine->video_in_discontinuity) ) {
+ (this->stream->video_fifo->size(this->stream->video_fifo) < 10
+ || this->stream->video_in_discontinuity) ) {
printf ("video_out: possible still frame (fifosize = %d)\n",
- this->xine->video_fifo->size(this->xine->video_fifo));
+ this->stream->video_fifo->size(this->stream->video_fifo));
this->img_backup = duplicate_frame (this, img);
}
@@ -620,7 +621,7 @@ static void paused_loop( vos_t *this, int64_t vpts )
/* prevent decoder thread from allocating new frames */
this->free_img_buf_queue->locked_for_read = 1;
- while( this->xine->speed == XINE_SPEED_PAUSE ) {
+ while (this->stream->speed == XINE_SPEED_PAUSE) {
/* we need at least one free frame to keep going */
if( this->display_img_buf_queue->first &&
@@ -716,7 +717,7 @@ static void *video_out_loop (void *this_gen) {
diff = vpts - this->last_delivery_pts;
if (diff > 30000 && !this->display_img_buf_queue->first) {
- if (this->xine->cur_video_decoder_plugin) {
+ if (this->stream->video_decoder_plugin) {
#ifdef LOG
printf ("video_out: flushing current video decoder plugin (%d %d)\n",
@@ -724,7 +725,7 @@ static void *video_out_loop (void *this_gen) {
this->free_img_buf_queue->num_buffers);
#endif
- this->xine->cur_video_decoder_plugin->flush(this->xine->cur_video_decoder_plugin);
+ this->stream->video_decoder_plugin->flush(this->stream->video_decoder_plugin);
}
this->last_delivery_pts = vpts;
}
@@ -747,8 +748,8 @@ static void *video_out_loop (void *this_gen) {
do {
vpts = this->metronom->get_current_time (this->metronom);
- if( this->xine->speed == XINE_SPEED_PAUSE )
- paused_loop( this, vpts );
+ if (this->stream->speed == XINE_SPEED_PAUSE)
+ paused_loop (this, vpts);
usec_to_sleep = (next_frame_vpts - vpts) * 100 / 9;
@@ -886,7 +887,8 @@ static void vo_enable_overlay (vo_instance_t *this_gen, int overlay_enabled) {
}
-vo_instance_t *vo_new_instance (xine_vo_driver_t *driver, xine_t *xine) {
+vo_instance_t *vo_new_instance (xine_vo_driver_t *driver,
+ xine_stream_t *stream) {
vos_t *this;
int i;
@@ -898,8 +900,9 @@ vo_instance_t *vo_new_instance (xine_vo_driver_t *driver, xine_t *xine) {
this = xine_xmalloc (sizeof (vos_t)) ;
this->driver = driver;
- this->xine = xine;
- this->metronom = xine->metronom;
+ this->xine = stream->xine;
+ this->metronom = stream->metronom;
+ this->stream = stream;
this->vo.open = vo_open;
this->vo.get_frame = vo_get_frame;
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index fa955cac9..2e7585af7 100644
--- a/src/xine-engine/video_out.h
+++ b/src/xine-engine/video_out.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out.h,v 1.63 2002/10/09 05:13:40 storri Exp $
+ * $Id: video_out.h,v 1.64 2002/10/14 15:47:42 guenter Exp $
*
*
* xine version of video_out.h
@@ -303,6 +303,8 @@ struct xine_vo_driver_s {
*/
int (*redraw_needed) (xine_vo_driver_t *this);
+ void *node; /* needed by plugin_loader */
+
};
typedef struct rle_elem_s {
@@ -363,7 +365,8 @@ video_overlay_instance_t *video_overlay_new_instance ();
* a given video driver
*/
-vo_instance_t *vo_new_instance (xine_vo_driver_t *driver, xine_t *xine) ;
+vo_instance_t *vo_new_instance (xine_vo_driver_t *driver,
+ xine_stream_t *stream) ;
#ifdef __cplusplus
}
diff --git a/src/xine-engine/video_overlay.h b/src/xine-engine/video_overlay.h
index be6d392ff..d2d50348c 100644
--- a/src/xine-engine/video_overlay.h
+++ b/src/xine-engine/video_overlay.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_overlay.h,v 1.8 2002/04/09 13:20:44 jcdutton Exp $
+ * $Id: video_overlay.h,v 1.9 2002/10/14 15:47:43 guenter Exp $
*
*/
@@ -25,6 +25,7 @@
#define HAVE_VIDEO_OVERLAY_H
#include "xine_internal.h"
+#include "events.h"
#ifdef __GNUC__
#define CLUT_Y_CR_CB_INIT(_y,_cr,_cb) {y: (_y), cr: (_cr), cb: (_cb)}
@@ -67,10 +68,10 @@ typedef struct vo_buttons_s {
int32_t right;
uint32_t select_color[OVL_PALETTE_SIZE];
uint8_t select_trans[OVL_PALETTE_SIZE];
- xine_menu_event_t select_event;
+ xine_event_t select_event;
uint32_t active_color[OVL_PALETTE_SIZE];
uint8_t active_trans[OVL_PALETTE_SIZE];
- xine_menu_event_t active_event;
+ xine_event_t active_event;
int32_t clip_rgb_clut; /* true if clut was converted to rgb*/
/* FIXME: Probably not needed ^^^ */
} vo_buttons_t;
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index f8474baf2..51b57d0a1 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine.c,v 1.164 2002/10/12 19:22:05 jkeil Exp $
+ * $Id: xine.c,v 1.165 2002/10/14 15:47:43 guenter Exp $
*
* top-level xine functions
*
@@ -57,507 +57,362 @@
#include "xineutils.h"
#include "compat.h"
-#define LOGO_DELAY 500000 /* usec */
+void xine_notify_stream_finished (xine_stream_t *stream) {
-static void play_logo_internal (xine_t *this) {
- pthread_mutex_lock (&this->logo_lock);
- this->playing_logo = 1;
- if( !xine_open_internal(this, this->logo_mrl) )
- this->playing_logo = 0;
- else {
- xine_play_internal (this, 0, 0);
- this->status = XINE_STATUS_LOGO;
- }
- pthread_mutex_unlock (&this->logo_lock);
-}
-
-/* config callback for logo mrl changing */
-static void _logo_change_cb(void *data, xine_cfg_entry_t *cfg) {
- xine_t *this = (xine_t *) data;
-
- pthread_mutex_lock (&this->logo_lock);
- this->logo_mrl = cfg->str_value;
- pthread_mutex_unlock (&this->logo_lock);
-
- /*
- * Start playback of new mrl only if
- * current status is XINE_STATUS_STOP or XINE_STATUS_LOGO
- */
- pthread_mutex_lock (&this->xine_lock);
- if(this->metronom && (this->status == XINE_STATUS_LOGO || this->status == XINE_STATUS_STOP)) {
- xine_stop_internal(this);
- this->metronom->adjust_clock(this->metronom,
- this->metronom->get_current_time(this->metronom) + 30 * 90000 );
- play_logo_internal(this);
- }
- pthread_mutex_unlock (&this->xine_lock);
-}
-
-void * xine_notify_stream_finished_thread (void * this_gen) {
- xine_t *this = this_gen;
xine_event_t event;
- pthread_mutex_lock (&this->xine_lock);
- xine_stop_internal (this);
- pthread_mutex_unlock (&this->xine_lock);
-
- event.type = XINE_EVENT_PLAYBACK_FINISHED;
- xine_send_event (this, &event);
-
- xine_usec_sleep (LOGO_DELAY);
-
- pthread_mutex_lock (&this->xine_lock);
- if (this->status == XINE_STATUS_STOP) {
- play_logo_internal(this);
- }
- pthread_mutex_unlock (&this->xine_lock);
-
- return NULL;
-}
-
-void xine_notify_stream_finished (xine_t *this) {
- int err;
-
- if (this->status == XINE_STATUS_QUIT)
+ if (stream->status == XINE_STATUS_QUIT)
return;
- if (this->finished_thread_running)
- pthread_join (this->finished_thread, NULL);
-
- this->finished_thread_running = 1;
-
- /* This thread will just execute xine_stop and (possibly) xine_play then die.
- It might look useless but i need to detach this code from the current
- thread to make sure that video_decoder and audio_decoder are running and
- freeing buffers. Free buffers might be needed by the main thread during
- a xine_play, for example.
+ event.data_length = 0;
+ event.type = XINE_EVENT_UI_PLAYBACK_FINISHED;
- This is not a theorical situation: i was able to trigger it with simple
- user actions (play,seek,etc). [MF]
- */
- if ((err = pthread_create (&this->finished_thread,
- NULL, xine_notify_stream_finished_thread, this)) != 0) {
- printf (_("xine_notify_stream_finished: can't create new thread (%s)\n"),
- strerror(err));
- abort();
- }
+ xine_event_send (stream, &event);
}
-void xine_report_codec( xine_t *this, int codec_type, uint32_t fourcc, uint32_t buf_type, int handled ) {
+void xine_report_codec (xine_stream_t *stream, int codec_type,
+ uint32_t fourcc, uint32_t buf_type, int handled) {
- if( this->report_codec_cb ) {
- if( codec_type == XINE_CODEC_VIDEO ) {
- if( !buf_type )
- buf_type = fourcc_to_buf_video( fourcc );
-
- this->report_codec_cb( this->report_codec_user_data,
- codec_type, fourcc,
- buf_video_name( buf_type ), handled );
- } else {
- if( !buf_type )
- buf_type = formattag_to_buf_audio( fourcc );
-
- this->report_codec_cb( this->report_codec_user_data,
- codec_type, fourcc,
- buf_audio_name( buf_type ), handled );
- }
- }
-}
-
-int xine_register_report_codec_cb(xine_t *this,
- xine_report_codec_cb_t report_codec,
- void *user_data) {
-
- this->report_codec_cb = report_codec;
- this->report_codec_user_data = user_data;
- return 1;
-}
-
-void xine_internal_osd (xine_t *this, char *str, int duration) {
-
- uint32_t seconds;
- char tstr[256];
- int64_t start_time;
-
- this->curtime_needed_for_osd = 0;
- start_time = this->metronom->get_current_time (this->metronom);
-
- if (this->osd_display) {
-
- this->osd_renderer->filled_rect (this->osd, 0, 0, 299, 99, 0);
- this->osd_renderer->render_text (this->osd, 0, 5, str, OSD_TEXT1);
-
- seconds = this->cur_input_time;
-
- sprintf (tstr, "%02d:%02d:%02d",
- seconds / (60 * 60),
- (seconds % (60*60)) / 60,
- seconds % 60);
-
- this->osd_renderer->render_text (this->osd, 45, 5, tstr, OSD_TEXT1);
-
- this->osd_renderer->show (this->osd, start_time);
- this->osd_renderer->hide (this->osd, start_time+duration);
+ if (codec_type == XINE_CODEC_VIDEO) {
+ stream->stream_info[XINE_STREAM_INFO_VIDEO_FOURCC] = fourcc;
+ stream->stream_info[XINE_STREAM_INFO_VIDEO_HANDLED] = handled;
+ } else {
+ stream->stream_info[XINE_STREAM_INFO_AUDIO_FOURCC] = fourcc;
+ stream->stream_info[XINE_STREAM_INFO_AUDIO_HANDLED] = handled;
}
}
-static void update_osd_display(void *this_gen, xine_cfg_entry_t *entry)
-{
- xine_t *this = (xine_t *) this_gen;
-
- this->osd_display = entry->num_value;
-}
-
-static void xine_set_speed_internal (xine_t *this, int speed) {
+static void xine_set_speed_internal (xine_stream_t *stream, int speed) {
- this->metronom->set_speed (this->metronom, speed);
+ stream->metronom->set_speed (stream->metronom, speed);
/* see coment on audio_out loop about audio_paused */
- if( this->audio_out ) {
- this->audio_out->audio_paused = (speed != XINE_SPEED_NORMAL) +
- (speed == XINE_SPEED_PAUSE);
+ if( stream->audio_out ) {
+ stream->audio_out->audio_paused = (speed != XINE_SPEED_NORMAL) +
+ (speed == XINE_SPEED_PAUSE);
/*
* slow motion / fast forward does not play sound, drop buffered
* samples from the sound driver
*/
if (speed != XINE_SPEED_NORMAL && speed != XINE_SPEED_PAUSE)
- this->audio_out->control(this->audio_out, AO_CTRL_FLUSH_BUFFERS);
+ stream->audio_out->control(stream->audio_out, AO_CTRL_FLUSH_BUFFERS);
- this->audio_out->control(this->audio_out,
- speed == XINE_SPEED_PAUSE ? AO_CTRL_PLAY_PAUSE : AO_CTRL_PLAY_RESUME);
+ stream->audio_out->control(stream->audio_out,
+ speed == XINE_SPEED_PAUSE ? AO_CTRL_PLAY_PAUSE : AO_CTRL_PLAY_RESUME);
}
-
- this->speed = speed;
+
+ stream->speed = speed;
}
-void xine_stop_internal (xine_t *this) {
+static void xine_stop_internal (xine_stream_t *stream) {
+
+ int finished_count_audio = 0;
+ int finished_count_video = 0;
- printf ("xine_stop. status before = %d\n", this->status);
+ printf ("xine: xine_stop. status before = %d\n", stream->status);
- if (this->status == XINE_STATUS_STOP) {
- printf ("xine_stop ignored\n");
+ if (stream->status == XINE_STATUS_STOP) {
+ printf ("xine: xine_stop ignored\n");
return;
}
/* make sure we're not in "paused" state */
- xine_set_speed_internal(this, XINE_SPEED_NORMAL);
+ xine_set_speed_internal (stream, XINE_SPEED_NORMAL);
/* Don't change status if we're quitting */
- if(this->status != XINE_STATUS_QUIT)
- this->status = XINE_STATUS_STOP;
+ if (stream->status != XINE_STATUS_QUIT)
+ stream->status = XINE_STATUS_STOP;
- printf ("xine_stop: stopping demuxer\n");
- if(this->cur_demuxer_plugin) {
- this->cur_demuxer_plugin->stop (this->cur_demuxer_plugin);
- this->cur_demuxer_plugin = NULL;
+ /*
+ * stop demux
+ */
+
+ pthread_mutex_lock (&stream->counter_lock);
+ if (stream->audio_fifo)
+ finished_count_audio = stream->finished_count_audio + 1;
+ else
+ finished_count_audio = 0;
+
+ finished_count_video = stream->finished_count_video + 1;
+ pthread_mutex_unlock (&stream->counter_lock);
+
+ printf ("xine_stop: stopping demux\n");
+ if (stream->demux_plugin) {
+ stream->demux_plugin->dispose (stream->demux_plugin);
+ stream->demux_plugin = NULL;
+
+ /*
+ * wait until engine has really stopped
+ */
+
+ pthread_mutex_lock (&stream->counter_lock);
+ while ((stream->finished_count_audio<finished_count_audio) ||
+ (stream->finished_count_video<finished_count_video)) {
+ printf ("xine: waiting for finisheds.\n");
+ pthread_cond_wait (&stream->counter_changed, &stream->counter_lock);
+ }
+ pthread_mutex_unlock (&stream->counter_lock);
}
- printf ("xine_stop: stopped demuxer\n");
+ printf ("xine_stop: demux stopped\n");
- if(this->cur_input_plugin) {
- this->cur_input_plugin->close(this->cur_input_plugin);
- if (strcmp(this->cur_mrl, this->logo_mrl) != 0)
- /* remember the last input plugin for a possible eject */
- this->last_input_plugin = this->cur_input_plugin;
+ /*
+ * close input plugin
+ */
+
+ if (stream->input_plugin) {
+ stream->input_plugin->dispose(stream->input_plugin);
+ stream->input_plugin = NULL;
}
/* remove buffered samples from the sound device driver */
- if (this->audio_out)
- this->audio_out->control(this->audio_out, AO_CTRL_FLUSH_BUFFERS);
+ if (stream->audio_out)
+ stream->audio_out->control (stream->audio_out, AO_CTRL_FLUSH_BUFFERS);
printf ("xine_stop: done\n");
}
-void xine_stop (xine_t *this) {
- pthread_mutex_lock (&this->xine_lock);
- xine_stop_internal(this);
+void xine_stop (xine_stream_t *stream) {
+
+ pthread_mutex_lock (&stream->frontend_lock);
+
+ xine_stop_internal (stream);
/*
- this will make output threads discard about everything
- am i abusing of xine architeture? :)
- */
- this->metronom->adjust_clock(this->metronom,
- this->metronom->get_current_time(this->metronom) + 30 * 90000 );
+ * stream will make output threads discard about everything
+ * am i abusing of xine architeture? :)
+ */
+ stream->metronom->adjust_clock (stream->metronom,
+ stream->metronom->get_current_time(stream->metronom) + 30 * 90000 );
- if(this->status == XINE_STATUS_STOP) {
- play_logo_internal(this);
- }
-
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
}
+xine_stream_t *xine_stream_new (xine_t *this,
+ xine_ao_driver_t *ao, xine_vo_driver_t *vo) {
-/*
- * demuxer probing
- */
-static int probe_demux (xine_t *this, int stage1, int stage2) {
-
- int i;
- int stages[3];
+ xine_stream_t *stream;
+ int i;
- stages[0] = stage1;
- stages[1] = stage2;
- stages[2] = -1;
+ printf ("xine: xine_stream_new\n");
- if (stages[0] == -1) {
- printf ("xine: probe_demux stage1 = %d is not allowed \n", stage1);
- return 0;
- }
+ /*
+ * create a new stream object
+ */
- i = 0;
- while (stages[i] != -1) {
+ pthread_mutex_lock (&this->streams_lock);
- plugin_node_t *node;
+ stream = (xine_stream_t *) xine_xmalloc (sizeof (xine_stream_t)) ;
- node = xine_list_first_content (this->plugin_catalog->demux);
+ stream->xine = this;
+ stream->status = XINE_STATUS_STOP;
+ for (i=0; i<XINE_STREAM_INFO_MAX; i++) {
+ stream->stream_info[i] = 0;
+ stream->meta_info[i] = NULL;
+ }
+ stream->speed = XINE_SPEED_NORMAL;
+ stream->input_pos = 0;
+ stream->input_length = 0;
+ stream->input_time = 0;
+ stream->spu_out = NULL;
+ stream->spu_decoder_plugin = NULL;
+ stream->audio_channel_user = -1;
+ stream->audio_channel_auto = 0;
+ stream->spu_channel_auto = -1;
+ stream->spu_channel_letterbox = -1;
+ stream->spu_channel_pan_scan = -1;
+ stream->spu_channel_user = -1;
+ stream->spu_channel = -1;
+ stream->video_driver = vo;
+ stream->video_in_discontinuity = 0;
+ stream->video_channel = 0;
+ stream->header_count_audio = 0;
+ stream->header_count_video = 0;
+ stream->finished_count_audio = 0;
+ stream->finished_count_video = 0;
+ stream->err = 0;
- while (node) {
- demux_plugin_t *plugin;
+ /*
+ * init mutexes and conditions
+ */
- plugin = (demux_plugin_t *) node->plugin;
+ pthread_mutex_init (&stream->frontend_lock, NULL);
+ pthread_mutex_init (&stream->event_queues_lock, NULL);
+ pthread_mutex_init (&stream->osd_lock, NULL);
+ pthread_mutex_init (&stream->counter_lock, NULL);
+ pthread_cond_init (&stream->counter_changed, NULL);
- if (plugin->open (plugin,
- this->cur_input_plugin,
- stages[i]) == DEMUX_CAN_HANDLE) {
-
- this->cur_demuxer_plugin = plugin;
+ /*
+ * create a metronom
+ */
- return 1;
- }
- node = xine_list_next_content (this->plugin_catalog->demux);
- }
- i++;
- }
+ stream->metronom = metronom_init ( (ao != NULL), stream);
- return 0;
-}
+ /*
+ * alloc fifos, init and start decoder threads
+ */
-/*
- * try to find a demuxer which handle current mrl.
- */
-static int find_demuxer(xine_t *this) {
+ stream->video_out = vo_new_instance (vo, stream);
+ video_decoder_init (stream);
- this->cur_demuxer_plugin = NULL;
+ if (ao)
+ stream->audio_out = ao_new_instance (ao, stream);
+ audio_decoder_init (stream);
- switch (this->demux_strategy) {
+ /*
+ * osd
+ */
- case DEMUX_DEFAULT_STRATEGY:
- if (probe_demux (this, STAGE_BY_CONTENT, STAGE_BY_EXTENSION))
- return 1;
- break;
+ stream->osd_renderer = osd_renderer_init (stream->video_out->get_overlay_instance (stream->video_out), stream->xine->config );
+
+ /*
+ * register stream
+ */
- case DEMUX_REVERT_STRATEGY:
- if (probe_demux (this, STAGE_BY_EXTENSION, STAGE_BY_CONTENT))
- return 1;
- break;
+ xine_list_append_content (this->streams, stream);
- case DEMUX_CONTENT_STRATEGY:
- if (probe_demux (this, STAGE_BY_CONTENT, -1))
- return 1;
- break;
+ pthread_mutex_unlock (&this->streams_lock);
- case DEMUX_EXTENSION_STRATEGY:
- if (probe_demux (this, STAGE_BY_EXTENSION, -1))
- return 1;
- break;
- }
-
- return 0;
+ return stream;
}
-int xine_open_internal (xine_t *this, const char *mrl) {
-
- printf ("xine: open mrl '%s'\n", mrl);
+static int xine_open_internal (xine_stream_t *stream, const char *mrl) {
- /*
- * is this an 'opt:' mrlstyle ?
- */
- if (xine_config_change_opt(this->config, mrl)) {
- xine_event_t event;
-
- this->status = XINE_STATUS_STOP;
-
- event.type = XINE_EVENT_PLAYBACK_FINISHED;
- pthread_mutex_unlock (&this->xine_lock);
- xine_send_event (this, &event);
- pthread_mutex_lock (&this->xine_lock);
- return 1;
- }
+ int header_count_audio;
+ int header_count_video;
/*
- * stop engine only for different mrl
+ * find an input plugin
*/
- if ((this->status == XINE_STATUS_PLAY && strcmp (mrl, this->cur_mrl))
- || (this->status == XINE_STATUS_LOGO)) {
-
- printf ("xine: stopping engine\n");
+ if (!(stream->input_plugin = find_input_plugin (stream, mrl))) {
+ xine_log (stream->xine, XINE_LOG_MSG,
+ _("xine: cannot find input plugin for this MRL\n"));
- if (this->speed != XINE_SPEED_NORMAL)
- xine_set_speed_internal (this, XINE_SPEED_NORMAL);
+ stream->err = XINE_ERROR_NO_INPUT_PLUGIN;
+ return 0;
+ }
+ stream->input_class = stream->input_plugin->input_class;
+ stream->meta_info[XINE_META_INFO_INPUT_PLUGIN]
+ = strdup (stream->input_class->get_identifier (stream->input_class));
- if(this->cur_demuxer_plugin) {
- this->playing_logo = 0;
- this->cur_demuxer_plugin->stop (this->cur_demuxer_plugin);
- }
-
- if(this->cur_input_plugin) {
- if (strcmp (mrl, this->cur_mrl))
- this->cur_input_plugin->close(this->cur_input_plugin);
- else
- this->cur_input_plugin->stop(this->cur_input_plugin);
- }
+ /*
+ * find a demux plugin
+ */
+ if (!find_demux_plugin (stream, stream->input_plugin)) {
+ xine_log (stream->xine, XINE_LOG_MSG,
+ _("xine: couldn't find demux for >%s<\n"), mrl);
+ stream->input_plugin->dispose (stream->input_plugin);
+ stream->input_plugin = NULL;
+ stream->err = XINE_ERROR_NO_DEMUX_PLUGIN;
/* remove buffered samples from the sound device driver */
- if (this->audio_out)
- this->audio_out->control(this->audio_out, AO_CTRL_FLUSH_BUFFERS);
+ if (stream->audio_out)
+ stream->audio_out->control (stream->audio_out, AO_CTRL_FLUSH_BUFFERS);
- this->status = XINE_STATUS_STOP;
+ stream->status = XINE_STATUS_STOP;
+ return 0;
}
- if (this->status == XINE_STATUS_STOP) {
-
- plugin_node_t *node;
- int i, header_count;
-
- /*
- * (1/3) reset metainfo
- */
-
- for (i=0; i<XINE_STREAM_INFO_MAX; i++) {
- this->stream_info[i] = 0;
- if (this->meta_info[i]) {
- free (this->meta_info[i]);
- this->meta_info[i] = NULL;
- }
- }
+ stream->meta_info[XINE_META_INFO_SYSTEMLAYER]
+ = strdup (stream->demux_plugin->demux_class->get_identifier());
- /*
- * (2/3) start engine for new mrl'
- */
+ /*
+ * start metronom clock
+ */
- printf ("xine: starting engine for new mrl\n");
+ stream->metronom->start_clock (stream->metronom, 0);
- /*
- * find input plugin
- */
- this->cur_input_plugin = NULL;
- node = xine_list_first_content (this->plugin_catalog->input);
- while (node) {
- input_plugin_t *plugin;
-
- plugin = (input_plugin_t *) node->plugin;
-
- if (plugin->open (plugin, mrl)) {
- this->cur_input_plugin = plugin;
- break;
- }
- node = xine_list_next_content (this->plugin_catalog->input);
- }
+ /*
+ * send and decode headers
+ */
- if (!this->cur_input_plugin) {
- xine_log (this, XINE_LOG_MSG,
- _("xine: cannot find input plugin for this MRL\n"));
- this->cur_demuxer_plugin = NULL;
- this->err = XINE_ERROR_NO_INPUT_PLUGIN;
+ pthread_mutex_lock (&stream->counter_lock);
+ if (stream->audio_fifo)
+ header_count_audio = stream->header_count_audio + 1;
+ else
+ header_count_audio = 0;
- return 0;
- }
+ header_count_video = stream->header_count_video + 1;
+ pthread_mutex_unlock (&stream->counter_lock);
- this->meta_info[XINE_META_INFO_INPUT_PLUGIN]
- = strdup (this->cur_input_plugin->get_identifier(this->cur_input_plugin));
+ stream->demux_plugin->send_headers (stream->demux_plugin);
- /*
- * find demuxer plugin
- */
- header_count = this->header_sent_counter+1;
-
- if (!find_demuxer(this)) {
- xine_log (this, XINE_LOG_MSG,
- _("xine: couldn't find demuxer for >%s<\n"), mrl);
- this->cur_input_plugin->close(this->cur_input_plugin);
- this->err = XINE_ERROR_NO_DEMUXER_PLUGIN;
- return 0;
- }
+ pthread_mutex_lock (&stream->counter_lock);
+ while ((stream->header_count_audio<header_count_audio) ||
+ (stream->header_count_video<header_count_video)) {
+ printf ("xine: waiting for headers.\n");
+ pthread_cond_wait (&stream->counter_changed, &stream->counter_lock);
+ }
+ pthread_mutex_unlock (&stream->counter_lock);
- this->meta_info[XINE_META_INFO_SYSTEMLAYER]
- = strdup (this->cur_demuxer_plugin->get_identifier());
+ return 1;
+}
- /* FIXME: ?? limited length ??? */
- strncpy (this->cur_mrl, mrl, 1024);
+int xine_open (xine_stream_t *stream, const char *mrl) {
- printf ("xine: engine start successful - waiting for headers to be sent\n");
+ int ret;
- /*
- * (3/3) wait for headers to be sent and decoded
- */
+ pthread_mutex_lock (&stream->frontend_lock);
- while (header_count>this->header_sent_counter) {
- printf ("xine: waiting for headers.\n");
- xine_usec_sleep (20000);
- }
+ printf ("xine: xine_open %s\n", mrl);
- printf ("xine: xine_open done.\n");
+ ret = xine_open_internal (stream, mrl);
- return 1;
- }
+ pthread_mutex_unlock (&stream->frontend_lock);
- printf ("xine: xine_open ignored (same mrl, already playing)\n");
- return 0;
+ return ret;
}
-int xine_play_internal (xine_t *this, int start_pos, int start_time) {
+
+static int xine_play_internal (xine_stream_t *stream, int start_pos, int start_time) {
double share ;
off_t pos, len;
int demux_status;
- printf ("xine: xine_play_internal\n");
+ printf ("xine: xine_play\n");
- if (this->speed != XINE_SPEED_NORMAL)
- xine_set_speed_internal (this, XINE_SPEED_NORMAL);
+ if (stream->speed != XINE_SPEED_NORMAL)
+ xine_set_speed_internal (stream, XINE_SPEED_NORMAL);
/*
- * start/seek demuxer
+ * start/seek demux
*/
if (start_pos) {
/* FIXME: do we need to protect concurrent access to input plugin here? */
- len = this->cur_input_plugin->get_length (this->cur_input_plugin);
+ len = stream->input_plugin->get_length (stream->input_plugin);
share = (double) start_pos / 65535;
pos = (off_t) (share * len) ;
} else
pos = 0;
- if (this->status == XINE_STATUS_STOP) {
+ if (stream->status == XINE_STATUS_STOP) {
- demux_status = this->cur_demuxer_plugin->start (this->cur_demuxer_plugin,
+ demux_status = stream->demux_plugin->start (stream->demux_plugin,
pos, start_time);
} else {
- demux_status = this->cur_demuxer_plugin->seek (this->cur_demuxer_plugin,
+ demux_status = stream->demux_plugin->seek (stream->demux_plugin,
pos, start_time);
}
if (demux_status != DEMUX_OK) {
- xine_log (this, XINE_LOG_MSG,
- _("xine_play: demuxer failed to start\n"));
+ xine_log (stream->xine, XINE_LOG_MSG,
+ _("xine_play: demux failed to start\n"));
- this->err = XINE_ERROR_DEMUXER_FAILED;
+ stream->err = XINE_ERROR_DEMUX_FAILED;
- if( this->status == XINE_STATUS_STOP )
- this->cur_input_plugin->close(this->cur_input_plugin);
+ if (stream->status == XINE_STATUS_STOP)
+ stream->input_plugin->dispose(stream->input_plugin);
+ pthread_mutex_unlock (&stream->frontend_lock);
return 0;
} else {
-
- this->status = XINE_STATUS_PLAY;
-
- /* osd will be updated as soon as we know cur_input_time */
- if( !this->playing_logo )
- this->curtime_needed_for_osd = 5;
+ stream->status = XINE_STATUS_PLAY;
}
printf ("xine: xine_play_internal ...done\n");
@@ -565,102 +420,88 @@ int xine_play_internal (xine_t *this, int start_pos, int start_time) {
return 1;
}
-int xine_open (xine_t *this, const char *mrl) {
+int xine_play (xine_stream_t *stream, int start_pos, int start_time) {
+
int ret;
- pthread_mutex_lock (&this->xine_lock);
- ret = xine_open_internal (this, mrl);
- pthread_mutex_unlock (&this->xine_lock);
-
- return ret;
-}
+ pthread_mutex_lock (&stream->frontend_lock);
-int xine_play (xine_t *this, int start_pos, int start_time) {
- int ret;
+ ret = xine_play_internal (stream, start_pos, start_time);
- pthread_mutex_lock (&this->xine_lock);
- ret = xine_play_internal (this, start_pos, start_time);
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
return ret;
}
-
-int xine_eject (xine_t *this) {
+int xine_eject (xine_stream_t *stream) {
int status;
- if(this->last_input_plugin == NULL)
+ if (!stream->input_class)
return 0;
- pthread_mutex_lock (&this->xine_lock);
+ pthread_mutex_lock (&stream->frontend_lock);
status = 0;
- if (((this->status == XINE_STATUS_STOP) || (this->status == XINE_STATUS_LOGO))
- && this->last_input_plugin && this->last_input_plugin->eject_media) {
+ if ((stream->status == XINE_STATUS_STOP)
+ && stream->input_class && stream->input_class->eject_media) {
- status = this->last_input_plugin->eject_media (this->last_input_plugin);
+ status = stream->input_class->eject_media (stream->input_class);
}
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
return status;
}
-void xine_exit (xine_t *this) {
+void xine_dispose (xine_stream_t *stream) {
- int i;
+ printf ("xine: xine_dispose\n");
- /* skip some cleanup steps, when xine_init wasn't run */
- if (this->video_driver && this->metronom) {
+ stream->status = XINE_STATUS_QUIT;
- /* cleanup things from xine_init... */
- this->status = XINE_STATUS_QUIT;
+ xine_stop(stream);
- xine_stop(this);
+ printf ("xine_exit: shutdown audio\n");
- pthread_mutex_lock (&this->finished_lock);
+ audio_decoder_shutdown (stream);
- if (this->finished_thread_running)
- pthread_join (this->finished_thread, NULL);
+ printf ("xine_exit: shutdown video\n");
- pthread_mutex_unlock (&this->finished_lock);
+ video_decoder_shutdown (stream);
- printf ("xine_exit: shutdown audio\n");
+ stream->osd_renderer->close( stream->osd_renderer );
+ stream->video_out->exit (stream->video_out);
+ stream->video_fifo->dispose (stream->video_fifo);
- audio_decoder_shutdown (this);
+ pthread_mutex_destroy (&stream->frontend_lock);
+ pthread_mutex_destroy (&stream->counter_lock);
+ pthread_mutex_destroy (&stream->osd_lock);
+ pthread_mutex_destroy (&stream->event_queues_lock);
+ pthread_cond_destroy (&stream->counter_changed);
- printf ("xine_exit: shutdown video\n");
+ free (stream);
+}
- video_decoder_shutdown (this);
+void xine_exit (xine_t *this) {
- this->osd_renderer->close( this->osd_renderer );
- this->video_out->exit (this->video_out);
- this->video_fifo->dispose (this->video_fifo);
+ /* FIXME */
- this->metronom->exit (this->metronom);
+ printf ("xine_exit: bye!\n");
- printf ("xine_exit: bye!\n");
- }
+#if 0
- /* cleanup things from xine_new... */
- this->status = XINE_STATUS_QUIT;
+ int i;
for (i = 0; i < XINE_LOG_NUM; i++)
- this->log_buffers[i]->dispose (this->log_buffers[i]);
-
- dispose_plugins (this);
- xine_profiler_print_results ();
- this->config->dispose(this->config);
+ stream->log_buffers[i]->dispose (stream->log_buffers[i]);
- pthread_mutex_destroy (&this->logo_lock);
- pthread_mutex_destroy (&this->xine_lock);
- pthread_mutex_destroy (&this->finished_lock);
- pthread_mutex_destroy (&this->osd_lock);
- pthread_mutex_destroy (&this->event_lock);
- pthread_cond_destroy (&this->event_handled);
+ stream->metronom->exit (stream->metronom);
- free (this);
+ dispose_plugins (stream);
+ xine_profiler_print_results ();
+ stream->config->dispose(stream->config);
+#endif
}
xine_t *xine_new (void) {
@@ -684,22 +525,6 @@ xine_t *xine_new (void) {
#endif
/*
- * init locks
- */
-
- pthread_mutex_init (&this->xine_lock, NULL);
-
- pthread_mutex_init (&this->finished_lock, NULL);
-
- pthread_mutex_init (&this->osd_lock, NULL);
-
- pthread_mutex_init (&this->event_lock, NULL);
-
- pthread_cond_init (&this->event_handled, NULL);
-
- this->finished_thread_running = 0;
-
- /*
* config
*/
@@ -711,33 +536,12 @@ xine_t *xine_new (void) {
for (i = 0; i < XINE_LOG_NUM; i++)
this->log_buffers[i] = new_scratch_buffer (25);
-
- /*
- * defaults
- */
- this->err = XINE_ERROR_NONE;
- this->spu_channel_auto = -1;
- this->spu_channel_letterbox = -1;
- this->spu_channel_pan_scan = -1;
- this->spu_channel_user = -1;
- this->cur_input_pos = 0;
- this->cur_input_length = 0;
- this->last_input_plugin = NULL;
- this->num_event_listeners = 0; /* initially there are none */
- this->cur_input_plugin = NULL;
- this->cur_spu_decoder_plugin = NULL;
- this->report_codec_cb = NULL;
- this->header_sent_counter = 0;
-
- /*
- * meta info
+ /*
+ * streams_lock
*/
- for (i=0; i<XINE_STREAM_INFO_MAX; i++) {
- this->stream_info[i] = 0;
- this->meta_info [i] = NULL;
- }
+ pthread_mutex_init (&this->streams_lock, NULL);
/*
* plugins
@@ -745,48 +549,21 @@ xine_t *xine_new (void) {
scan_plugins(this);
- /*
- * logo
- */
-
- pthread_mutex_init (&this->logo_lock, NULL);
-
- pthread_mutex_lock (&this->logo_lock);
- this->logo_mrl = this->config->register_string(this->config,
- "misc.logo_mrl",
- XINE_LOGO_FILE,
- _("logo mrl, displayed in video output window"),
- NULL, 0, _logo_change_cb,
- (void *) this);
- pthread_mutex_unlock (&this->logo_lock);
-
return this;
-
}
-void xine_init (xine_t *this,
- xine_ao_driver_t *ao,
- xine_vo_driver_t *vo) {
+void xine_init (xine_t *this) {
static char *demux_strategies[] = {"default", "reverse", "content",
"extension", NULL};
- this->video_driver = vo;
-
/* initialize color conversion tables and functions */
init_yuv_conversion();
-
- /*
- * create a metronom
- */
-
- this->metronom = metronom_init ( (ao != NULL), this);
-
/* probe for optimized memcpy or config setting */
xine_probe_fast_memcpy (this->config);
-
+
/*
* content detection strategy
*/
@@ -797,216 +574,121 @@ void xine_init (xine_t *this,
demux_strategies,
"media format detection strategy",
NULL, 10, NULL, NULL);
-
/*
- * init and start decoder threads
+ * keep track of all opened streams
*/
- this->video_out = vo_new_instance (vo, this);
- video_decoder_init (this);
-
- this->osd_renderer = osd_renderer_init (this->video_out->get_overlay_instance (this->video_out), this->config );
-
- this->osd = this->osd_renderer->new_object (this->osd_renderer, 300, 100);
- this->osd_renderer->set_font (this->osd, "cetus", 24);
- this->osd_renderer->set_text_palette (this->osd, TEXTPALETTE_WHITE_BLACK_TRANSPARENT, OSD_TEXT1 );
- this->osd_renderer->set_position (this->osd, 10,10);
-
- this->osd_display = this->config->register_bool (this->config,
- "misc.osd_display", 1,
- "Show status on play, pause, ff, ...",
- NULL, 0,
- update_osd_display, this );
-
- if (ao)
- this->audio_out = ao_new_instance (ao, this);
-
- audio_decoder_init (this);
-
- /*
- * start metronom clock (needed for osd)
- */
-
- this->metronom->start_clock (this->metronom, 0);
-
- if (this->osd_display) {
-
- char tstr[30];
-
- this->osd_renderer->filled_rect (this->osd, 0, 0, 299, 99, 0);
- sprintf (tstr, "xine-lib v%01d.%01d.%01d", XINE_MAJOR, XINE_MINOR, XINE_SUB);
-
- this->osd_renderer->render_text (this->osd, 5, 5, tstr, OSD_TEXT1);
-
- this->osd_renderer->show (this->osd, 0);
- this->osd_renderer->hide (this->osd, 300000);
- }
-
- this->status = XINE_STATUS_STOP;
+ this->streams = xine_list_new();
+ pthread_mutex_init (&this->streams_lock, NULL);
- play_logo_internal(this);
}
-void xine_select_spu_channel (xine_t *this, int channel) {
+void xine_select_spu_channel (xine_stream_t *stream, int channel) {
- pthread_mutex_lock (&this->xine_lock);
+ pthread_mutex_lock (&stream->frontend_lock);
- this->spu_channel_user = (channel >= -2 ? channel : -2);
+ stream->spu_channel_user = (channel >= -2 ? channel : -2);
- switch (this->spu_channel_user) {
+ switch (stream->spu_channel_user) {
case -2:
- this->spu_channel = -1;
- this->video_out->enable_ovl (this->video_out, 0);
+ stream->spu_channel = -1;
+ stream->video_out->enable_ovl (stream->video_out, 0);
break;
case -1:
- this->spu_channel = this->spu_channel_auto;
- this->video_out->enable_ovl (this->video_out, 1);
+ stream->spu_channel = stream->spu_channel_auto;
+ stream->video_out->enable_ovl (stream->video_out, 1);
break;
default:
- this->spu_channel = this->spu_channel_user;
- this->video_out->enable_ovl (this->video_out, 1);
+ stream->spu_channel = stream->spu_channel_user;
+ stream->video_out->enable_ovl (stream->video_out, 1);
}
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
}
-static int xine_get_current_position (xine_t *this) {
+static int xine_get_current_position (xine_stream_t *stream) {
off_t len;
double share;
- pthread_mutex_lock (&this->xine_lock);
+ pthread_mutex_lock (&stream->frontend_lock);
- if (!this->cur_input_plugin) {
+ if (!stream->input_plugin) {
printf ("xine: xine_get_current_position: no input source\n");
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
return 0;
}
- /* pos = this->mCurInput->seek (0, SEEK_CUR); */
- len = this->cur_input_length;
- if (len == 0) len = this->cur_input_plugin->get_length (this->cur_input_plugin);
- share = (double) this->cur_input_pos / (double) len * 65535;
+ /* pos = stream->mCurInput->seek (0, SEEK_CUR); */
+ len = stream->input_length;
+ if (len == 0) len = stream->input_plugin->get_length (stream->input_plugin);
+ share = (double) stream->input_pos / (double) len * 65535;
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
return (int) share;
}
-int xine_get_status(xine_t *this) {
- int status;
-
- status = this->status;
- if( status == XINE_STATUS_LOGO )
- status = XINE_STATUS_STOP;
- return status;
+int xine_get_status (xine_stream_t *stream) {
+ return stream->status;
}
/*
* trick play
*/
-void xine_set_speed (xine_t *this, int speed) {
+void xine_set_speed (xine_stream_t *stream, int speed) {
- pthread_mutex_lock (&this->xine_lock);
+ pthread_mutex_lock (&stream->frontend_lock);
if (speed <= XINE_SPEED_PAUSE)
speed = XINE_SPEED_PAUSE;
else if (speed > XINE_SPEED_FAST_4)
speed = XINE_SPEED_FAST_4;
- /* osd */
-
- pthread_mutex_lock (&this->osd_lock);
- switch (speed) {
- case XINE_SPEED_PAUSE:
- xine_internal_osd (this, "<", 90000);
- break;
- case XINE_SPEED_SLOW_4:
- xine_internal_osd (this, "<>", 20000 * speed);
- break;
- case XINE_SPEED_SLOW_2:
- xine_internal_osd (this, "@>", 20000 * speed);
- break;
- case XINE_SPEED_NORMAL:
- xine_internal_osd (this, ">", 20000 * speed);
- break;
- case XINE_SPEED_FAST_2:
- xine_internal_osd (this, "$$", 20000 * speed);
- break;
- case XINE_SPEED_FAST_4:
- xine_internal_osd (this, "$$$", 20000 * speed);
- break;
- }
- pthread_mutex_unlock (&this->osd_lock);
-
printf ("xine: set_speed %d\n", speed);
- xine_set_speed_internal (this, speed);
+ xine_set_speed_internal (stream, speed);
- pthread_mutex_unlock (&this->xine_lock);
+ pthread_mutex_unlock (&stream->frontend_lock);
}
-int xine_get_speed (xine_t *this) {
- return this->speed;
+int xine_get_speed (xine_stream_t *stream) {
+ return stream->speed;
}
/*
* time measurement / seek
*/
-static int xine_get_stream_length (xine_t *this) {
+static int xine_get_stream_length (xine_stream_t *stream) {
- if(this->cur_demuxer_plugin)
- return this->cur_demuxer_plugin->get_stream_length (this->cur_demuxer_plugin);
+ if (stream->demux_plugin)
+ return stream->demux_plugin->get_stream_length (stream->demux_plugin);
return 0;
}
-int xine_get_pos_length (xine_t *this, int *pos_stream,
+int xine_get_pos_length (xine_stream_t *stream, int *pos_stream,
int *pos_time, int *length_time) {
if (pos_stream)
- *pos_stream = xine_get_current_position (this);
+ *pos_stream = xine_get_current_position (stream);
if (pos_time)
- *pos_time = this->cur_input_time * 1000;
+ *pos_time = stream->input_time * 1000;
if (length_time)
- *length_time = xine_get_stream_length (this) * 1000;
+ *length_time = xine_get_stream_length (stream) * 1000;
return 1;
}
-static int xine_get_audio_capabilities(xine_t *this) {
-
- if(this->audio_out)
- return (this->audio_out->get_capabilities(this->audio_out));
-
- return AO_CAP_NOCAP;
-}
-
-static int xine_get_audio_property(xine_t *this, int property) {
-
- if(this->audio_out)
- return(this->audio_out->get_property(this->audio_out, property));
-
- return 0;
-}
-
-static int xine_set_audio_property(xine_t *this, int property, int value) {
-
- if(this->audio_out)
- return(this->audio_out->set_property(this->audio_out, property, value));
-
- return ~value;
-}
-
-int xine_get_current_frame (xine_t *this, int *width, int *height,
+int xine_get_current_frame (xine_stream_t *stream, int *width, int *height,
int *ratio_code, int *format,
uint8_t *img) {
vo_frame_t *frame;
- frame = this->video_out->get_last_frame (this->video_out);
+ frame = stream->video_out->get_last_frame (stream->video_out);
if (!frame)
return 0;
@@ -1041,42 +723,39 @@ int xine_get_current_frame (xine_t *this, int *width, int *height,
return 1;
}
-const char * xine_get_spu_lang (xine_t *this, int channel) {
+int xine_get_spu_lang (xine_stream_t *stream, int channel, char *lang) {
- if (this->cur_input_plugin) {
- if (this->cur_input_plugin->get_capabilities (this->cur_input_plugin) & INPUT_CAP_SPULANG) {
- this->cur_input_plugin->get_optional_data (this->cur_input_plugin,
- this->spu_lang,
- INPUT_OPTIONAL_DATA_SPULANG);
- return this->spu_lang;
+ if (stream->input_plugin) {
+ if (stream->input_plugin->get_capabilities (stream->input_plugin) & INPUT_CAP_SPULANG) {
+ stream->input_plugin->get_optional_data (stream->input_plugin, lang,
+ INPUT_OPTIONAL_DATA_SPULANG);
+ return 1;
}
}
- return NULL;
+ return 0;
}
-const char* xine_get_audio_lang (xine_t *this, int channel) {
+int xine_get_audio_lang (xine_stream_t *stream, int channel, char *lang) {
- if (this->cur_input_plugin) {
- if (this->cur_input_plugin->get_capabilities (this->cur_input_plugin) & INPUT_CAP_AUDIOLANG) {
- this->cur_input_plugin->get_optional_data (this->cur_input_plugin,
- this->audio_lang,
- INPUT_OPTIONAL_DATA_AUDIOLANG);
- return this->audio_lang;
+ if (stream->input_plugin) {
+ if (stream->input_plugin->get_capabilities (stream->input_plugin) & INPUT_CAP_AUDIOLANG) {
+ stream->input_plugin->get_optional_data (stream->input_plugin, lang,
+ INPUT_OPTIONAL_DATA_AUDIOLANG);
+ return 1;
}
}
- return NULL;
+ return 0;
}
-int xine_get_spu_channel (xine_t *this) {
-
- return this->spu_channel_user;
+int xine_get_spu_channel (xine_stream_t *stream) {
+ return stream->spu_channel_user;
}
-osd_renderer_t *xine_get_osd_renderer (xine_t *this) {
+osd_renderer_t *xine_get_osd_renderer (xine_stream_t *stream) {
- return this->osd_renderer;
+ return stream->osd_renderer;
}
/*
@@ -1127,11 +806,11 @@ void xine_register_log_cb (xine_t *this, xine_log_cb_t cb, void *user_data) {
}
-int xine_get_error (xine_t *this) {
- return this->err;
+int xine_get_error (xine_stream_t *stream) {
+ return stream->err;
}
-int xine_trick_mode (xine_t *this, int mode, int value) {
+int xine_trick_mode (xine_stream_t *stream, int mode, int value) {
printf ("xine: xine_trick_mode not implemented yet.\n");
abort ();
}
diff --git a/src/xine-engine/xine_interface.c b/src/xine-engine/xine_interface.c
index 541fe3f0a..677a16c67 100644
--- a/src/xine-engine/xine_interface.c
+++ b/src/xine-engine/xine_interface.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_interface.c,v 1.22 2002/09/22 14:29:40 mroi Exp $
+ * $Id: xine_interface.c,v 1.23 2002/10/14 15:47:44 guenter Exp $
*
* convenience/abstraction layer, functions to implement
* libxine's public interface
@@ -304,41 +304,42 @@ void xine_config_reset (xine_t *this) {
pthread_mutex_unlock(&config->config_lock);
}
-int xine_gui_send_vo_data (xine_t *this,
+int xine_gui_send_vo_data (xine_stream_t *stream,
int type, void *data) {
- return this->video_driver->gui_data_exchange (this->video_driver, type, data);
+ return stream->video_driver->gui_data_exchange (stream->video_driver,
+ type, data);
}
-void xine_set_param (xine_t *this, int param, int value) {
+void xine_set_param (xine_stream_t *stream, int param, int value) {
switch (param) {
case XINE_PARAM_SPEED:
- xine_set_speed (this, value);
+ xine_set_speed (stream, value);
break;
case XINE_PARAM_AV_OFFSET:
- this->metronom->set_option (this->metronom, METRONOM_AV_OFFSET, value);
+ stream->metronom->set_option (stream->metronom, METRONOM_AV_OFFSET, value);
break;
case XINE_PARAM_AUDIO_CHANNEL_LOGICAL:
- pthread_mutex_lock (&this->xine_lock);
+ pthread_mutex_lock (&stream->frontend_lock);
if (value < -2)
value = -2;
- this->audio_channel_user = value;
- pthread_mutex_unlock (&this->xine_lock);
+ stream->audio_channel_user = value;
+ pthread_mutex_unlock (&stream->frontend_lock);
break;
case XINE_PARAM_SPU_CHANNEL:
- xine_select_spu_channel (this, value);
+ xine_select_spu_channel (stream, value);
break;
case XINE_PARAM_VIDEO_CHANNEL:
- pthread_mutex_lock (&this->xine_lock);
+ pthread_mutex_lock (&stream->frontend_lock);
if (value<0)
value = 0;
- this->video_channel = value;
- pthread_mutex_unlock (&this->xine_lock);
+ stream->video_channel = value;
+ pthread_mutex_unlock (&stream->frontend_lock);
break;
case XINE_PARAM_AUDIO_VOLUME:
@@ -357,7 +358,7 @@ void xine_set_param (xine_t *this, int param, int value) {
case XINE_PARAM_VO_ZOOM_Y:
case XINE_PARAM_VO_PAN_SCAN:
case XINE_PARAM_VO_TVMODE:
- this->video_driver->set_property(this->video_driver, param & 0xffffff, value);
+ stream->video_driver->set_property(stream->video_driver, param & 0xffffff, value);
break;
default:
@@ -365,23 +366,23 @@ void xine_set_param (xine_t *this, int param, int value) {
}
}
-int xine_get_param (xine_t *this, int param) {
+int xine_get_param (xine_stream_t *stream, int param) {
switch (param) {
case XINE_PARAM_SPEED:
- return this->speed;
+ return stream->speed;
case XINE_PARAM_AV_OFFSET:
- return this->metronom->get_option (this->metronom, METRONOM_AV_OFFSET);
+ return stream->metronom->get_option (stream->metronom, METRONOM_AV_OFFSET);
case XINE_PARAM_AUDIO_CHANNEL_LOGICAL:
- return this->audio_channel_user;
+ return stream->audio_channel_user;
case XINE_PARAM_SPU_CHANNEL:
- return this->spu_channel_user;
+ return stream->spu_channel_user;
case XINE_PARAM_VIDEO_CHANNEL:
- return this->video_channel;
+ return stream->video_channel;
case XINE_PARAM_AUDIO_VOLUME:
return -1; /* FIXME: implement */
@@ -399,7 +400,7 @@ int xine_get_param (xine_t *this, int param) {
case XINE_PARAM_VO_ZOOM_Y:
case XINE_PARAM_VO_PAN_SCAN:
case XINE_PARAM_VO_TVMODE:
- return this->video_driver->get_property(this->video_driver, param & 0xffffff);
+ return stream->video_driver->get_property(stream->video_driver, param & 0xffffff);
break;
default:
@@ -409,18 +410,18 @@ int xine_get_param (xine_t *this, int param) {
return 0;
}
-uint32_t xine_get_stream_info (xine_t *this, int info) {
+uint32_t xine_get_stream_info (xine_stream_t *stream, int info) {
switch (info) {
case XINE_STREAM_INFO_SEEKABLE:
- if (this->cur_input_plugin)
- return this->cur_input_plugin->get_capabilities (this->cur_input_plugin) & INPUT_CAP_SEEKABLE;
+ if (stream->input_plugin)
+ return stream->input_plugin->get_capabilities (stream->input_plugin) & INPUT_CAP_SEEKABLE;
return 0;
case XINE_STREAM_INFO_HAS_CHAPTERS:
- if (this->cur_input_plugin)
- return this->cur_input_plugin->get_capabilities (this->cur_input_plugin) & INPUT_CAP_CHAPTERS;
+ if (stream->input_plugin)
+ return stream->input_plugin->get_capabilities (stream->input_plugin) & INPUT_CAP_CHAPTERS;
return 0;
case XINE_STREAM_INFO_BITRATE:
@@ -435,7 +436,7 @@ uint32_t xine_get_stream_info (xine_t *this, int info) {
case XINE_STREAM_INFO_AUDIO_BITS:
case XINE_STREAM_INFO_AUDIO_SAMPLERATE:
case XINE_STREAM_INFO_AUDIO_BITRATE:
- return this->stream_info[info];
+ return stream->stream_info[info];
default:
printf ("xine_interface: error, unknown stream info (%d) requested\n",
@@ -444,8 +445,8 @@ uint32_t xine_get_stream_info (xine_t *this, int info) {
return 0;
}
-const char *xine_get_meta_info (xine_t *this, int info) {
+const char *xine_get_meta_info (xine_stream_t *stream, int info) {
- return this->meta_info[info];
+ return stream->meta_info[info];
}
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index a00095ee4..a07916a9e 100644
--- a/src/xine-engine/xine_internal.h
+++ b/src/xine-engine/xine_internal.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_internal.h,v 1.103 2002/09/20 22:34:26 f1rmb Exp $
+ * $Id: xine_internal.h,v 1.104 2002/10/14 15:47:45 guenter Exp $
*
*/
@@ -66,245 +66,183 @@ extern "C" {
#include "scratch.h"
#include "xineintl.h"
#include "plugin_catalog.h"
+#include "video_decoder.h"
+#include "audio_decoder.h"
-#define VIDEO_DECODER_IFACE_VERSION 10
-#define AUDIO_DECODER_IFACE_VERSION 9
#define XINE_MAX_EVENT_LISTENERS 50
#define XINE_MAX_EVENT_TYPES 100
+#define XINE_CODEC_AUDIO 0
+#define XINE_CODEC_VIDEO 1
+
/* used by plugin loader */
#define XINE_VERSION_CODE XINE_MAJOR_VERSION*10000+XINE_MINOR_VERSION*100+XINE_SUB_VERSION
/*
- * generic xine video decoder plugin interface
- *
- * for a dynamic plugin make sure you provide this function call:
- * video_decoder_t *init_video_decoder_plugin (int iface_version,
- * xine_t *xine);
+ * log constants
*/
-typedef struct video_decoder_s video_decoder_t;
-
-struct video_decoder_s {
-
- void (*init) (video_decoder_t *this, vo_instance_t *video_out);
-
- void (*decode_data) (video_decoder_t *this, buf_element_t *buf);
-
- void (*reset) (video_decoder_t *this);
-
- void (*flush) (video_decoder_t *this);
-
- void (*close) (video_decoder_t *this);
-
- char* (*get_identifier) (void);
-
- void (*dispose) (video_decoder_t *this);
+#define XINE_LOG_MSG 0 /* warnings, errors, ... */
+#define XINE_LOG_PLUGIN 1
+#define XINE_LOG_NUM 2 /* # of log buffers defined */
-};
+#define XINE_STREAM_INFO_MAX 99
/*
- * generic xine audio decoder plugin interface
- *
- * for a dynamic plugin make sure you provide this function call:
- * audio_decoder_t *init_audio_decoder_plugin (int iface_version,
- * xine_t *xine);
+ * the "big" xine struct, holding everything together
*/
-typedef struct audio_decoder_s audio_decoder_t;
-
-struct audio_decoder_s {
-
- void (*init) (audio_decoder_t *this, ao_instance_t *audio_out);
-
- void (*decode_data) (audio_decoder_t *this, buf_element_t *buf);
-
- void (*reset) (audio_decoder_t *this);
+struct xine_s {
- void (*close) (audio_decoder_t *this);
+ config_values_t *config;
- char* (*get_identifier) (void);
+ plugin_catalog_t *plugin_catalog;
+
+ int demux_strategy;
- void (*dispose) (audio_decoder_t *this);
+ /* log output that may be presented to the user */
+ scratch_buffer_t *log_buffers[XINE_LOG_NUM];
+ xine_list_t *streams;
+ pthread_mutex_t streams_lock;
};
/*
- * log constants
+ * xine event queue
*/
-#define XINE_LOG_MSG 0 /* warnings, errors, ... */
-#define XINE_LOG_PLUGIN 1
-#define XINE_LOG_NUM 2 /* # of log buffers defined */
-
-#define XINE_STREAM_INFO_MAX 99
+struct xine_event_queue_s {
+ xine_list_t *events;
+ pthread_mutex_t lock;
+ pthread_cond_t new_event;
+ xine_stream_t *stream;
+ pthread_t *listener_thread;
+ xine_event_listener_cb_t callback;
+ void *user_data;
+};
/*
- * the big xine struct, holding everything together
+ * xine_stream - per-stream parts of the xine engine
*/
-struct xine_s {
-
- /* private : */
-
- metronom_t *metronom;
-
- config_values_t *config;
-
- /* MRL of displayed logo */
- char *logo_mrl;
- /* Logo manipulation mutex */
- pthread_mutex_t logo_lock;
-
- plugin_catalog_t *plugin_catalog;
+struct xine_stream_s {
- input_plugin_t *cur_input_plugin;
- /* kept to do proper ejecting (otherwise we eject the logo) */
- input_plugin_t *last_input_plugin;
-
- demux_plugin_t *cur_demuxer_plugin;
- int demux_strategy;
+ xine_t *xine;
int status;
- int speed;
- off_t cur_input_pos;
- off_t cur_input_length;
- int cur_input_time;
- char cur_mrl[1024];
- spu_functions_t *spu_out;
- pthread_t spu_thread;
- spu_decoder_t *cur_spu_decoder_plugin;
- int spu_finished;
+ input_plugin_t *input_plugin;
+ input_class_t *input_class; /* eject */
+ int content_detection_method;
+ demux_plugin_t *demux_plugin;
- /* *_user: -2 => off
- -1 => auto (use *_auto value)
- >=0 => respect the user's choice
- */
-
- int audio_channel_user;
- int audio_channel_auto;
- int spu_channel_user;
- int spu_channel_auto;
- int spu_channel_letterbox;
- int spu_channel_pan_scan;
- int spu_channel;
+ metronom_t *metronom;
+ int speed;
+ off_t input_pos;
+ off_t input_length;
+ int input_time;
xine_vo_driver_t *video_driver;
vo_instance_t *video_out;
fifo_buffer_t *video_fifo;
pthread_t video_thread;
- video_decoder_t *cur_video_decoder_plugin;
- int video_finished;
+ video_decoder_t *video_decoder_plugin;
int video_in_discontinuity;
int video_channel;
- osd_renderer_t *osd_renderer;
- osd_object_t *osd;
- int osd_display;
-
ao_instance_t *audio_out;
fifo_buffer_t *audio_fifo;
lrb_t *audio_temp;
pthread_t audio_thread;
- audio_decoder_t *cur_audio_decoder_plugin;
+ audio_decoder_t *audio_decoder_plugin;
uint32_t audio_track_map[50];
int audio_track_map_entries;
- int audio_finished;
uint32_t audio_type;
+ /* *_user: -2 => off
+ -1 => auto (use *_auto value)
+ >=0 => respect the user's choice
+ */
+ int audio_channel_user;
+ int audio_channel_auto;
- /* Lock for xine player functions */
- pthread_mutex_t xine_lock;
-
- /* Lock for xxx_finished variables */
- pthread_mutex_t finished_lock;
-
- /* Array of event handlers. */
- xine_event_listener_cb_t event_listeners[XINE_MAX_EVENT_LISTENERS];
- void *event_listener_user_data[XINE_MAX_EVENT_LISTENERS];
- uint16_t num_event_listeners;
- uint8_t event_pending[XINE_MAX_EVENT_TYPES];
- pthread_cond_t event_handled;
- pthread_mutex_t event_lock;
-
- /* scratch string buffers */
- char str[1024];
- char spu_lang[80];
- char audio_lang[80];
-
- /* log output that may be presented to the user */
- scratch_buffer_t *log_buffers[XINE_LOG_NUM];
+ spu_functions_t *spu_out;
+ pthread_t spu_thread;
+ spu_decoder_t *spu_decoder_plugin;
+ int spu_channel_user;
+ int spu_channel_auto;
+ int spu_channel_letterbox;
+ int spu_channel_pan_scan;
+ int spu_channel;
- int err;
+ /* lock for public xine player functions */
+ pthread_mutex_t frontend_lock;
- pthread_t finished_thread;
- int finished_thread_running;
-
- xine_report_codec_cb_t report_codec_cb;
- void *report_codec_user_data;
-
- int playing_logo;
- int curtime_needed_for_osd;
pthread_mutex_t osd_lock;
+ osd_renderer_t *osd_renderer;
/* stream meta information */
int stream_info[XINE_STREAM_INFO_MAX];
char *meta_info [XINE_STREAM_INFO_MAX];
- int header_sent_counter; /* wait for headers sent */
-};
+ /* wait for headers sent / stream decoding finished */
+ pthread_mutex_t counter_lock;
+ pthread_cond_t counter_changed;
+ int header_count_audio;
+ int header_count_video;
+ int finished_count_audio;
+ int finished_count_video;
-/*
- * private function prototypes:
- */
+ /* event mechanism */
+ xine_list_t *event_queues;
+ pthread_mutex_t event_queues_lock;
-int xine_open_internal (xine_t *this, const char *mrl);
-int xine_play_internal (xine_t *this,
- int start_pos, int start_time);
-void xine_stop_internal (xine_t *this);
-void xine_notify_stream_finished (xine_t *this);
-void xine_report_codec (xine_t *this, int codec_type,
- uint32_t fourcc, uint32_t buf_type, int handled );
-void xine_internal_osd (xine_t *this, char *str, int duration);
+ int err;
+};
-void video_decoder_init (xine_t *this);
-void video_decoder_shutdown (xine_t *this);
-void audio_decoder_init (xine_t *this);
-void audio_decoder_shutdown (xine_t *this);
-/*
- * demuxer helper functions from demux.c
+/*
+ * private function prototypes:
*/
-void xine_demux_flush_engine (xine_t *this);
+void xine_handle_stream_end (xine_stream_t *stream, int non_user);
-void xine_demux_control_newpts (xine_t *this, int64_t pts, uint32_t flags );
+/* find and instantiate input and demux plugins */
-void xine_demux_control_headers_done (xine_t *this );
+input_plugin_t *find_input_plugin (xine_stream_t *stream, const char *mrl);
+demux_plugin_t *find_demux_plugin (xine_stream_t *stream, input_plugin_t *input);
-void xine_demux_control_start (xine_t *this );
+/* create decoder fifos and threads */
-void xine_demux_control_end (xine_t *this, uint32_t flags );
+void video_decoder_init (xine_stream_t *stream);
+void video_decoder_shutdown (xine_stream_t *stream);
-/*
- * plugin management
- */
+void audio_decoder_init (xine_stream_t *stream);
+void audio_decoder_shutdown (xine_stream_t *stream);
-/*
- * on-demand loading of audio/video/spu decoder plugins
- */
+/* demuxer helper functions from demux.c */
-video_decoder_t *get_video_decoder (xine_t *this, uint8_t stream_type);
-audio_decoder_t *get_audio_decoder (xine_t *this, uint8_t stream_type);
-spu_decoder_t *get_spu_decoder (xine_t *this, uint8_t stream_type);
+void xine_demux_flush_engine (xine_stream_t *stream);
+void xine_demux_control_newpts (xine_stream_t *stream, int64_t pts, uint32_t flags);
+void xine_demux_control_headers_done (xine_stream_t *stream);
+void xine_demux_control_start (xine_stream_t *stream);
+void xine_demux_control_end (xine_stream_t *stream, uint32_t flags);
/*
* plugin_loader functions
*
*/
+/* on-demand loading of audio/video/spu decoder plugins */
+
+video_decoder_t *get_video_decoder (xine_stream_t *stream, uint8_t stream_type);
+void free_video_decoder (xine_stream_t *stream, video_decoder_t *decoder);
+audio_decoder_t *get_audio_decoder (xine_stream_t *stream, uint8_t stream_type);
+void free_audio_decoder (xine_stream_t *stream, audio_decoder_t *decoder);
+spu_decoder_t *get_spu_decoder (xine_stream_t *stream, uint8_t stream_type);
+void free_spu_decoder (xine_stream_t *stream, spu_decoder_t *decoder);
+
/*
* load_video_output_plugin
*
@@ -327,13 +265,13 @@ xine_vo_driver_t *xine_load_video_output_plugin(xine_t *this,
xine_ao_driver_t *xine_load_audio_output_plugin (xine_t *self, char *id);
-void xine_set_speed (xine_t *this, int speed) ;
+void xine_set_speed (xine_stream_t *stream, int speed) ;
-void xine_select_spu_channel (xine_t *this, int channel) ;
+void xine_select_spu_channel (xine_stream_t *stream, int channel) ;
-int xine_get_audio_channel (xine_t *this) ;
+int xine_get_audio_channel (xine_stream_t *stream) ;
-int xine_get_spu_channel (xine_t *this) ;
+int xine_get_spu_channel (xine_stream_t *stream) ;
#ifdef __cplusplus
}
diff --git a/src/xine-engine/xine_plugin.h b/src/xine-engine/xine_plugin.h
index 99297cc7e..16845dbf0 100644
--- a/src/xine-engine/xine_plugin.h
+++ b/src/xine-engine/xine_plugin.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_plugin.h,v 1.3 2002/09/05 16:24:14 guenter Exp $
+ * $Id: xine_plugin.h,v 1.4 2002/10/14 15:47:46 guenter Exp $
*
* generic plugin definitions
*
@@ -26,7 +26,7 @@
#ifndef XINE_PLUGIN_H
#define XINE_PLUGIN_H
-#define PLUGIN_NONE 0
+#define PLUGIN_NONE 0
#define PLUGIN_INPUT 1
#define PLUGIN_DEMUX 2
#define PLUGIN_AUDIO_DECODER 3
@@ -42,7 +42,8 @@ typedef struct {
char *id; /* a name that identifies this plugin */
uint32_t version; /* version number, increased every release */
void *special_info; /* plugin-type specific, see structs below */
- void *(*init)(xine_t *, void *); /* used to get/initialize an instance*/
+ void *(*init)(xine_t *, void *); /* init the plugin class */
+ void *(*open)(void *, xine_stream_t *, const void *); /* create an instance*/
} plugin_info_t;