diff options
author | Michael Roitzsch <mroi@users.sourceforge.net> | 2002-11-20 11:57:38 +0000 |
---|---|---|
committer | Michael Roitzsch <mroi@users.sourceforge.net> | 2002-11-20 11:57:38 +0000 |
commit | 4e95a4f5224e241075b8cd86b4423c85c1d0ee26 (patch) | |
tree | cd9287e15591dce94560663ad66fc4005d006012 /src/xine-engine | |
parent | 74893748b868ecc6ae539fa66e326e06947c4ac9 (diff) | |
download | xine-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.h | 4 | ||||
-rw-r--r-- | src/xine-engine/audio_out.c | 147 | ||||
-rw-r--r-- | src/xine-engine/audio_out.h | 76 | ||||
-rw-r--r-- | src/xine-engine/demux.c | 4 | ||||
-rw-r--r-- | src/xine-engine/load_plugins.c | 42 | ||||
-rw-r--r-- | src/xine-engine/metronom.c | 133 | ||||
-rw-r--r-- | src/xine-engine/metronom.h | 142 | ||||
-rw-r--r-- | src/xine-engine/video_decoder.h | 4 | ||||
-rw-r--r-- | src/xine-engine/video_out.c | 146 | ||||
-rw-r--r-- | src/xine-engine/video_out.h | 85 | ||||
-rw-r--r-- | src/xine-engine/video_overlay.c | 4 | ||||
-rw-r--r-- | src/xine-engine/xine.c | 39 | ||||
-rw-r--r-- | src/xine-engine/xine_interface.c | 4 | ||||
-rw-r--r-- | src/xine-engine/xine_internal.h | 17 |
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) ; |