summaryrefslogtreecommitdiff
path: root/src/xine-engine
diff options
context:
space:
mode:
authorMichael Roitzsch <mroi@users.sourceforge.net>2002-11-20 11:57:38 +0000
committerMichael Roitzsch <mroi@users.sourceforge.net>2002-11-20 11:57:38 +0000
commit4e95a4f5224e241075b8cd86b4423c85c1d0ee26 (patch)
treecd9287e15591dce94560663ad66fc4005d006012 /src/xine-engine
parent74893748b868ecc6ae539fa66e326e06947c4ac9 (diff)
downloadxine-lib-4e95a4f5224e241075b8cd86b4423c85c1d0ee26.tar.gz
xine-lib-4e95a4f5224e241075b8cd86b4423c85c1d0ee26.tar.bz2
engine modifications to allow post plugin layer:
* new public output interface xine_{audio,video}_port_t instead of xine_{ao,vo}_driver_t, old names kept as aliases for compatibility * modified the engine to allow multiple streams per output * renaming of some internal structures according to public changes * moving SCR out of per-stream-metronom into a global metronom_clock_t residing in xine_t and therefore easily available to the output layer * adapting all available plugins (note to external projects: the compiler will help you a lot, if a plugin compiles, it is adapted, because all changes add new parameters to some functions) * bump up all interface versions because of xine_t and xine_stream_t changes CVS patchset: 3312 CVS date: 2002/11/20 11:57:38
Diffstat (limited to 'src/xine-engine')
-rw-r--r--src/xine-engine/audio_decoder.h4
-rw-r--r--src/xine-engine/audio_out.c147
-rw-r--r--src/xine-engine/audio_out.h76
-rw-r--r--src/xine-engine/demux.c4
-rw-r--r--src/xine-engine/load_plugins.c42
-rw-r--r--src/xine-engine/metronom.c133
-rw-r--r--src/xine-engine/metronom.h142
-rw-r--r--src/xine-engine/video_decoder.h4
-rw-r--r--src/xine-engine/video_out.c146
-rw-r--r--src/xine-engine/video_out.h85
-rw-r--r--src/xine-engine/video_overlay.c4
-rw-r--r--src/xine-engine/xine.c39
-rw-r--r--src/xine-engine/xine_interface.c4
-rw-r--r--src/xine-engine/xine_internal.h17
14 files changed, 508 insertions, 339 deletions
diff --git a/src/xine-engine/audio_decoder.h b/src/xine-engine/audio_decoder.h
index 847ff9736..fec946f5a 100644
--- a/src/xine-engine/audio_decoder.h
+++ b/src/xine-engine/audio_decoder.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_decoder.h,v 1.6 2002/11/12 18:40:54 miguelfreitas Exp $
+ * $Id: audio_decoder.h,v 1.7 2002/11/20 11:57:49 mroi Exp $
*
* xine audio decoder plugin interface
*
@@ -29,7 +29,7 @@
#include <inttypes.h>
#include "buffer.h"
-#define AUDIO_DECODER_IFACE_VERSION 11
+#define AUDIO_DECODER_IFACE_VERSION 12
/*
* generic xine audio decoder plugin interface
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 18ca40cd5..2421336b7 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.82 2002/11/18 15:53:31 heikos Exp $
+ * $Id: audio_out.c,v 1.83 2002/11/20 11:57:49 mroi Exp $
*
* 22-8-2001 James imported some useful AC3 sections from the previous alsa driver.
* (c) 2001 Andy Lo A Foe <andy@alsaplayer.org>
@@ -207,7 +207,7 @@ static audio_buffer_t *fifo_remove (audio_fifo_t *fifo) {
}
-void write_pause_burst(ao_instance_t *this, uint32_t num_frames) {
+void write_pause_burst(xine_audio_port_t *this, uint32_t num_frames) {
int error = 0;
unsigned char buf[8192];
@@ -245,7 +245,7 @@ void write_pause_burst(ao_instance_t *this, uint32_t num_frames) {
}
-static void ao_fill_gap (ao_instance_t *this, int64_t pts_len) {
+static void ao_fill_gap (xine_audio_port_t *this, int64_t pts_len) {
int num_frames ;
@@ -286,7 +286,7 @@ static void ensure_buffer_size (audio_buffer_t *buf, int bytes_per_frame,
buf->num_frames = frames;
}
-static audio_buffer_t * swap_frame_buffers ( ao_instance_t *this ) {
+static audio_buffer_t * swap_frame_buffers ( xine_audio_port_t *this ) {
audio_buffer_t *tmp;
tmp = this->frame_buf[1];
@@ -311,7 +311,7 @@ static int mode_channels( int mode ) {
return 0;
}
-static void audio_filter_compress (ao_instance_t *this, int16_t *mem, int num_frames) {
+static void audio_filter_compress (xine_audio_port_t *this, int16_t *mem, int num_frames) {
int i, maxs;
double f_max;
@@ -354,7 +354,7 @@ static void audio_filter_compress (ao_instance_t *this, int16_t *mem, int num_fr
mem [i] = mem[i] * this->compression_factor;
}
-static audio_buffer_t* prepare_samples( ao_instance_t *this, audio_buffer_t *buf) {
+static audio_buffer_t* prepare_samples( xine_audio_port_t *this, audio_buffer_t *buf) {
double acc_output_frames, output_frame_excess = 0;
int num_output_frames ;
@@ -488,7 +488,7 @@ static audio_buffer_t* prepare_samples( ao_instance_t *this, audio_buffer_t *bu
*/
static void *ao_loop (void *this_gen) {
- ao_instance_t *this = (ao_instance_t *) this_gen;
+ xine_audio_port_t *this = (xine_audio_port_t *) this_gen;
int64_t hw_vpts;
audio_buffer_t *in_buf, *out_buf;
int64_t gap;
@@ -537,7 +537,7 @@ static void *ao_loop (void *this_gen) {
if (this->audio_paused == 1) {
- cur_time = this->metronom->get_current_time (this->metronom);
+ cur_time = this->clock->get_current_time (this->clock);
if (in_buf->vpts < cur_time ) {
#ifdef LOG
printf ("audio_out:loop: next fifo\n");
@@ -573,7 +573,7 @@ static void *ao_loop (void *this_gen) {
* hardware audio buffer at the moment?
*/
- cur_time = this->metronom->get_current_time (this->metronom);
+ cur_time = this->clock->get_current_time (this->clock);
hw_vpts = cur_time;
#ifdef LOG
@@ -621,13 +621,19 @@ static void *ao_loop (void *this_gen) {
} else if ( abs(gap) < AO_MAX_GAP && abs(gap) > this->gap_tolerance &&
cur_time > (last_sync_time + SYNC_TIME_INVERVAL) &&
bufs_since_sync >= SYNC_BUF_INTERVAL ) {
+ xine_stream_t *stream;
#ifdef LOG
printf ("audio_out: audio_loop: ADJ_VPTS\n");
#endif
- this->metronom->set_option(this->metronom, METRONOM_ADJ_VPTS_OFFSET,
- -gap/SYNC_GAP_RATE );
- last_sync_time = cur_time;
- bufs_since_sync = 0;
+ pthread_mutex_lock(&this->streams_lock);
+ for (stream = xine_list_first_content(this->streams); stream;
+ stream = xine_list_next_content(this->streams)) {
+ stream->metronom->set_option(stream->metronom, METRONOM_ADJ_VPTS_OFFSET,
+ -gap/SYNC_GAP_RATE );
+ last_sync_time = cur_time;
+ bufs_since_sync = 0;
+ }
+ pthread_mutex_unlock(&this->streams_lock);
} else if ( gap > AO_MAX_GAP ) {
/* for big gaps output silence */
@@ -684,7 +690,7 @@ static void *ao_loop (void *this_gen) {
* open the audio device for writing to, start audio output thread
*/
-static int ao_open(ao_instance_t *this,
+static int ao_open(xine_audio_port_t *this, xine_stream_t *stream,
uint32_t bits, uint32_t rate, int mode) {
int output_sample_rate, err;
@@ -693,31 +699,36 @@ static int ao_open(ao_instance_t *this,
/*
* set metainfo
*/
-
- switch (mode) {
- case AO_CAP_MODE_MONO:
- this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 1;
- break;
- case AO_CAP_MODE_STEREO:
- this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 2;
- break;
- case AO_CAP_MODE_4CHANNEL:
- this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 4;
- break;
- case AO_CAP_MODE_5CHANNEL:
- this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 5;
- break;
- case AO_CAP_MODE_5_1CHANNEL:
- this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 6;
- break;
- case AO_CAP_MODE_A52:
- case AO_CAP_MODE_AC5:
- default:
- this->stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 255; /* unknown */
- }
+ pthread_mutex_lock(&this->streams_lock);
+ xine_list_append_content(this->streams, stream);
+ for (stream = xine_list_first_content(this->streams); stream;
+ stream = xine_list_next_content(this->streams)) {
+ switch (mode) {
+ case AO_CAP_MODE_MONO:
+ stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 1;
+ break;
+ case AO_CAP_MODE_STEREO:
+ stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 2;
+ break;
+ case AO_CAP_MODE_4CHANNEL:
+ stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 4;
+ break;
+ case AO_CAP_MODE_5CHANNEL:
+ stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 5;
+ break;
+ case AO_CAP_MODE_5_1CHANNEL:
+ stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 6;
+ break;
+ case AO_CAP_MODE_A52:
+ case AO_CAP_MODE_AC5:
+ default:
+ stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 255; /* unknown */
+ }
- this->stream->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = bits;
- this->stream->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] = rate;
+ stream->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = bits;
+ stream->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] = rate;
+ }
+ pthread_mutex_unlock(&this->streams_lock);
this->input.mode = mode;
this->input.rate = rate;
@@ -781,7 +792,11 @@ static int ao_open(ao_instance_t *this,
printf ("audio_out : audio_step %d pts per 32768 frames\n", this->audio_step);
#endif
- this->metronom->set_audio_rate(this->metronom, this->audio_step);
+ pthread_mutex_lock(&this->streams_lock);
+ for (stream = xine_list_first_content(this->streams); stream;
+ stream = xine_list_next_content(this->streams))
+ stream->metronom->set_audio_rate(stream->metronom, this->audio_step);
+ pthread_mutex_unlock(&this->streams_lock);
/*
* start output thread
@@ -811,11 +826,11 @@ static int ao_open(ao_instance_t *this,
return this->output.rate;
}
-static audio_buffer_t *ao_get_buffer (ao_instance_t *this) {
+static audio_buffer_t *ao_get_buffer (xine_audio_port_t *this) {
return fifo_remove (this->free_fifo);
}
-static void ao_put_buffer (ao_instance_t *this, audio_buffer_t *buf) {
+static void ao_put_buffer (xine_audio_port_t *this, audio_buffer_t *buf, xine_stream_t *stream) {
int64_t pts;
@@ -826,8 +841,8 @@ static void ao_put_buffer (ao_instance_t *this, audio_buffer_t *buf) {
pts = buf->vpts;
- buf->vpts = this->metronom->got_audio_samples (this->metronom, pts,
- buf->num_frames);
+ buf->vpts = stream->metronom->got_audio_samples (stream->metronom, pts,
+ buf->num_frames);
#ifdef LOG
printf ("audio_out: ao_put_buffer, pts=%lld, vpts=%lld\n",
@@ -854,9 +869,10 @@ static void ao_put_buffer (ao_instance_t *this, audio_buffer_t *buf) {
#endif
}
-static void ao_close(ao_instance_t *this) {
+static void ao_close(xine_audio_port_t *this, xine_stream_t *stream) {
audio_buffer_t *audio_buffer;
+ xine_stream_t *cur;
if (this->audio_loop_running) {
void *p;
@@ -871,13 +887,23 @@ static void ao_close(ao_instance_t *this) {
pthread_join (this->audio_thread, &p);
this->audio_thread = 0;
}
+
+ /* unregister stream */
+ pthread_mutex_lock(&this->streams_lock);
+ for (cur = xine_list_first_content(this->streams); cur;
+ cur = xine_list_next_content(this->streams))
+ if (cur == stream) {
+ xine_list_delete_current(this->streams);
+ break;
+ }
+ pthread_mutex_unlock(&this->streams_lock);
pthread_mutex_lock( &this->driver_lock );
this->driver->close(this->driver);
pthread_mutex_unlock( &this->driver_lock );
}
-static void ao_exit(ao_instance_t *this) {
+static void ao_exit(xine_audio_port_t *this) {
int vol;
int prop = 0;
@@ -894,6 +920,10 @@ static void ao_exit(ao_instance_t *this) {
this->xine->config->update_num(this->xine->config, "audio.mixer_volume", vol);
this->driver->exit(this->driver);
pthread_mutex_unlock( &this->driver_lock );
+
+ pthread_mutex_destroy(&this->driver_lock);
+ pthread_mutex_destroy(&this->streams_lock);
+ xine_list_free(this->streams);
free (this->frame_buf[0]->mem);
free (this->frame_buf[0]);
@@ -930,7 +960,7 @@ static void ao_exit(ao_instance_t *this) {
free (this);
}
-static uint32_t ao_get_capabilities (ao_instance_t *this) {
+static uint32_t ao_get_capabilities (xine_audio_port_t *this) {
uint32_t result;
pthread_mutex_lock( &this->driver_lock );
@@ -940,7 +970,7 @@ static uint32_t ao_get_capabilities (ao_instance_t *this) {
return result;
}
-static int ao_get_property (ao_instance_t *this, int property) {
+static int ao_get_property (xine_audio_port_t *this, int property) {
int ret;
switch (property) {
@@ -956,7 +986,7 @@ static int ao_get_property (ao_instance_t *this, int property) {
return ret;
}
-static int ao_set_property (ao_instance_t *this, int property, int value) {
+static int ao_set_property (xine_audio_port_t *this, int property, int value) {
int ret;
switch (property) {
@@ -977,7 +1007,7 @@ static int ao_set_property (ao_instance_t *this, int property, int value) {
return ret;
}
-static int ao_control (ao_instance_t *this, int cmd, ...) {
+static int ao_control (xine_audio_port_t *this, int cmd, ...) {
va_list args;
void *arg;
@@ -993,7 +1023,7 @@ static int ao_control (ao_instance_t *this, int cmd, ...) {
return rval;
}
-static void ao_flush (ao_instance_t *this) {
+static void ao_flush (xine_audio_port_t *this) {
audio_buffer_t *buf;
int i, num_buffers;
@@ -1023,20 +1053,21 @@ static void ao_flush (ao_instance_t *this) {
pthread_mutex_unlock (&this->out_fifo->mutex);
}
-ao_instance_t *ao_new_instance (xine_ao_driver_t *driver,
- xine_stream_t *stream) {
+xine_audio_port_t *ao_new_port (xine_t *xine, ao_driver_t *driver) {
- config_values_t *config = stream->xine->config;
- ao_instance_t *this;
+ config_values_t *config = xine->config;
+ xine_audio_port_t *this;
int i;
static char *resample_modes[] = {"auto", "off", "on", NULL};
- this = xine_xmalloc (sizeof (ao_instance_t)) ;
+ this = xine_xmalloc (sizeof (xine_audio_port_t)) ;
this->driver = driver;
- this->metronom = stream->metronom;
- this->xine = stream->xine;
- this->stream = stream;
+ this->xine = xine;
+ this->clock = xine->clock;
+ this->streams = xine_list_new();
+
+ pthread_mutex_init( &this->streams_lock, NULL );
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 5e1cedaa4..a839f628c 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.40 2002/10/29 16:02:47 mroi Exp $
+ * $Id: audio_out.h,v 1.41 2002/11/20 11:57:49 mroi Exp $
*/
#ifndef HAVE_AUDIO_OUT_H
#define HAVE_AUDIO_OUT_H
@@ -31,20 +31,24 @@ extern "C" {
#if defined(XINE_COMPILE)
#include "metronom.h"
#include "configfile.h"
+#include "xineutils.h"
#else
#include <xine/metronom.h>
#include <xine/configfile.h>
+#inlcude <xine/xineutils.h>
#endif
-#define AUDIO_OUT_IFACE_VERSION 5
+#define AUDIO_OUT_IFACE_VERSION 6
/*
* ao_driver_s contains the driver every audio output
* driver plugin has to implement.
*/
-struct xine_ao_driver_s {
+typedef struct ao_driver_s ao_driver_t;
+
+struct ao_driver_s {
/*
*
@@ -53,7 +57,7 @@ struct xine_ao_driver_s {
*
* See AO_CAP_* bellow.
*/
- uint32_t (*get_capabilities) (xine_ao_driver_t *this);
+ uint32_t (*get_capabilities) (ao_driver_t *this);
/*
* open the driver and make it ready to receive audio data
@@ -61,26 +65,26 @@ struct xine_ao_driver_s {
*
* return value: 0 : failure, >0 : output sample rate
*/
- int (*open)(xine_ao_driver_t *this, uint32_t bits, uint32_t rate, int mode);
+ int (*open)(ao_driver_t *this, uint32_t bits, uint32_t rate, int mode);
/* return the number of audio channels
*/
- int (*num_channels)(xine_ao_driver_t *self_gen);
+ int (*num_channels)(ao_driver_t *self_gen);
/* return the number of bytes per frame.
* A frame is equivalent to one sample being output on every audio channel.
*/
- int (*bytes_per_frame)(xine_ao_driver_t *self_gen);
+ int (*bytes_per_frame)(ao_driver_t *self_gen);
/* return the delay is frames measured by
* looking at pending samples in the audio output device
*/
- int (*delay)(xine_ao_driver_t *self_gen);
+ int (*delay)(ao_driver_t *self_gen);
/*
* return gap tolerance (in pts) needed for this driver
*/
- int (*get_gap_tolerance) (xine_ao_driver_t *self_gen);
+ int (*get_gap_tolerance) (ao_driver_t *self_gen);
/*
* write audio data to output buffer
@@ -90,20 +94,20 @@ struct xine_ao_driver_s {
* 0 => audio samples were not yet processed,
* call write_audio_data with the _same_ samples again
*/
- int (*write)(xine_ao_driver_t *this,
+ int (*write)(ao_driver_t *this,
int16_t* audio_data, uint32_t num_samples);
/*
* this is called when the decoder no longer uses the audio
* output driver - the driver should get ready to get opened() again
*/
- void (*close)(xine_ao_driver_t *this);
+ void (*close)(ao_driver_t *this);
/*
* shut down this audio output driver plugin and
* free all resources allocated
*/
- void (*exit) (xine_ao_driver_t *this);
+ void (*exit) (ao_driver_t *this);
/*
* Get, Set a property of audio driver.
@@ -113,9 +117,9 @@ struct xine_ao_driver_s {
*
* See AO_PROP_* below for available properties.
*/
- int (*get_property) (xine_ao_driver_t *this, int property);
+ int (*get_property) (ao_driver_t *this, int property);
- int (*set_property) (xine_ao_driver_t *this, int property, int value);
+ int (*set_property) (ao_driver_t *this, int property, int value);
/*
@@ -123,13 +127,13 @@ struct xine_ao_driver_s {
*
* See AO_CTRL_* below.
*/
- int (*control) (xine_ao_driver_t *this, int cmd, /* arg */ ...);
+ int (*control) (ao_driver_t *this, int cmd, /* arg */ ...);
void *node;
};
/*
- * ao_instance_s contains the instance every audio decoder talks to
+ * ao_port_s contains the port every audio decoder talks to
*/
typedef struct audio_fifo_s audio_fifo_t;
@@ -156,63 +160,63 @@ struct ao_format_s {
int mode;
};
-typedef struct ao_instance_s ao_instance_t;
-
-struct ao_instance_s {
- uint32_t (*get_capabilities) (ao_instance_t *this); /* for constants see below */
+struct xine_audio_port_s {
+ uint32_t (*get_capabilities) (xine_audio_port_t *this); /* for constants see below */
/*
* Get/Set audio property
*
* See AO_PROP_* bellow
*/
- int (*get_property) (ao_instance_t *this, int property);
- int (*set_property) (ao_instance_t *this, int property, int value);
+ int (*get_property) (xine_audio_port_t *this, int property);
+ int (*set_property) (xine_audio_port_t *this, int property, int value);
/* open audio driver for audio output
* return value: 0:failure, >0:output sample rate
*/
- int (*open) (ao_instance_t *this,
+ int (*open) (xine_audio_port_t *this, xine_stream_t *stream,
uint32_t bits, uint32_t rate, int mode);
/*
* get a piece of memory for audio data
*/
- audio_buffer_t * (*get_buffer) (ao_instance_t *this);
+ audio_buffer_t * (*get_buffer) (xine_audio_port_t *this);
/*
* append a buffer filled with audio data to the audio fifo
* for output
*/
- void (*put_buffer) (ao_instance_t *this, audio_buffer_t *buf);
+ void (*put_buffer) (xine_audio_port_t *this, audio_buffer_t *buf, xine_stream_t *stream);
/* audio driver is no longer used by decoder => close */
- void (*close) (ao_instance_t *self);
+ void (*close) (xine_audio_port_t *self, xine_stream_t *stream);
/* called on xine exit */
- void (*exit) (ao_instance_t *this);
+ void (*exit) (xine_audio_port_t *this);
/*
* misc control operations on the audio device.
*
* See AO_CTRL_* below.
*/
- int (*control) (ao_instance_t *this, int cmd, /* arg */ ...);
+ int (*control) (xine_audio_port_t *this, int cmd, /* arg */ ...);
/*
* Flush audio_out fifo.
*/
- void (*flush) (ao_instance_t *this);
+ void (*flush) (xine_audio_port_t *this);
+ /* the driver in use */
+ ao_driver_t *driver;
+
/* private stuff */
-
- xine_ao_driver_t *driver;
pthread_mutex_t driver_lock;
- metronom_t *metronom;
- xine_stream_t *stream;
+ metronom_clock_t *clock;
xine_t *xine;
+ xine_list_t *streams;
+ pthread_mutex_t streams_lock;
int audio_loop_running;
int audio_paused;
@@ -242,6 +246,7 @@ struct ao_instance_s {
int do_compress;
double compression_factor; /* current compression */
double compression_factor_max; /* user limit on compression */
+
};
typedef struct audio_driver_class_s audio_driver_class_t;
@@ -251,7 +256,7 @@ struct audio_driver_class_s {
/*
* open a new instance of this plugin class
*/
- xine_ao_driver_t* (*open_plugin) (audio_driver_class_t *this, const void *data);
+ ao_driver_t* (*open_plugin) (audio_driver_class_t *this, const void *data);
/*
* return short, human readable identifier for this plugin class
@@ -275,8 +280,7 @@ struct audio_driver_class_s {
* 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_stream_t *stream) ;
+xine_audio_port_t *ao_new_port (xine_t *xine, ao_driver_t *driver) ;
/*
* audio output modes + capabilities
diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c
index 5b7138cd1..54edcbe97 100644
--- a/src/xine-engine/demux.c
+++ b/src/xine-engine/demux.c
@@ -66,8 +66,8 @@ void xine_demux_flush_engine (xine_stream_t *stream) {
stream->audio_out->flush(stream->audio_out);
}
- stream->metronom->adjust_clock(stream->metronom,
- stream->metronom->get_current_time(stream->metronom) + 30 * 90000 );
+ stream->xine->clock->adjust_clock(stream->xine->clock,
+ stream->xine->clock->get_current_time(stream->xine->clock) + 30 * 90000 );
}
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index b838f589e..5a82607a7 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.113 2002/11/14 19:45:01 esnel Exp $
+ * $Id: load_plugins.c,v 1.114 2002/11/20 11:57:49 mroi Exp $
*
*
* Load input/demux/audio_out/video_out/codec plugins
@@ -816,10 +816,10 @@ const char *xine_get_input_plugin_description (xine_t *this, const char *plugin_
* video out plugins section
*/
-static xine_vo_driver_t *_load_video_driver (xine_t *this, plugin_node_t *node,
- void *data) {
+static vo_driver_t *_load_video_driver (xine_t *this, plugin_node_t *node,
+ void *data) {
- xine_vo_driver_t *driver;
+ vo_driver_t *driver;
if (!node->plugin_class)
node->plugin_class = _load_plugin_class (this, node->filename, node->info, data);
@@ -843,12 +843,13 @@ static xine_vo_driver_t *_load_video_driver (xine_t *this, plugin_node_t *node,
return driver;
}
-xine_vo_driver_t *xine_open_video_driver (xine_t *this,
- const char *id,
- int visual_type, void *visual) {
+xine_video_port_t *xine_open_video_driver (xine_t *this,
+ const char *id,
+ int visual_type, void *visual) {
plugin_node_t *node;
- xine_vo_driver_t *driver;
+ vo_driver_t *driver;
+ xine_video_port_t *port;
vo_info_t *vo_info;
plugin_catalog_t *catalog = this->plugin_catalog;
@@ -895,7 +896,9 @@ xine_vo_driver_t *xine_open_video_driver (xine_t *this,
pthread_mutex_unlock (&catalog->lock);
- return driver;
+ port = vo_new_port(this, driver);
+
+ return port;
}
/*
@@ -958,10 +961,10 @@ const char *const *xine_list_video_output_plugins (xine_t *this) {
return catalog->ids;
}
-static xine_ao_driver_t *_load_audio_driver (xine_t *this, plugin_node_t *node,
- void *data) {
+static ao_driver_t *_load_audio_driver (xine_t *this, plugin_node_t *node,
+ void *data) {
- xine_ao_driver_t *driver;
+ ao_driver_t *driver;
if (!node->plugin_class)
node->plugin_class = _load_plugin_class (this, node->filename, node->info, data);
@@ -985,11 +988,12 @@ static xine_ao_driver_t *_load_audio_driver (xine_t *this, plugin_node_t *node,
return driver;
}
-xine_ao_driver_t *xine_open_audio_driver (xine_t *this, const char *id,
- void *data) {
+xine_audio_port_t *xine_open_audio_driver (xine_t *this, const char *id,
+ void *data) {
plugin_node_t *node;
- xine_ao_driver_t *driver;
+ ao_driver_t *driver;
+ xine_audio_port_t *port;
ao_info_t *ao_info;
plugin_catalog_t *catalog = this->plugin_catalog;
@@ -1035,16 +1039,18 @@ xine_ao_driver_t *xine_open_audio_driver (xine_t *this, const char *id,
}
pthread_mutex_unlock (&catalog->lock);
+
+ port = ao_new_port(this, driver);
- return driver;
+ return port;
}
-void xine_close_audio_driver (xine_t *this, xine_ao_driver_t *driver) {
+void xine_close_audio_driver (xine_t *this, xine_audio_port_t *driver) {
/* FIXME : implement */
}
-void xine_close_video_driver (xine_t *this, xine_vo_driver_t *driver) {
+void xine_close_video_driver (xine_t *this, xine_video_port_t *driver) {
/* FIXME : implement */
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index a8ab454b6..faf803c96 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.101 2002/11/19 00:45:42 miguelfreitas Exp $
+ * $Id: metronom.c,v 1.102 2002/11/20 11:57:49 mroi Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -198,28 +198,30 @@ static scr_plugin_t* unixscr_init () {
*/
-static void metronom_start_clock (metronom_t *this, int64_t pts) {
+static void metronom_start_clock (metronom_clock_t *this, int64_t pts) {
scr_plugin_t** scr;
printf ("metronom: start_clock (at %lld)\n", pts);
for (scr = this->scr_list; scr < this->scr_list+MAX_SCR_PROVIDERS; scr++)
if (*scr) (*scr)->start(*scr, pts);
+
+ this->speed = XINE_SPEED_NORMAL;
}
-static int64_t metronom_get_current_time (metronom_t *this) {
+static int64_t metronom_get_current_time (metronom_clock_t *this) {
return this->scr_master->get_current(this->scr_master);
}
-static void metronom_stop_clock(metronom_t *this) {
+static void metronom_stop_clock(metronom_clock_t *this) {
scr_plugin_t** scr;
for (scr = this->scr_list; scr < this->scr_list+MAX_SCR_PROVIDERS; scr++)
if (*scr) (*scr)->set_speed(*scr, XINE_SPEED_PAUSE);
}
-static void metronom_resume_clock(metronom_t *this) {
+static void metronom_resume_clock(metronom_clock_t *this) {
scr_plugin_t** scr;
for (scr = this->scr_list; scr < this->scr_list+MAX_SCR_PROVIDERS; scr++)
if (*scr) (*scr)->set_speed(*scr, XINE_SPEED_NORMAL);
@@ -227,17 +229,19 @@ static void metronom_resume_clock(metronom_t *this) {
-static void metronom_adjust_clock(metronom_t *this, int64_t desired_pts) {
+static void metronom_adjust_clock(metronom_clock_t *this, int64_t desired_pts) {
if (this->scr_adjustable)
this->scr_master->adjust(this->scr_master, desired_pts);
}
-static int metronom_set_speed (metronom_t *this, int speed) {
+static int metronom_set_speed (metronom_clock_t *this, int speed) {
scr_plugin_t **scr;
int true_speed;
true_speed = this->scr_master->set_speed (this->scr_master, speed);
+
+ this->speed = true_speed;
for (scr = this->scr_list; scr < this->scr_list+MAX_SCR_PROVIDERS; scr++)
if (*scr) (*scr)->set_speed(*scr, true_speed);
@@ -554,9 +558,6 @@ static void metronom_set_option (metronom_t *this, int option, int64_t value) {
this->av_offset = value;
printf ("metronom: av_offset=%lld pts\n", this->av_offset);
break;
- case METRONOM_SCR_ADJUSTABLE:
- this->scr_adjustable = value;
- break;
case METRONOM_ADJ_VPTS_OFFSET:
this->vpts_offset += value;
#ifdef LOG
@@ -571,11 +572,36 @@ static void metronom_set_option (metronom_t *this, int option, int64_t value) {
pthread_mutex_unlock (&this->lock);
}
+static void metronom_clock_set_option (metronom_clock_t *this,
+ int option, int64_t value) {
+
+ pthread_mutex_lock (&this->lock);
+
+ switch (option) {
+ case CLOCK_SCR_ADJUSTABLE:
+ this->scr_adjustable = value;
+ break;
+ default:
+ printf ("metronom: unknown option in set_option: %d\n",
+ option);
+ }
+
+ pthread_mutex_unlock (&this->lock);
+}
+
static int64_t metronom_get_option (metronom_t *this, int option) {
switch (option) {
case METRONOM_AV_OFFSET:
return this->av_offset;
- case METRONOM_SCR_ADJUSTABLE:
+ }
+ printf ("metronom: unknown option in get_option: %d\n",
+ option);
+ return 0;
+}
+
+static int64_t metronom_clock_get_option (metronom_clock_t *this, int option) {
+ switch (option) {
+ case CLOCK_SCR_ADJUSTABLE:
return this->scr_adjustable;
}
printf ("metronom: unknown option in get_option: %d\n",
@@ -583,7 +609,7 @@ static int64_t metronom_get_option (metronom_t *this, int option) {
return 0;
}
-static scr_plugin_t* get_master_scr(metronom_t *this) {
+static scr_plugin_t* get_master_scr(metronom_clock_t *this) {
int select = -1, maxprio = 0, i;
/* find the SCR provider with the highest priority */
@@ -602,7 +628,7 @@ static scr_plugin_t* get_master_scr(metronom_t *this) {
return this->scr_list[select];
}
-static int metronom_register_scr (metronom_t *this, scr_plugin_t *scr) {
+static int metronom_register_scr (metronom_clock_t *this, scr_plugin_t *scr) {
int i;
if (scr->interface_version != 2) return -1;
@@ -612,13 +638,13 @@ static int metronom_register_scr (metronom_t *this, scr_plugin_t *scr) {
if (i >= MAX_SCR_PROVIDERS)
return -1; /* No free slot available */
- scr->metronom = this;
+ scr->clock = this;
this->scr_list[i] = scr;
this->scr_master = get_master_scr(this);
return 0;
}
-static void metronom_unregister_scr (metronom_t *this, scr_plugin_t *scr) {
+static void metronom_unregister_scr (metronom_clock_t *this, scr_plugin_t *scr) {
int i;
int64_t time;
@@ -640,22 +666,22 @@ static void metronom_unregister_scr (metronom_t *this, scr_plugin_t *scr) {
this->scr_master = get_master_scr(this);
}
-static int metronom_sync_loop (metronom_t *this) {
+static int metronom_sync_loop (metronom_clock_t *this) {
struct timeval tv;
struct timespec ts;
scr_plugin_t** scr;
int64_t pts;
- while (this->stream->status != XINE_STATUS_QUIT) {
+ while (this->thread_running) {
+ /* synchronise every 5 seconds */
+ pthread_mutex_lock (&this->lock);
+
pts = this->scr_master->get_current(this->scr_master);
for (scr = this->scr_list; scr < this->scr_list+MAX_SCR_PROVIDERS; scr++)
if (*scr && *scr != this->scr_master) (*scr)->adjust(*scr, pts);
- /* synchronise every 5 seconds */
- pthread_mutex_lock (&this->lock);
-
gettimeofday(&tv, NULL);
ts.tv_sec = tv.tv_sec + 5;
ts.tv_nsec = tv.tv_usec * 1000;
@@ -668,8 +694,19 @@ static int metronom_sync_loop (metronom_t *this) {
static void metronom_exit (metronom_t *this) {
+ pthread_mutex_destroy (&this->lock);
+ pthread_cond_destroy (&this->video_discontinuity_reached);
+ pthread_cond_destroy (&this->audio_discontinuity_reached);
+
+ free (this);
+}
+
+static void metronom_clock_exit (metronom_clock_t *this) {
+
scr_plugin_t** scr;
+ this->thread_running = 0;
+
pthread_mutex_lock (&this->lock);
pthread_cond_signal (&this->cancel);
pthread_mutex_unlock (&this->lock);
@@ -677,8 +714,6 @@ static void metronom_exit (metronom_t *this) {
pthread_join (this->sync_thread, NULL);
pthread_mutex_destroy (&this->lock);
- pthread_cond_destroy (&this->video_discontinuity_reached);
- pthread_cond_destroy (&this->audio_discontinuity_reached);
pthread_cond_destroy (&this->cancel);
for (scr = this->scr_list; scr < this->scr_list+MAX_SCR_PROVIDERS; scr++)
@@ -692,9 +727,9 @@ static void metronom_exit (metronom_t *this) {
metronom_t * metronom_init (int have_audio, xine_stream_t *stream) {
metronom_t *this = xine_xmalloc (sizeof (metronom_t));
- int err;
this->stream = stream;
+ this->clock = stream->xine->clock;
this->set_audio_rate = metronom_set_audio_rate;
this->got_video_frame = metronom_got_video_frame;
this->got_audio_samples = metronom_got_audio_samples;
@@ -703,27 +738,9 @@ metronom_t * metronom_init (int have_audio, xine_stream_t *stream) {
this->handle_video_discontinuity = metronom_handle_video_discontinuity;
this->set_option = metronom_set_option;
this->get_option = metronom_get_option;
- this->start_clock = metronom_start_clock;
- this->stop_clock = metronom_stop_clock;
- this->resume_clock = metronom_resume_clock;
- this->get_current_time = metronom_get_current_time;
- this->adjust_clock = metronom_adjust_clock;
- this->register_scr = metronom_register_scr;
- this->unregister_scr = metronom_unregister_scr;
- this->set_speed = metronom_set_speed;
this->exit = metronom_exit;
- this->scr_adjustable = 1;
- this->scr_list = calloc(MAX_SCR_PROVIDERS, sizeof(void*));
- this->register_scr(this, unixscr_init());
-
pthread_mutex_init (&this->lock, NULL);
- pthread_cond_init (&this->cancel, NULL);
-
- if ((err = pthread_create(&this->sync_thread, NULL,
- (void*(*)(void*)) metronom_sync_loop, this)) != 0)
- printf ("metronom: cannot create sync thread (%s)\n",
- strerror(err));
this->av_offset = 0;
this->vpts_offset = 0;
@@ -752,3 +769,37 @@ metronom_t * metronom_init (int have_audio, xine_stream_t *stream) {
return this;
}
+
+metronom_clock_t *metronom_clock_init(void)
+{
+ metronom_clock_t *this = (metronom_clock_t *)malloc(sizeof(metronom_clock_t));
+ int err;
+
+ this->set_option = metronom_clock_set_option;
+ this->get_option = metronom_clock_get_option;
+ this->start_clock = metronom_start_clock;
+ this->stop_clock = metronom_stop_clock;
+ this->resume_clock = metronom_resume_clock;
+ this->get_current_time = metronom_get_current_time;
+ this->adjust_clock = metronom_adjust_clock;
+ this->set_speed = metronom_set_speed;
+ this->register_scr = metronom_register_scr;
+ this->unregister_scr = metronom_unregister_scr;
+ this->exit = metronom_clock_exit;
+
+ this->scr_adjustable = 1;
+ this->scr_list = calloc(MAX_SCR_PROVIDERS, sizeof(void*));
+ this->register_scr(this, unixscr_init());
+
+ pthread_mutex_init (&this->lock, NULL);
+ pthread_cond_init (&this->cancel, NULL);
+
+ this->thread_running = 1;
+
+ if ((err = pthread_create(&this->sync_thread, NULL,
+ (void*(*)(void*)) metronom_sync_loop, this)) != 0)
+ printf ("metronom: cannot create sync thread (%s)\n",
+ strerror(err));
+
+ return this;
+}
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
index 0471d1209..949729010 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.40 2002/11/12 18:40:55 miguelfreitas Exp $
+ * $Id: metronom.h,v 1.41 2002/11/20 11:57:49 mroi Exp $
*
* metronom: general pts => virtual calculation/assoc
*
@@ -54,6 +54,7 @@ extern "C" {
#include "xine.h"
typedef struct metronom_s metronom_t ;
+typedef struct metronom_clock_s metronom_clock_t;
typedef struct scr_plugin_s scr_plugin_t;
/* see below */
@@ -150,40 +151,105 @@ struct metronom_s {
*/
void (*set_option) (metronom_t *this, int option, int64_t value);
int64_t (*get_option) (metronom_t *this, int option);
+
+ void (*exit) (metronom_t *this);
+
+ /*
+ * pointer to current xine stream object.
+ */
+ xine_stream_t *stream;
+
+ metronom_clock_t *clock;
+
+ /*
+ * metronom internal stuff
+ */
+
+ int64_t pts_per_smpls;
+
+ int64_t video_vpts;
+ int64_t spu_vpts;
+ int64_t audio_vpts;
+
+ int64_t vpts_offset;
+
+ int64_t video_drift;
+ int64_t video_drift_step;
+
+ int audio_samples;
+ int64_t audio_drift_step;
+
+ int64_t av_offset;
+
+ pthread_mutex_t lock;
+
+ int have_audio;
+ int video_discontinuity_count;
+ int audio_discontinuity_count;
+ int discontinuity_handled_count;
+ pthread_cond_t video_discontinuity_reached;
+ pthread_cond_t audio_discontinuity_reached;
+ pthread_cond_t cancel;
+
+ int force_video_jump;
+ int force_audio_jump;
+
+ int64_t img_duration;
+ int img_cpt;
+ int64_t last_video_pts;
+
+};
+
+/*
+ * metronom options
+ */
+
+#define METRONOM_AV_OFFSET 2
+#define METRONOM_ADJ_VPTS_OFFSET 3
+
+metronom_t *metronom_init (int have_audio, xine_stream_t *stream);
+
+struct metronom_clock_s {
+
+ /*
+ * set/get options for clock, constants see below
+ */
+ void (*set_option) (metronom_clock_t *this, int option, int64_t value);
+ int64_t (*get_option) (metronom_clock_t *this, int option);
/*
* system clock reference (SCR) functions
*/
/*
- * start metronom clock (no clock reset)
+ * start clock (no clock reset)
* at given pts
*/
- void (*start_clock) (metronom_t *this, int64_t pts);
+ void (*start_clock) (metronom_clock_t *this, int64_t pts);
/*
* stop metronom clock
*/
- void (*stop_clock) (metronom_t *this);
+ void (*stop_clock) (metronom_clock_t *this);
/*
* resume clock from where it was stopped
*/
- void (*resume_clock) (metronom_t *this);
+ void (*resume_clock) (metronom_clock_t *this);
/*
* get current clock value in vpts
*/
- int64_t (*get_current_time) (metronom_t *this);
+ int64_t (*get_current_time) (metronom_clock_t *this);
/*
* adjust master clock to external timer (e.g. audio hardware)
*/
- void (*adjust_clock) (metronom_t *this, int64_t desired_pts);
+ void (*adjust_clock) (metronom_clock_t *this, int64_t desired_pts);
/*
@@ -191,74 +257,36 @@ struct metronom_s {
* for constants see xine_internal.h
*/
- int (*set_speed) (metronom_t *this, int speed);
+ int (*set_speed) (metronom_clock_t *this, int speed);
/*
* (un)register a System Clock Reference provider at the metronom
*/
- int (*register_scr) (metronom_t *this, scr_plugin_t *scr);
- void (*unregister_scr) (metronom_t *this, scr_plugin_t *scr);
-
- void (*exit) (metronom_t *this);
-
- /*
- * pointer to current xine stream object.
- */
- xine_stream_t *stream;
+ int (*register_scr) (metronom_clock_t *this, scr_plugin_t *scr);
+ void (*unregister_scr) (metronom_clock_t *this, scr_plugin_t *scr);
- /*
- * metronom internal stuff
- */
-
- int64_t pts_per_smpls;
-
- int64_t video_vpts;
- int64_t spu_vpts;
- int64_t audio_vpts;
-
- int64_t vpts_offset;
-
- int64_t video_drift;
- int64_t video_drift_step;
+ void (*exit) (metronom_clock_t *this);
- int audio_samples;
- int64_t audio_drift_step;
-
- int64_t av_offset;
-
scr_plugin_t* scr_master;
scr_plugin_t** scr_list;
pthread_t sync_thread;
+ int thread_running;
int scr_adjustable;
-
+
+ int speed;
+
pthread_mutex_t lock;
-
- int have_audio;
- int video_discontinuity_count;
- int audio_discontinuity_count;
- int discontinuity_handled_count;
- pthread_cond_t video_discontinuity_reached;
- pthread_cond_t audio_discontinuity_reached;
pthread_cond_t cancel;
- int force_video_jump;
- int force_audio_jump;
-
- int64_t img_duration;
- int img_cpt;
- int64_t last_video_pts;
-
};
-metronom_t *metronom_init (int have_audio, xine_stream_t *stream);
+metronom_clock_t *metronom_clock_init(void);
/*
- * metronom options
+ * clock options
*/
-#define METRONOM_SCR_ADJUSTABLE 1
-#define METRONOM_AV_OFFSET 2
-#define METRONOM_ADJ_VPTS_OFFSET 3
+#define CLOCK_SCR_ADJUSTABLE 1
/*
* SCR (system clock reference) plugins
@@ -287,7 +315,7 @@ struct scr_plugin_s
void (*exit) (scr_plugin_t *this);
- metronom_t *metronom;
+ metronom_clock_t *clock;
};
#ifdef __cplusplus
diff --git a/src/xine-engine/video_decoder.h b/src/xine-engine/video_decoder.h
index 022371128..b58f0008b 100644
--- a/src/xine-engine/video_decoder.h
+++ b/src/xine-engine/video_decoder.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_decoder.h,v 1.6 2002/11/12 18:40:55 miguelfreitas Exp $
+ * $Id: video_decoder.h,v 1.7 2002/11/20 11:57:49 mroi Exp $
*
* xine video decoder plugin interface
*
@@ -29,7 +29,7 @@
#include <inttypes.h>
#include "buffer.h"
-#define VIDEO_DECODER_IFACE_VERSION 12
+#define VIDEO_DECODER_IFACE_VERSION 13
/*
* generic xine video decoder plugin interface
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index a4a3079ec..34b0be478 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.111 2002/11/10 13:18:01 mroi Exp $
+ * $Id: video_out.c,v 1.112 2002/11/20 11:57:49 mroi Exp $
*
* frame allocation / queuing / scheduling / output functions
*/
@@ -49,12 +49,13 @@
typedef struct {
- vo_instance_t vo; /* public part */
+ xine_video_port_t vo; /* public part */
- xine_vo_driver_t *driver;
- metronom_t *metronom;
+ vo_driver_t *driver;
xine_t *xine;
- xine_stream_t *stream;
+ metronom_clock_t *clock;
+ xine_list_t *streams;
+ pthread_mutex_t streams_lock;
img_buf_fifo_t *free_img_buf_queue;
img_buf_fifo_t *display_img_buf_queue;
@@ -191,7 +192,7 @@ static void vo_frame_dec_lock (vo_frame_t *img) {
img->lock_counter--;
if (!img->lock_counter) {
- vos_t *this = (vos_t *) img->instance;
+ vos_t *this = (vos_t *) img->port;
vo_append_to_img_buf_queue (this->free_img_buf_queue, img);
}
@@ -211,7 +212,7 @@ static void vo_frame_dec_lock (vo_frame_t *img) {
*
*/
-static vo_frame_t *vo_get_frame (vo_instance_t *this_gen,
+static vo_frame_t *vo_get_frame (xine_video_port_t *this_gen,
uint32_t width, uint32_t height,
int ratio, int format,
int flags) {
@@ -250,19 +251,19 @@ static vo_frame_t *vo_get_frame (vo_instance_t *this_gen,
return img;
}
-static int vo_frame_draw (vo_frame_t *img) {
+static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) {
- vos_t *this = (vos_t *) img->instance;
+ vos_t *this = (vos_t *) img->port;
int64_t diff;
int64_t cur_vpts;
int64_t pic_vpts ;
int frames_to_skip;
- this->metronom->got_video_frame (this->metronom, img);
+ stream->metronom->got_video_frame (stream->metronom, img);
pic_vpts = img->vpts;
- cur_vpts = this->metronom->get_current_time(this->metronom);
+ cur_vpts = this->clock->get_current_time(this->clock);
this->last_delivery_pts = cur_vpts;
#ifdef LOG
@@ -293,12 +294,12 @@ static int vo_frame_draw (vo_frame_t *img) {
/*
* Wake up xine_play if it's waiting for a frame
*/
- pthread_mutex_lock (&this->stream->first_frame_lock);
- if (this->stream->first_frame_flag) {
- this->stream->first_frame_flag = 0;
- pthread_cond_broadcast(&this->stream->first_frame_reached);
+ pthread_mutex_lock (&stream->first_frame_lock);
+ if (stream->first_frame_flag) {
+ stream->first_frame_flag = 0;
+ pthread_cond_broadcast(&stream->first_frame_reached);
}
- pthread_mutex_unlock (&this->stream->first_frame_lock);
+ pthread_mutex_unlock (&stream->first_frame_lock);
/*
* put frame into FIFO-Buffer
@@ -578,12 +579,13 @@ static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts) {
* last frame? make backup for possible still image
*/
pthread_mutex_lock( &this->free_img_buf_queue->mutex );
- if (img && !img->next &&
+ if (img && !img->next /* FIXME: is this test needed? &&
(this->stream->video_fifo->size(this->stream->video_fifo) < 10
- || this->stream->video_in_discontinuity) ) {
+ || this->stream->video_in_discontinuity)*/ ) {
- printf ("video_out: possible still frame (fifosize = %d)\n",
- this->stream->video_fifo->size(this->stream->video_fifo));
+ /*printf ("video_out: possible still frame (fifosize = %d)\n",
+ this->stream->video_fifo->size(this->stream->video_fifo));*/
+ printf ("video_out: possible still frame\n");
this->img_backup = duplicate_frame (this, img);
}
@@ -607,7 +609,7 @@ static void overlay_and_display_frame (vos_t *this,
printf ("video_out: displaying image with vpts = %lld\n",
img->vpts);
#endif
-
+
if (this->overlay_source) {
this->overlay_source->multiple_overlay_blend (this->overlay_source,
vpts,
@@ -650,7 +652,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->stream->speed == XINE_SPEED_PAUSE) {
+ while (this->clock->speed == XINE_SPEED_PAUSE) {
/* we need at least one free frame to keep going */
if( this->display_img_buf_queue->first &&
@@ -704,7 +706,7 @@ static void *video_out_loop (void *this_gen) {
*/
frame_duration = 1500; /* default */
- next_frame_vpts = this->metronom->get_current_time (this->metronom);
+ next_frame_vpts = this->clock->get_current_time (this->clock);
#ifdef LOG
printf ("video_out: loop starting...\n");
@@ -716,7 +718,7 @@ static void *video_out_loop (void *this_gen) {
* get current time and find frame to display
*/
- vpts = this->metronom->get_current_time (this->metronom);
+ vpts = this->clock->get_current_time (this->clock);
#ifdef LOG
printf ("video_out: loop iteration at %lld\n", vpts);
#endif
@@ -746,16 +748,23 @@ 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->stream->video_decoder_plugin) {
+ xine_stream_t *stream;
+
+ pthread_mutex_lock(&this->streams_lock);
+ for (stream = xine_list_first_content(this->streams); stream;
+ stream = xine_list_next_content(this->streams)) {
+ if (stream->video_decoder_plugin) {
#ifdef LOG
- printf ("video_out: flushing current video decoder plugin (%d %d)\n",
- this->display_img_buf_queue->num_buffers,
- this->free_img_buf_queue->num_buffers);
+ printf ("video_out: flushing current video decoder plugin (%d %d)\n",
+ this->display_img_buf_queue->num_buffers,
+ this->free_img_buf_queue->num_buffers);
#endif
- this->stream->video_decoder_plugin->flush(this->stream->video_decoder_plugin);
+ stream->video_decoder_plugin->flush(stream->video_decoder_plugin);
+ }
}
+ pthread_mutex_unlock(&this->streams_lock);
this->last_delivery_pts = vpts;
}
@@ -775,9 +784,9 @@ static void *video_out_loop (void *this_gen) {
#endif
do {
- vpts = this->metronom->get_current_time (this->metronom);
+ vpts = this->clock->get_current_time (this->clock);
- if (this->stream->speed == XINE_SPEED_PAUSE)
+ if (this->clock->speed == XINE_SPEED_PAUSE)
paused_loop (this, vpts);
usec_to_sleep = (next_frame_vpts - vpts) * 100 / 9;
@@ -825,31 +834,48 @@ static void *video_out_loop (void *this_gen) {
pthread_exit(NULL);
}
-static uint32_t vo_get_capabilities (vo_instance_t *this_gen) {
+static uint32_t vo_get_capabilities (xine_video_port_t *this_gen) {
vos_t *this = (vos_t *) this_gen;
return this->driver->get_capabilities (this->driver);
}
-static void vo_open (vo_instance_t *this_gen) {
+static void vo_open (xine_video_port_t *this_gen, xine_stream_t *stream) {
vos_t *this = (vos_t *) this_gen;
this->video_opened = 1;
this->last_delivery_pts = 0;
+ if (!this->overlay_enabled && stream->spu_channel_user > -2)
+ /* enable overlays if our new stream might want to show some */
+ this->overlay_enabled = 1;
+ pthread_mutex_lock(&this->streams_lock);
+ xine_list_append_content(this->streams, stream);
+ pthread_mutex_unlock(&this->streams_lock);
}
-static void vo_close (vo_instance_t *this_gen) {
+static void vo_close (xine_video_port_t *this_gen, xine_stream_t *stream) {
- vos_t *this = (vos_t *) this_gen;
+ vos_t *this = (vos_t *) this_gen;
+ xine_stream_t *cur;
/* this will make sure all hide events were processed */
if (this->overlay_source)
this->overlay_source->flush_events (this->overlay_source);
this->video_opened = 0;
+
+ /* unregister stream */
+ pthread_mutex_lock(&this->streams_lock);
+ for (cur = xine_list_first_content(this->streams); cur;
+ cur = xine_list_next_content(this->streams))
+ if (cur == stream) {
+ xine_list_delete_current(this->streams);
+ break;
+ }
+ pthread_mutex_unlock(&this->streams_lock);
}
-static void vo_free_img_buffers (vo_instance_t *this_gen) {
+static void vo_free_img_buffers (xine_video_port_t *this_gen) {
vos_t *this = (vos_t *) this_gen;
vo_frame_t *img;
@@ -864,7 +890,7 @@ static void vo_free_img_buffers (vo_instance_t *this_gen) {
}
}
-static void vo_exit (vo_instance_t *this_gen) {
+static void vo_exit (xine_video_port_t *this_gen) {
vos_t *this = (vos_t *) this_gen;
@@ -891,6 +917,9 @@ static void vo_exit (vo_instance_t *this_gen) {
if (this->overlay_source) {
this->overlay_source->dispose (this->overlay_source);
}
+
+ xine_list_free(this->streams);
+ pthread_mutex_destroy(&this->streams_lock);
free (this->free_img_buf_queue);
free (this->display_img_buf_queue);
@@ -898,7 +927,7 @@ static void vo_exit (vo_instance_t *this_gen) {
free (this);
}
-static vo_frame_t *vo_get_last_frame (vo_instance_t *this_gen) {
+static vo_frame_t *vo_get_last_frame (xine_video_port_t *this_gen) {
vos_t *this = (vos_t *) this_gen;
return this->last_frame;
}
@@ -907,20 +936,37 @@ static vo_frame_t *vo_get_last_frame (vo_instance_t *this_gen) {
* overlay stuff
*/
-static video_overlay_instance_t *vo_get_overlay_instance (vo_instance_t *this_gen) {
+static video_overlay_instance_t *vo_get_overlay_instance (xine_video_port_t *this_gen) {
vos_t *this = (vos_t *) this_gen;
return this->overlay_source;
}
-static void vo_enable_overlay (vo_instance_t *this_gen, int overlay_enabled) {
+static void vo_enable_overlay (xine_video_port_t *this_gen, int overlay_enabled) {
vos_t *this = (vos_t *) this_gen;
- this->overlay_enabled = overlay_enabled;
+
+ if (overlay_enabled) {
+ /* we always ENable ... */
+ this->overlay_enabled = 1;
+ } else {
+ /* ... but we only actually DISable, if all associated streams have SPU off */
+ xine_stream_t *stream;
+ pthread_mutex_lock(&this->streams_lock);
+ for (stream = xine_list_first_content(this->streams) ; stream ;
+ stream = xine_list_next_content(this->streams)) {
+ if (stream->spu_channel_user > -2) {
+ pthread_mutex_unlock(&this->streams_lock);
+ return;
+ }
+ }
+ pthread_mutex_unlock(&this->streams_lock);
+ this->overlay_enabled = 0;
+ }
}
/*
* Flush video_out fifo
*/
-static void vo_flush (vo_instance_t *this_gen) {
+static void vo_flush (xine_video_port_t *this_gen) {
vos_t *this = (vos_t *) this_gen;
vo_frame_t *img;
int i, num_buffers;
@@ -938,8 +984,7 @@ static void vo_flush (vo_instance_t *this_gen) {
}
-vo_instance_t *vo_new_instance (xine_vo_driver_t *driver,
- xine_stream_t *stream) {
+xine_video_port_t *vo_new_port (xine_t *xine, vo_driver_t *driver) {
vos_t *this;
int i;
@@ -950,10 +995,12 @@ vo_instance_t *vo_new_instance (xine_vo_driver_t *driver,
this = xine_xmalloc (sizeof (vos_t)) ;
+ this->xine = xine;
+ this->clock = xine->clock;
this->driver = driver;
- this->xine = stream->xine;
- this->metronom = stream->metronom;
- this->stream = stream;
+ this->streams = xine_list_new();
+
+ pthread_mutex_init(&this->streams_lock, NULL);
this->vo.open = vo_open;
this->vo.get_frame = vo_get_frame;
@@ -964,6 +1011,7 @@ vo_instance_t *vo_new_instance (xine_vo_driver_t *driver,
this->vo.enable_ovl = vo_enable_overlay;
this->vo.get_overlay_instance = vo_get_overlay_instance;
this->vo.flush = vo_flush;
+ this->vo.driver = driver;
this->num_frames_delivered = 0;
this->num_frames_skipped = 0;
@@ -993,7 +1041,7 @@ vo_instance_t *vo_new_instance (xine_vo_driver_t *driver,
img->id = i;
- img->instance = &this->vo;
+ img->port = &this->vo;
img->free = vo_frame_dec_lock;
img->displayed = vo_frame_dec_lock;
img->draw = vo_frame_draw;
@@ -1013,7 +1061,7 @@ vo_instance_t *vo_new_instance (xine_vo_driver_t *driver,
this->video_loop_running = 1;
this->video_opened = 0;
-
+
pthread_attr_init(&pth_attrs);
pthread_attr_setscope(&pth_attrs, PTHREAD_SCOPE_SYSTEM);
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index 275fcd0d0..e011b2788 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.69 2002/10/29 16:02:50 mroi Exp $
+ * $Id: video_out.h,v 1.70 2002/11/20 11:57:49 mroi Exp $
*
*
* xine version of video_out.h
@@ -27,7 +27,7 @@
*
* vo_driver : lowlevel, platform-specific video output code
*
- * vo_instance : generic frame_handling code, uses
+ * vo_port : generic frame_handling code, uses
* a vo_driver for output
*
*/
@@ -47,11 +47,10 @@ extern "C" {
#include <pthread.h>
typedef struct vo_frame_s vo_frame_t;
-typedef struct vo_instance_s vo_instance_t;
typedef struct img_buf_fifo_s img_buf_fifo_t;
typedef struct vo_overlay_s vo_overlay_t;
typedef struct video_overlay_instance_s video_overlay_instance_t;
-typedef struct vo_private_s vo_private_t;
+typedef struct vo_driver_s vo_driver_t;
/* public part, video drivers may add private fields */
@@ -87,8 +86,8 @@ struct vo_frame_s {
pthread_mutex_t mutex; /* protect access to lock_count */
/* "backward" references to where this frame originates from */
- vo_instance_t *instance;
- xine_vo_driver_t *driver;
+ xine_video_port_t *port;
+ vo_driver_t *driver;
int id; /* debugging - track this frame */
@@ -107,7 +106,7 @@ struct vo_frame_s {
/* append this frame to the display queue,
returns number of frames to skip if decoder is late */
- int (*draw) (vo_frame_t *vo_img);
+ int (*draw) (vo_frame_t *vo_img, xine_stream_t *stream);
/* this frame is no longer used by the video driver */
void (*displayed) (vo_frame_t *vo_img);
@@ -116,12 +115,12 @@ struct vo_frame_s {
void (*dispose) (vo_frame_t *vo_img);
};
-struct vo_instance_s {
+struct xine_video_port_s {
- uint32_t (*get_capabilities) (vo_instance_t *this); /* for constants see below */
+ uint32_t (*get_capabilities) (xine_video_port_t *this); /* for constants see below */
/* open display driver for video output */
- void (*open) (vo_instance_t *this);
+ void (*open) (xine_video_port_t *this, xine_stream_t *stream);
/*
* get_frame - allocate an image buffer from display driver
@@ -132,29 +131,32 @@ struct vo_instance_s {
* format == FOURCC descriptor of image format
* flags == field/prediction flags
*/
- vo_frame_t* (*get_frame) (vo_instance_t *this, uint32_t width,
+ vo_frame_t* (*get_frame) (xine_video_port_t *this, uint32_t width,
uint32_t height, int ratio_code,
int format, int flags);
- vo_frame_t* (*get_last_frame) (vo_instance_t *this);
+ vo_frame_t* (*get_last_frame) (xine_video_port_t *this);
/* overlay stuff */
- void (*enable_ovl) (vo_instance_t *this, int ovl_enable);
+ void (*enable_ovl) (xine_video_port_t *this, int ovl_enable);
/* video driver is no longer used by decoder => close */
- void (*close) (vo_instance_t *this);
+ void (*close) (xine_video_port_t *this, xine_stream_t *stream);
/* called on xine exit */
- void (*exit) (vo_instance_t *this);
+ void (*exit) (xine_video_port_t *this);
/* get overlay instance (overlay source) */
- video_overlay_instance_t* (*get_overlay_instance) (vo_instance_t *this);
+ video_overlay_instance_t* (*get_overlay_instance) (xine_video_port_t *this);
/* flush video_out fifo */
- void (*flush) (vo_instance_t *this);
+ void (*flush) (xine_video_port_t *this);
- /* private stuff can be added here */
+ /* the driver in use */
+ vo_driver_t *driver;
+ /* private stuff can be added here */
+
};
/* constants for the get/set property functions */
@@ -224,37 +226,37 @@ struct vo_instance_s {
#define VO_CAP_AUTOPAINT_COLORKEY 0x00000200 /* driver can set AUTOPAINT_COLORKEY value */
/*
- * xine_vo_driver_s contains the functions every display driver
- * has to implement. The vo_new_instance function (see below)
- * should then be used to construct a vo_instance using this
+ * vo_driver_s contains the functions every display driver
+ * has to implement. The vo_new_port function (see below)
+ * should then be used to construct a vo_port using this
* driver. Some of the function pointers will be copied
- * directly into vo_instance_s, others will be called
+ * directly into xine_video_port_s, others will be called
* from generic vo functions.
*/
-#define VIDEO_OUT_DRIVER_IFACE_VERSION 10
+#define VIDEO_OUT_DRIVER_IFACE_VERSION 11
-struct xine_vo_driver_s {
+struct vo_driver_s {
- uint32_t (*get_capabilities) (xine_vo_driver_t *this); /* for constants see above */
+ uint32_t (*get_capabilities) (vo_driver_t *this); /* for constants see above */
/*
* allocate an vo_frame_t struct,
* the driver must supply the copy, field and dispose functions
*/
- vo_frame_t* (*alloc_frame) (xine_vo_driver_t *this);
+ vo_frame_t* (*alloc_frame) (vo_driver_t *this);
/*
* check if the given image fullfills the format specified
* (re-)allocate memory if necessary
*/
- void (*update_frame_format) (xine_vo_driver_t *this, vo_frame_t *img,
+ void (*update_frame_format) (vo_driver_t *this, vo_frame_t *img,
uint32_t width, uint32_t height,
int ratio_code, int format, int flags);
/* display a given frame */
- void (*display_frame) (xine_vo_driver_t *this, vo_frame_t *vo_img);
+ void (*display_frame) (vo_driver_t *this, vo_frame_t *vo_img);
/* overlay_begin and overlay_end are used by drivers suporting
* persistent overlays. they can be optimized to update only when
@@ -268,18 +270,18 @@ struct xine_vo_driver_s {
*
* any function pointer from this group may be set to NULL.
*/
- void (*overlay_begin) (xine_vo_driver_t *this, vo_frame_t *vo_img, int changed);
- void (*overlay_blend) (xine_vo_driver_t *this, vo_frame_t *vo_img, vo_overlay_t *overlay);
- void (*overlay_end) (xine_vo_driver_t *this, vo_frame_t *vo_img);
+ void (*overlay_begin) (vo_driver_t *this, vo_frame_t *vo_img, int changed);
+ void (*overlay_blend) (vo_driver_t *this, vo_frame_t *vo_img, vo_overlay_t *overlay);
+ void (*overlay_end) (vo_driver_t *this, vo_frame_t *vo_img);
/*
* these can be used by the gui directly:
*/
- int (*get_property) (xine_vo_driver_t *this, int property);
- int (*set_property) (xine_vo_driver_t *this,
+ int (*get_property) (vo_driver_t *this, int property);
+ int (*set_property) (vo_driver_t *this,
int property, int value);
- void (*get_property_min_max) (xine_vo_driver_t *this,
+ void (*get_property_min_max) (vo_driver_t *this,
int property, int *min, int *max);
/*
@@ -289,20 +291,20 @@ struct xine_vo_driver_s {
* etc. to the driver
*/
- int (*gui_data_exchange) (xine_vo_driver_t *this, int data_type,
+ int (*gui_data_exchange) (vo_driver_t *this, int data_type,
void *data);
/* check if a redraw is needed (due to resize)
* this is only used for still frames, normal video playback
* must call that inside display_frame() function.
*/
- int (*redraw_needed) (xine_vo_driver_t *this);
+ int (*redraw_needed) (vo_driver_t *this);
/*
* free all resources, close driver
*/
- void (*dispose) (xine_vo_driver_t *this);
+ void (*dispose) (vo_driver_t *this);
void *node; /* needed by plugin_loader */
};
@@ -314,7 +316,7 @@ struct video_driver_class_s {
/*
* open a new instance of this plugin class
*/
- xine_vo_driver_t* (*open_plugin) (video_driver_class_t *this, const void *visual);
+ vo_driver_t* (*open_plugin) (video_driver_class_t *this, const void *visual);
/*
* return short, human readable identifier for this plugin class
@@ -382,19 +384,18 @@ struct video_overlay_instance_s {
int (*redraw_needed) (video_overlay_instance_t *this_gen, int64_t vpts );
void (*multiple_overlay_blend) (video_overlay_instance_t *this_gen, int64_t vpts,
- xine_vo_driver_t *output, vo_frame_t *vo_img, int enabled);
+ vo_driver_t *output, vo_frame_t *vo_img, int enabled);
};
video_overlay_instance_t *video_overlay_new_instance ();
/*
- * build a video_out_instance from
+ * build a video_out_port from
* a given video driver
*/
-vo_instance_t *vo_new_instance (xine_vo_driver_t *driver,
- xine_stream_t *stream) ;
+xine_video_port_t *vo_new_port (xine_t *xine, vo_driver_t *driver) ;
#ifdef __cplusplus
}
diff --git a/src/xine-engine/video_overlay.c b/src/xine-engine/video_overlay.c
index 56409e63a..fd51c4699 100644
--- a/src/xine-engine/video_overlay.c
+++ b/src/xine-engine/video_overlay.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_overlay.c,v 1.26 2002/11/19 00:45:42 miguelfreitas Exp $
+ * $Id: video_overlay.c,v 1.27 2002/11/20 11:57:49 mroi Exp $
*
*/
@@ -484,7 +484,7 @@ static int video_overlay_event( video_overlay_t *this, int64_t vpts ) {
* must call output->overlay_blend for each active overlay.
*/
static void video_overlay_multiple_overlay_blend (video_overlay_instance_t *this_gen, int64_t vpts,
- xine_vo_driver_t *output, vo_frame_t *vo_img, int enabled) {
+ vo_driver_t *output, vo_frame_t *vo_img, int enabled) {
video_overlay_t *this = (video_overlay_t *) this_gen;
int i;
int32_t handle;
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index 43bdc6b55..80c0f9686 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.193 2002/11/17 17:41:45 mroi Exp $
+ * $Id: xine.c,v 1.194 2002/11/20 11:57:49 mroi Exp $
*
* top-level xine functions
*
@@ -101,7 +101,7 @@ void xine_report_codec (xine_stream_t *stream, int codec_type,
static void xine_set_speed_internal (xine_stream_t *stream, int speed) {
- stream->metronom->set_speed (stream->metronom, speed);
+ stream->xine->clock->set_speed (stream->xine->clock, speed);
/* see coment on audio_out loop about audio_paused */
if( stream->audio_out ) {
@@ -118,8 +118,6 @@ static void xine_set_speed_internal (xine_stream_t *stream, int speed) {
stream->audio_out->control(stream->audio_out,
speed == XINE_SPEED_PAUSE ? AO_CTRL_PLAY_PAUSE : AO_CTRL_PLAY_RESUME);
}
-
- stream->speed = speed;
}
@@ -202,8 +200,8 @@ void xine_stop (xine_stream_t *stream) {
* 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 );
+ stream->xine->clock->adjust_clock (stream->xine->clock,
+ stream->xine->clock->get_current_time(stream->xine->clock) + 30 * 90000 );
pthread_mutex_unlock (&stream->frontend_lock);
}
@@ -256,7 +254,7 @@ void xine_close (xine_stream_t *stream) {
xine_stream_t *xine_stream_new (xine_t *this,
- xine_ao_driver_t *ao, xine_vo_driver_t *vo) {
+ xine_audio_port_t *ao, xine_video_port_t *vo) {
xine_stream_t *stream;
int i;
@@ -277,13 +275,13 @@ xine_stream_t *xine_stream_new (xine_t *this,
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->spu_decoder_streamtype = -1;
+ stream->audio_out = ao;
stream->audio_channel_user = -1;
stream->audio_channel_auto = 0;
stream->audio_decoder_plugin = NULL;
@@ -293,7 +291,8 @@ xine_stream_t *xine_stream_new (xine_t *this,
stream->spu_channel_pan_scan = -1;
stream->spu_channel_user = -1;
stream->spu_channel = -1;
- stream->video_driver = vo;
+ stream->video_out = vo;
+ stream->video_driver = vo->driver;
stream->video_in_discontinuity = 0;
stream->video_channel = 0;
stream->video_decoder_plugin = NULL;
@@ -333,11 +332,8 @@ xine_stream_t *xine_stream_new (xine_t *this,
* alloc fifos, init and start decoder threads
*/
- stream->video_out = vo_new_instance (vo, stream);
video_decoder_init (stream);
- if (ao)
- stream->audio_out = ao_new_instance (ao, stream);
audio_decoder_init (stream);
/*
@@ -347,12 +343,6 @@ xine_stream_t *xine_stream_new (xine_t *this,
stream->osd_renderer = osd_renderer_init (stream->video_out->get_overlay_instance (stream->video_out), stream->xine->config );
/*
- * start metronom clock
- */
-
- stream->metronom->start_clock (stream->metronom, 0);
-
- /*
* register stream
*/
@@ -685,7 +675,7 @@ static int xine_play_internal (xine_stream_t *stream, int start_pos, int start_t
printf ("xine: xine_play\n");
- if (stream->speed != XINE_SPEED_NORMAL)
+ if (stream->xine->clock->speed != XINE_SPEED_NORMAL)
xine_set_speed_internal (stream, XINE_SPEED_NORMAL);
/* Wait until the first frame produced by the previous
@@ -821,6 +811,7 @@ void xine_exit (xine_t *this) {
this->log_buffers[i]->dispose (this->log_buffers[i]);
dispose_plugins (this);
+ this->clock->exit (this->clock);
this->config->dispose(this->config);
free (this);
@@ -902,6 +893,14 @@ void xine_init (xine_t *this) {
this->streams = xine_list_new();
pthread_mutex_init (&this->streams_lock, NULL);
+
+ /*
+ * start metronom clock
+ */
+
+ this->clock = metronom_clock_init();
+
+ this->clock->start_clock (this->clock, 0);
}
@@ -976,7 +975,7 @@ void xine_set_speed (xine_stream_t *stream, int speed) {
int xine_get_speed (xine_stream_t *stream) {
- return stream->speed;
+ return stream->xine->clock->speed;
}
/*
diff --git a/src/xine-engine/xine_interface.c b/src/xine-engine/xine_interface.c
index 440206898..439bc97cc 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.29 2002/11/11 04:57:18 tmmm Exp $
+ * $Id: xine_interface.c,v 1.30 2002/11/20 11:57:50 mroi Exp $
*
* convenience/abstraction layer, functions to implement
* libxine's public interface
@@ -397,7 +397,7 @@ int xine_get_param (xine_stream_t *stream, int param) {
switch (param) {
case XINE_PARAM_SPEED:
- return stream->speed;
+ return stream->xine->clock->speed;
case XINE_PARAM_AV_OFFSET:
return stream->metronom->get_option (stream->metronom, METRONOM_AV_OFFSET);
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index 1d02136ad..013bff436 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.112 2002/11/17 17:41:45 mroi Exp $
+ * $Id: xine_internal.h,v 1.113 2002/11/20 11:57:50 mroi Exp $
*
*/
@@ -108,6 +108,8 @@ struct xine_s {
xine_list_t *streams;
pthread_mutex_t streams_lock;
+
+ metronom_clock_t *clock;
};
/*
@@ -140,13 +142,12 @@ struct xine_stream_s {
demux_plugin_t *demux_plugin;
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;
+ xine_video_port_t *video_out;
+ vo_driver_t *video_driver;
fifo_buffer_t *video_fifo;
pthread_t video_thread;
video_decoder_t *video_decoder_plugin;
@@ -154,7 +155,7 @@ struct xine_stream_s {
int video_in_discontinuity;
int video_channel;
- ao_instance_t *audio_out;
+ xine_audio_port_t *audio_out;
fifo_buffer_t *audio_fifo;
lrb_t *audio_temp;
pthread_t audio_thread;
@@ -273,8 +274,8 @@ void free_spu_decoder (xine_stream_t *stream, spu_decoder_t *decod
* load a specific video output plugin
*/
-xine_vo_driver_t *xine_load_video_output_plugin(xine_t *this,
- char *id, int visual_type, void *visual);
+vo_driver_t *xine_load_video_output_plugin(xine_t *this,
+ char *id, int visual_type, void *visual);
/*
* audio output plugin dynamic loading stuff
@@ -286,7 +287,7 @@ xine_vo_driver_t *xine_load_video_output_plugin(xine_t *this,
* load a specific audio output plugin
*/
-xine_ao_driver_t *xine_load_audio_output_plugin (xine_t *self, char *id);
+ao_driver_t *xine_load_audio_output_plugin (xine_t *self, char *id);
void xine_set_speed (xine_stream_t *stream, int speed) ;