diff options
Diffstat (limited to 'src/xine-engine')
-rw-r--r-- | src/xine-engine/Makefile.am | 4 | ||||
-rw-r--r-- | src/xine-engine/audio_decoder.c | 20 | ||||
-rw-r--r-- | src/xine-engine/audio_out.c | 18 | ||||
-rw-r--r-- | src/xine-engine/audio_out.h | 48 | ||||
-rw-r--r-- | src/xine-engine/configfile.c | 392 | ||||
-rw-r--r-- | src/xine-engine/configfile.h | 113 | ||||
-rw-r--r-- | src/xine-engine/events.c | 8 | ||||
-rw-r--r-- | src/xine-engine/load_plugins.c | 1437 | ||||
-rw-r--r-- | src/xine-engine/metronom.c | 12 | ||||
-rw-r--r-- | src/xine-engine/osd.c | 9 | ||||
-rw-r--r-- | src/xine-engine/plugin_catalog.h | 71 | ||||
-rw-r--r-- | src/xine-engine/tvmode.c | 650 | ||||
-rw-r--r-- | src/xine-engine/video_decoder.c | 7 | ||||
-rw-r--r-- | src/xine-engine/video_out.c | 80 | ||||
-rw-r--r-- | src/xine-engine/video_out.h | 77 | ||||
-rw-r--r-- | src/xine-engine/video_overlay.c | 11 | ||||
-rw-r--r-- | src/xine-engine/vo_scale.c | 52 | ||||
-rw-r--r-- | src/xine-engine/vo_scale.h | 14 | ||||
-rw-r--r-- | src/xine-engine/xine.c | 536 | ||||
-rw-r--r-- | src/xine-engine/xine_interface.c | 318 | ||||
-rw-r--r-- | src/xine-engine/xine_internal.h | 461 | ||||
-rw-r--r-- | src/xine-engine/xine_plugin.h | 68 |
22 files changed, 1904 insertions, 2502 deletions
diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am index b7d7174a4..dbb8e8aec 100644 --- a/src/xine-engine/Makefile.am +++ b/src/xine-engine/Makefile.am @@ -14,7 +14,7 @@ endif libxine_la_SOURCES = $(nvtv) xine.c metronom.c configfile.c buffer.c \ load_plugins.c video_decoder.c buffer_types.c \ audio_decoder.c video_out.c audio_out.c resample.c events.c lrb.c \ - video_overlay.c osd.c scratch.c locale.c demux.c vo_scale.c + video_overlay.c osd.c scratch.c locale.c demux.c vo_scale.c xine_interface.c libxine_la_DEPENDENCIES = @INTLLIBS@ libxine_la_LIBADD = $(THREAD_LIBS) $(DYNAMIC_LD_LIBS) @INTLLIBS@ $(ZLIB_LIBS) -lm @@ -23,7 +23,7 @@ libxine_la_LDFLAGS = \ include_HEADERS = buffer.h metronom.h configfile.h vo_scale.h \ audio_out.h resample.h video_out.h xine_internal.h spu_decoder.h \ - events.h lrb.h video_overlay.h osd.h scratch.h xineintl.h + lrb.h video_overlay.h osd.h scratch.h xineintl.h noinst_HEADERS = bswap.h nvtvd.h diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c index b40675912..cabd18b03 100644 --- a/src/xine-engine/audio_decoder.c +++ b/src/xine-engine/audio_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_decoder.c,v 1.82 2002/07/26 14:51:23 mroi Exp $ + * $Id: audio_decoder.c,v 1.83 2002/09/04 23:31:13 guenter Exp $ * * * functions that implement audio decoding @@ -234,7 +234,7 @@ void *audio_decoder_loop (void *this_gen) { int streamtype = (buf->type>>16) & 0xFF; - decoder = this->audio_decoder_plugins [streamtype]; + decoder = get_audio_decoder (this, streamtype); /* close old decoder of audio type has changed */ @@ -362,19 +362,3 @@ int xine_get_audio_channel (xine_t *this) { return this->audio_type & 0xFFFF; } -void xine_select_audio_channel (xine_t *this, int channel) { - - pthread_mutex_lock (&this->xine_lock); - - if (channel < -2) - channel = -2; - - this->audio_channel_user = channel; - - pthread_mutex_unlock (&this->xine_lock); -} - -int xine_get_audio_selection (xine_t *this) { - - return this->audio_channel_user; -} diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index bfba30d6e..89ac7afde 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.63 2002/08/09 22:07:29 mroi Exp $ + * $Id: audio_out.c,v 1.64 2002/09/04 23:31:13 guenter Exp $ * * 22-8-2001 James imported some useful AC3 sections from the previous alsa driver. * (c) 2001 Andy Lo A Foe <andy@alsaplayer.org> @@ -704,10 +704,6 @@ static void ao_exit(ao_instance_t *this) { vol = this->driver->get_property(this->driver, prop); this->xine->config->update_num(this->xine->config, "audio.mixer_volume", vol); - - /* Save config is needed, otherwise value change will be lost */ - this->xine->config->save(this->xine->config); - this->driver->exit(this->driver); pthread_mutex_unlock( &this->driver_lock ); @@ -792,7 +788,7 @@ static int ao_control (ao_instance_t *this, int cmd, ...) { return rval; } -ao_instance_t *ao_new_instance (ao_driver_t *driver, xine_t *xine) { +ao_instance_t *ao_new_instance (xine_ao_driver_t *driver, xine_t *xine) { config_values_t *config = xine->config; ao_instance_t *this; @@ -823,16 +819,16 @@ ao_instance_t *ao_new_instance (ao_driver_t *driver, xine_t *xine) { this->resample_conf = config->register_enum (config, "audio.resample_mode", 0, resample_modes, _("adjust whether resampling is done or not"), - NULL, NULL, NULL); + NULL, 20, NULL, NULL); this->force_rate = config->register_num (config, "audio.force_rate", 0, _("if !=0 always resample to given rate"), - NULL, NULL, NULL); + NULL, 20, NULL, NULL); this->passthrough_offset = config->register_num (config, "audio.passthrough_offset", 10000, _("adjust if audio is offsync"), - NULL, NULL, NULL); + NULL, 10, NULL, NULL); /* * pre-allocate memory for samples @@ -872,12 +868,12 @@ ao_instance_t *ao_new_instance (ao_driver_t *driver, xine_t *xine) { vol = config->register_range (config, "audio.mixer_volume", 50, 0, 100, _("Audio volume"), - NULL, NULL, NULL); + NULL, 0, NULL, NULL); if(config->register_bool (config, "audio.remember_volume", 0, _("restore volume level at startup"), _("if this not set, xine will not touch any mixer settings at startup"), - NULL, NULL)) { + 0, NULL, NULL)) { int prop = 0; if((ao_get_capabilities(this)) & AO_CAP_MIXER_VOL) diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h index b3aa50f85..a83e37f6b 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.32 2002/07/28 21:37:35 heikos Exp $ + * $Id: audio_out.h,v 1.33 2002/09/04 23:31:13 guenter Exp $ */ #ifndef HAVE_AUDIO_OUT_H #define HAVE_AUDIO_OUT_H @@ -44,9 +44,7 @@ extern "C" { * driver plugin has to implement. */ -typedef struct ao_driver_s ao_driver_t; - -struct ao_driver_s { +struct xine_ao_driver_s { /* * @@ -55,7 +53,7 @@ struct ao_driver_s { * * See AO_CAP_* bellow. */ - uint32_t (*get_capabilities) (ao_driver_t *this); + uint32_t (*get_capabilities) (xine_ao_driver_t *this); /* * open the driver and make it ready to receive audio data @@ -63,26 +61,26 @@ struct ao_driver_s { * * return value: 0 : failure, >0 : output sample rate */ - int (*open)(ao_driver_t *this, uint32_t bits, uint32_t rate, int mode); + int (*open)(xine_ao_driver_t *this, uint32_t bits, uint32_t rate, int mode); /* return the number of audio channels */ - int (*num_channels)(ao_driver_t *self_gen); + int (*num_channels)(xine_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)(ao_driver_t *self_gen); + int (*bytes_per_frame)(xine_ao_driver_t *self_gen); /* return the delay is frames measured by * looking at pending samples in the audio output device */ - int (*delay)(ao_driver_t *self_gen); + int (*delay)(xine_ao_driver_t *self_gen); /* * return gap tolerance (in pts) needed for this driver */ - int (*get_gap_tolerance) (ao_driver_t *self_gen); + int (*get_gap_tolerance) (xine_ao_driver_t *self_gen); /* * write audio data to output buffer @@ -92,20 +90,20 @@ struct ao_driver_s { * 0 => audio samples were not yet processed, * call write_audio_data with the _same_ samples again */ - int (*write)(ao_driver_t *this, + int (*write)(xine_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)(ao_driver_t *this); + void (*close)(xine_ao_driver_t *this); /* * shut down this audio output driver plugin and * free all resources allocated */ - void (*exit) (ao_driver_t *this); + void (*exit) (xine_ao_driver_t *this); /* * Get, Set a property of audio driver. @@ -115,9 +113,9 @@ struct ao_driver_s { * * See AO_PROP_* below for available properties. */ - int (*get_property) (ao_driver_t *this, int property); + int (*get_property) (xine_ao_driver_t *this, int property); - int (*set_property) (ao_driver_t *this, int property, int value); + int (*set_property) (xine_ao_driver_t *this, int property, int value); /* @@ -125,7 +123,7 @@ struct ao_driver_s { * * See AO_CTRL_* below. */ - int (*control) (ao_driver_t *this, int cmd, /* arg */ ...); + int (*control) (xine_ao_driver_t *this, int cmd, /* arg */ ...); }; /* @@ -204,7 +202,7 @@ struct ao_instance_s { /* private stuff */ - ao_driver_t *driver; + xine_ao_driver_t *driver; pthread_mutex_t driver_lock; metronom_t *metronom; xine_t *xine; @@ -236,20 +234,16 @@ struct ao_instance_s { /* This initiates the audio_out sync routines * found in ./src/xine-engine/audio_out.c */ -ao_instance_t *ao_new_instance (ao_driver_t *driver, xine_t *xine) ; +ao_instance_t *ao_new_instance (xine_ao_driver_t *driver, xine_t *xine) ; /* * to build a dynamic audio output plugin, * you have to implement these driver: * * - * ao_driver_t *init_audio_out_plugin (config_values_t *config) + * xine_ao_driver_t *init_audio_out_plugin (config_values_t *config) * * init this plugin, check if device is available * - * ao_info_t *get_audio_out_plugin_info () - * - * peek at some (static) information about the plugin without initializing it - * */ /* @@ -288,14 +282,6 @@ ao_instance_t *ao_new_instance (ao_driver_t *driver, xine_t *xine) ; /* above that value audio frames are discarded */ #define AO_MAX_GAP 15000 -typedef struct ao_info_s { - - int interface_version; - char *id; - char *description; - int priority; -} ao_info_t ; - #ifdef __cplusplus } #endif diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c index 95f2864cd..618c596ff 100644 --- a/src/xine-engine/configfile.c +++ b/src/xine-engine/configfile.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2000-2001 the xine project + * Copyright (C) 2000-2002 the xine project * - * This file is part of xine, a unix video player. + * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,9 +17,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: configfile.c,v 1.23 2002/06/17 07:47:50 f1rmb Exp $ + * $Id: configfile.c,v 1.24 2002/09/04 23:31:13 guenter Exp $ * - * config file management - implementation + * config object (was: file) management - implementation * */ @@ -35,9 +35,10 @@ #include <assert.h> #include "configfile.h" #include "xineutils.h" +#include "xine_internal.h" /* -#define CONFIG_LOG +#define LOG */ @@ -59,7 +60,7 @@ static char *copy_string (char *str) { return cpy; } -static cfg_entry_t *config_file_add (config_values_t *this, char *key) { +static cfg_entry_t *xine_config_add (config_values_t *this, char *key) { cfg_entry_t *entry; @@ -78,7 +79,7 @@ static cfg_entry_t *config_file_add (config_values_t *this, char *key) { this->last = entry; -#ifdef CONFIG_LOG +#ifdef LOG printf ("configfile: add entry key=%s\n", key); #endif @@ -89,7 +90,7 @@ static cfg_entry_t *config_file_add (config_values_t *this, char *key) { * external interface */ -static cfg_entry_t *config_file_lookup_entry (config_values_t *this, char *key) { +static cfg_entry_t *_xine_config_lookup_entry (config_values_t *this, char *key) { cfg_entry_t *entry; entry = this->first; @@ -101,28 +102,29 @@ static cfg_entry_t *config_file_lookup_entry (config_values_t *this, char *key) } -static char *config_file_register_string (config_values_t *this, - char *key, char *def_value, - char *description, - char *help, - config_cb_t changed_cb, - void *cb_data) { +static char *_xine_config_register_string (config_values_t *this, + char *key, char *def_value, + char *description, + char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { cfg_entry_t *entry; assert (key); assert (def_value); -#ifdef CONFIG_LOG +#ifdef LOG printf ("configfile: registering %s\n", key); #endif /* make sure this entry exists, create it if not */ - entry = config_file_lookup_entry (this, key); + entry = _xine_config_lookup_entry (this, key); if (!entry) { - entry = config_file_add (this, key); + entry = xine_config_add (this, key); entry->unknown_value = copy_string(def_value); } @@ -156,33 +158,35 @@ static char *config_file_register_string (config_values_t *this, entry->str_default = copy_string(def_value); entry->description = description; entry->help = help; + entry->exp_level = exp_level; entry->callback = changed_cb; entry->callback_data = cb_data; return entry->str_value; } -static int config_file_register_num (config_values_t *this, - char *key, int def_value, - char *description, - char *help, - config_cb_t changed_cb, - void *cb_data) { +static int _xine_config_register_num (config_values_t *this, + char *key, int def_value, + char *description, + char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { cfg_entry_t *entry; assert (key); -#ifdef CONFIG_LOG +#ifdef LOG printf ("configfile: registering %s\n", key); #endif /* make sure this entry exists, create it if not */ - entry = config_file_lookup_entry (this, key); + entry = _xine_config_lookup_entry (this, key); if (!entry) { - entry = config_file_add (this, key); + entry = xine_config_add (this, key); entry->unknown_value = NULL; } @@ -209,33 +213,35 @@ static int config_file_register_num (config_values_t *this, entry->num_default = def_value; entry->description = description; entry->help = help; + entry->exp_level = exp_level; entry->callback = changed_cb; entry->callback_data = cb_data; return entry->num_value; } -static int config_file_register_bool (config_values_t *this, - char *key, int def_value, - char *description, - char *help, - config_cb_t changed_cb, - void *cb_data) { +static int _xine_config_register_bool (config_values_t *this, + char *key, int def_value, + char *description, + char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { cfg_entry_t *entry; assert (key); -#ifdef CONFIG_LOG +#ifdef LOG printf ("configfile: registering %s\n", key); #endif /* make sure this entry exists, create it if not */ - entry = config_file_lookup_entry (this, key); + entry = _xine_config_lookup_entry (this, key); if (!entry) { - entry = config_file_add (this, key); + entry = xine_config_add (this, key); entry->unknown_value = NULL; } @@ -262,33 +268,35 @@ static int config_file_register_bool (config_values_t *this, entry->num_default = def_value; entry->description = description; entry->help = help; + entry->exp_level = exp_level; entry->callback = changed_cb; entry->callback_data = cb_data; return entry->num_value; } -static int config_file_register_range (config_values_t *this, - char *key, int def_value, - int min, int max, - char *description, - char *help, - config_cb_t changed_cb, - void *cb_data) { +static int _xine_config_register_range (config_values_t *this, + char *key, int def_value, + int min, int max, + char *description, + char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { cfg_entry_t *entry; assert (key); -#ifdef CONFIG_LOG - printf ("configfile: registering %s\n", key); +#ifdef LOG + printf ("configfile: registering range %s\n", key); #endif /* make sure this entry exists, create it if not */ - entry = config_file_lookup_entry (this, key); + entry = _xine_config_lookup_entry (this, key); if (!entry) { - entry = config_file_add (this, key); + entry = xine_config_add (this, key); entry->unknown_value = NULL; } @@ -316,13 +324,14 @@ static int config_file_register_range (config_values_t *this, entry->range_max = max; entry->description = description; entry->help = help; + entry->exp_level = exp_level; entry->callback = changed_cb; entry->callback_data = cb_data; return entry->num_value; } -static int config_file_parse_enum (char *str, char **values) { +static int xine_config_parse_enum (char *str, char **values) { char **value; int i; @@ -333,7 +342,7 @@ static int config_file_parse_enum (char *str, char **values) { while (*value) { -#ifdef CONFIG_LOG +#ifdef LOG printf ("configfile: parse enum, >%s< ?= >%s<\n", *value, str); #endif @@ -345,7 +354,7 @@ static int config_file_parse_enum (char *str, char **values) { i++; } -#ifdef CONFIG_LOG +#ifdef LOG printf ("configfile: warning, >%s< is not a valid enum here, using 0\n", str); #endif @@ -353,28 +362,29 @@ static int config_file_parse_enum (char *str, char **values) { return 0; } -static int config_file_register_enum (config_values_t *this, - char *key, int def_value, - char **values, - char *description, - char *help, - config_cb_t changed_cb, - void *cb_data) { +static int _xine_config_register_enum (config_values_t *this, + char *key, int def_value, + char **values, + char *description, + char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { cfg_entry_t *entry; assert (key); assert (values); -#ifdef CONFIG_LOG - printf ("configfile: registering %s\n", key); +#ifdef LOG + printf ("configfile: registering enum %s\n", key); #endif /* make sure this entry exists, create it if not */ - entry = config_file_lookup_entry (this, key); + entry = _xine_config_lookup_entry (this, key); if (!entry) { - entry = config_file_add (this, key); + entry = xine_config_add (this, key); entry->unknown_value = NULL; } @@ -390,7 +400,7 @@ static int config_file_register_enum (config_values_t *this, entry->type = CONFIG_TYPE_ENUM; if (entry->unknown_value) - entry->num_value = config_file_parse_enum (entry->unknown_value, values); + entry->num_value = xine_config_parse_enum (entry->unknown_value, values); else entry->num_value = def_value; @@ -402,22 +412,28 @@ static int config_file_register_enum (config_values_t *this, entry->enum_values = values; entry->description = description; entry->help = help; + entry->exp_level = exp_level; entry->callback = changed_cb; entry->callback_data = cb_data; return entry->num_value; } -static void config_file_update_num (config_values_t *this, +static void xine_config_update_num (config_values_t *this, char *key, int value) { cfg_entry_t *entry; entry = this->lookup_entry (this, key); +#ifdef LOG + printf ("configfile: updating %s to %d\n", + key, value); +#endif + if (!entry) { -#ifdef CONFIG_LOG +#ifdef LOG printf ("configfile: WARNING! tried to update unknown key %s (to %d)\n", key, value); #endif @@ -434,15 +450,22 @@ static void config_file_update_num (config_values_t *this, entry->num_value = value; + /* FIXME if (entry->callback) entry->callback (entry->callback_data, entry); + */ } -static void config_file_update_string (config_values_t *this, +static void xine_config_update_string (config_values_t *this, char *key, char *value) { cfg_entry_t *entry; +#ifdef LOG + printf ("configfile: updating %s to %s\n", + key, value); +#endif + entry = this->lookup_entry (this, key); if (!entry) { @@ -465,20 +488,60 @@ static void config_file_update_string (config_values_t *this, entry->str_value = copy_string (value); } + /* FIXME if (entry->callback) entry->callback (entry->callback_data, entry); + */ } -static void config_file_save (config_values_t *this) { +/* + * load/save config data from/to afile (e.g. $HOME/.xine/config) + */ +void xine_load_config (xine_t *x, char *filename) { + + config_values_t *this = x->config; FILE *f_config; - char filename[1024]; - sprintf (filename, "%s/.xine", xine_get_homedir()); - mkdir (filename, 0755); +#ifdef LOG + printf ("configfile: reading from file '%s'\n", + filename); +#endif - sprintf (filename, "%s/.xine/config", xine_get_homedir()); + f_config = fopen (filename, "r"); + + if (f_config) { + + char line[1024]; + char *value; -#ifdef CONFIG_LOG + while (fgets (line, 1023, f_config)) { + line[strlen(line)-1]= (char) 0; /* eliminate lf */ + + if (line[0] == '#') + continue; + + if ((value = strchr (line, ':'))) { + + cfg_entry_t *entry; + + *value = (char) 0; + value++; + + entry = xine_config_add (this, line); + entry->unknown_value = copy_string (value); + } + } + + fclose (f_config); + } +} + +void xine_save_config (xine_t *x, char *filename) { + + config_values_t *this = x->config; + FILE *f_config; + +#ifdef LOG printf ("writing config file to %s\n", filename); #endif @@ -493,6 +556,11 @@ static void config_file_save (config_values_t *this) { entry = this->first; while (entry) { + +#ifdef LOG + printf ("configfile: saving key '%s'\n", entry->key); +#endif + if (entry->description) fprintf (f_config, "# %s\n", entry->description); @@ -553,45 +621,16 @@ static void config_file_save (config_values_t *this) { } } -static void config_file_read (config_values_t *this, char *filename){ +static void xine_config_dispose (config_values_t *this) { - FILE *f_config; - - f_config = fopen (filename, "r"); - - if (f_config) { - - char line[1024]; - char *value; - - while (fgets (line, 1023, f_config)) { - line[strlen(line)-1]= (char) 0; /* eliminate lf */ - - if (line[0] == '#') - continue; - - if ((value = strchr (line, ':'))) { - - cfg_entry_t *entry; - - *value = (char) 0; - value++; - - entry = config_file_add (this, line); - entry->unknown_value = copy_string (value); - } - } - - fclose (f_config); - } -} - -static void config_file_dispose (config_values_t *this) -{ cfg_entry_t *entry, *last; entry = this->first; +#ifdef LOG + printf ("configfile: dispose\n"); +#endif + while (entry) { last = entry; entry = entry->next; @@ -612,15 +651,15 @@ static void config_file_dispose (config_values_t *this) } -static void config_file_unregister_cb (config_values_t *this, - char *key) -{ +static void xine_config_unregister_cb (config_values_t *this, + char *key) { + cfg_entry_t *entry; assert (this); assert (key); - entry = config_file_lookup_entry (this, key); + entry = _xine_config_lookup_entry (this, key); if (entry) { entry->callback = NULL; entry->callback_data = NULL; @@ -628,46 +667,43 @@ static void config_file_unregister_cb (config_values_t *this, } -config_values_t *xine_config_file_init (char *filename) { +config_values_t *xine_config_init () { #ifdef HAVE_IRIXAL volatile /* is this a (old, 2.91.66) irix gcc bug?!? */ #endif config_values_t *this; - if ( (this = xine_xmalloc(sizeof(config_values_t))) ) { - - this->first = NULL; - this->last = NULL; + if (!(this = xine_xmalloc(sizeof(config_values_t)))) { - config_file_read (this, filename); - - } else { printf ("configfile: could not allocate config object\n"); abort(); } - this->register_string = config_file_register_string; - this->register_range = config_file_register_range; - this->register_enum = config_file_register_enum; - this->register_num = config_file_register_num; - this->register_bool = config_file_register_bool; - this->update_num = config_file_update_num; - this->update_string = config_file_update_string; - this->parse_enum = config_file_parse_enum; - this->lookup_entry = config_file_lookup_entry; - this->save = config_file_save; - this->read = config_file_read; - this->dispose = config_file_dispose; - this->unregister_callback = config_file_unregister_cb; + this->first = NULL; + this->last = NULL; + + this->register_string = _xine_config_register_string; + this->register_range = _xine_config_register_range; + this->register_enum = _xine_config_register_enum; + this->register_num = _xine_config_register_num; + this->register_bool = _xine_config_register_bool; + this->update_num = xine_config_update_num; + this->update_string = xine_config_update_string; + this->parse_enum = xine_config_parse_enum; + this->lookup_entry = _xine_config_lookup_entry; + this->unregister_callback = xine_config_unregister_cb; return this; } - -int config_file_change_opt(config_values_t *config, char *opt) { +int xine_config_change_opt(config_values_t *config, char *opt) { cfg_entry_t *entry; int handled = 0; + +#ifdef LOG + printf ("configfile: change_opt '%s'\n", opt); +#endif if(config && opt && (!strncasecmp(opt, "opt:", 4))) { char *optsafe; @@ -701,7 +737,7 @@ int config_file_change_opt(config_values_t *config, char *opt) { break; case CONFIG_TYPE_UNKNOWN: -#if LOG +#ifdef LOG printf("configfile: change_opt() try to update an CONFIG_TYPE_UNKNOWN entry\n"); #endif break; @@ -714,95 +750,3 @@ int config_file_change_opt(config_values_t *config, char *opt) { return handled; } -/* - * $Log: configfile.c,v $ - * Revision 1.23 2002/06/17 07:47:50 f1rmb - * Add Siggi's idea about option config change on the fly. New "mrl style" - * opt:key=value. I hope i haven't introduced races here. - * - * Revision 1.22 2002/04/29 23:32:00 jcdutton - * Replace all exit(1) with abort(). - * xine-lib should really never do an exit or abort, but instead pass back nice error values to the calling application, but until that happens, use abort() as that is tracable with gdb, whereas exit(1) is not backtraceable. - * - * Revision 1.21 2002/04/27 23:00:40 cvogler - * Add function to unregister configfile callback. - * - * Necessary to prevent segfaults if target of a callback has been disposed. - * - * Revision 1.20 2002/04/11 07:17:43 esnel - * Fix configfile corruption reported by Chris Rankin - * - * Revision 1.19 2002/03/16 13:33:47 esnel - * fix memory leak, add dispose() function to config_values_s - * - * Revision 1.18 2002/02/06 10:57:15 f1rmb - * rename config_file_init to xine_config_file_init. - * - * Revision 1.17 2002/01/13 23:08:27 jcdutton - * Fix another compiler warning. - * - * Revision 1.16 2002/01/13 21:21:05 jcdutton - * Undo last change. - * - * Revision 1.15 2002/01/13 21:15:48 jcdutton - * Fix a few compile warnings. - * - * Revision 1.14 2002/01/09 15:16:37 mshopf - * IRIX port finally compiles (and actually works) again. - * - * Revision 1.13 2001/12/01 22:38:32 guenter - * add avi subtitle decoder (based on mplayer code), minor cleanups, removed register_empty function from configfile (undocumented and doesn't make sense) - * - * Revision 1.12 2001/11/30 21:55:06 f1rmb - * Add an automatic way for input plugin to add extra valid mrls: - * add at bottom of init_input_plugin() a line like this: - * REGISTER_VALID_MRLS(this->config, "mrl.mrls_mpeg_block", "xxx"); - * - * Revision 1.11 2001/11/20 19:13:28 guenter - * add more checks against incorrect configfile usage - * - * Revision 1.10 2001/11/20 17:22:14 miguelfreitas - * testing some configfile stuff... - * - * Revision 1.9 2001/11/19 02:57:10 guenter - * make description strings optional - config options without description string will not appear in setup dialog - * - * Revision 1.8 2001/11/18 21:38:23 miguelfreitas - * fix enum value saving - * - * Revision 1.7 2001/11/18 15:08:31 guenter - * more cleanups, config stuff bugfixes - * - * Revision 1.6 2001/11/18 03:53:25 guenter - * new configfile interface, code cleanup, xprintf is gone - * - * Revision 1.5 2001/11/17 14:26:39 f1rmb - * Add 'xine_' prefix to all of xine-utils functions (what about cpu - * acceleration?). Merge xine-utils header files to a new one "xineutils.h". - * Update xine-lib C/headers to reflect those changes. - * dxr3 headers are no more installed ine $includdir, but $includdir/xine. - * - * Revision 1.4 2001/07/26 11:12:26 f1rmb - * Updated doxy sections in xine.h.tmpl.in. Added man3. Removed french man page. Added API doc in html. Add new rpm package (doc). Fixes some little bugs in - * proto decl, etc... - * - * Revision 1.3 2001/06/15 11:08:13 f1rmb - * Check arguments in public functions. - * - * Revision 1.2 2001/06/15 10:17:53 f1rmb - * Passing NULL to config_file_lookup_str() is valid. - * - * Revision 1.1.1.1 2001/04/18 22:36:01 f1rmb - * Initial import into CVS - * - * Revision 1.8 2001/03/31 03:42:25 guenter - * more cleanups, started xv driver - * - * Revision 1.7 2001/03/28 12:30:25 siggi - * fixed init function - * added read function (multiple config files now supported) - * - * Revision 1.6 2001/03/27 17:12:49 siggi - * made config file handler a dynamic "object" - * - */ diff --git a/src/xine-engine/configfile.h b/src/xine-engine/configfile.h index 965f99bff..14e6fd4d7 100644 --- a/src/xine-engine/configfile.h +++ b/src/xine-engine/configfile.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 2000-2001 the xine project + * Copyright (C) 2000-2002 the xine project * - * This file is part of xine, a unix video player. + * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: configfile.h,v 1.11 2002/06/17 07:47:50 f1rmb Exp $ + * $Id: configfile.h,v 1.12 2002/09/04 23:31:13 guenter Exp $ * * config file management * @@ -32,11 +32,11 @@ extern "C" { #include <inttypes.h> +#include "xine.h" + typedef struct cfg_entry_s cfg_entry_t; typedef struct config_values_s config_values_t; -typedef void (*config_cb_t) (void *, cfg_entry_t *); - struct cfg_entry_s { cfg_entry_t *next; config_values_t *config; @@ -68,8 +68,11 @@ struct cfg_entry_s { char *description; char *help; + /* user experience level */ + int exp_level; + /* callback function and data for live changeable values */ - config_cb_t callback; + xine_config_cb_t callback; void *callback_data; }; @@ -100,7 +103,8 @@ struct config_values_s { char *def_value, char *description, char *help, - config_cb_t changed_cb, + int exp_level, + xine_config_cb_t changed_cb, void *cb_data); int (*register_range) (config_values_t *this, @@ -109,7 +113,8 @@ struct config_values_s { int min, int max, char *description, char *help, - config_cb_t changed_cb, + int exp_level, + xine_config_cb_t changed_cb, void *cb_data); int (*register_enum) (config_values_t *this, @@ -118,7 +123,8 @@ struct config_values_s { char **values, char *description, char *help, - config_cb_t changed_cb, + int exp_level, + xine_config_cb_t changed_cb, void *cb_data); int (*register_num) (config_values_t *this, @@ -126,7 +132,8 @@ struct config_values_s { int def_value, char *description, char *help, - config_cb_t changed_cb, + int exp_level, + xine_config_cb_t changed_cb, void *cb_data); int (*register_bool) (config_values_t *this, @@ -134,7 +141,8 @@ struct config_values_s { int def_value, char *description, char *help, - config_cb_t changed_cb, + int exp_level, + xine_config_cb_t changed_cb, void *cb_data); /* convenience function to update range, enum, num and bool values */ @@ -159,21 +167,6 @@ struct config_values_s { char *key); /* - * write config file to disk - */ - void (*save) (config_values_t *this); - - /* - * read config file from disk, overriding values in memory - */ - void (*read) (config_values_t *this, char *filename); - - /* - * free memory resources - */ - void (*dispose) (config_values_t *this); - - /* * unregister callback function */ void (*unregister_callback) (config_values_t *this, @@ -182,15 +175,21 @@ struct config_values_s { /* * config values are stored here: */ - cfg_entry_t *first, *last; + cfg_entry_t *first, *last, *cur; + xine_cfg_entry_t public_entry; }; /* - * init internal data structures, read config file - * (if it exists) + * allocate and init a new xine config object + */ +config_values_t *xine_config_init (); + +/* + * hack: intepret "opt:"-style mrls for config value changes */ -config_values_t *xine_config_file_init (char *filename); -int config_file_change_opt(config_values_t *config, char *opt); + +int xine_config_change_opt(config_values_t *config, char *opt) ; + #ifdef __cplusplus } @@ -198,55 +197,3 @@ int config_file_change_opt(config_values_t *config, char *opt); #endif -/* - * $Log: configfile.h,v $ - * Revision 1.11 2002/06/17 07:47:50 f1rmb - * Add Siggi's idea about option config change on the fly. New "mrl style" - * opt:key=value. I hope i haven't introduced races here. - * - * Revision 1.10 2002/04/27 23:00:40 cvogler - * Add function to unregister configfile callback. - * - * Necessary to prevent segfaults if target of a callback has been disposed. - * - * Revision 1.9 2002/03/16 13:33:47 esnel - * fix memory leak, add dispose() function to config_values_s - * - * Revision 1.8 2002/02/06 10:57:15 f1rmb - * rename config_file_init to xine_config_file_init. - * - * Revision 1.7 2001/12/01 22:38:32 guenter - * add avi subtitle decoder (based on mplayer code), minor cleanups, removed register_empty function from configfile (undocumented and doesn't make sense) - * - * Revision 1.6 2001/11/30 21:55:06 f1rmb - * Add an automatic way for input plugin to add extra valid mrls: - * add at bottom of init_input_plugin() a line like this: - * REGISTER_VALID_MRLS(this->config, "mrl.mrls_mpeg_block", "xxx"); - * - * Revision 1.5 2001/11/20 17:22:14 miguelfreitas - * testing some configfile stuff... - * - * Revision 1.4 2001/11/18 03:53:25 guenter - * new configfile interface, code cleanup, xprintf is gone - * - * Revision 1.3 2001/07/26 11:12:26 f1rmb - * Updated doxy sections in xine.h.tmpl.in. Added man3. Removed french man page. Added API doc in html. Add new rpm package (doc). Fixes some little bugs in - * proto decl, etc... - * - * Revision 1.2 2001/07/18 21:38:17 f1rmb - * Split alsa drivers, more checks about versions. Made xine lib c++ compliant. - * - * Revision 1.1.1.1 2001/04/18 22:36:05 f1rmb - * Initial import into CVS - * - * Revision 1.6 2001/03/31 03:42:25 guenter - * more cleanups, started xv driver - * - * Revision 1.5 2001/03/28 12:30:25 siggi - * fixed init function - * added read function (multiple config files now supported) - * - * Revision 1.4 2001/03/27 21:49:02 siggi - * started touching demuxers - * - */ diff --git a/src/xine-engine/events.c b/src/xine-engine/events.c index 5db72b59c..623a984fc 100644 --- a/src/xine-engine/events.c +++ b/src/xine-engine/events.c @@ -29,8 +29,9 @@ #include "xine_internal.h" -int xine_register_event_listener(xine_t *this, xine_event_listener_t listener, - void *user_data) { +int xine_register_event_listener (xine_t *this, + xine_event_listener_cb_t listener, + void *user_data) { /* Ensure the listener is non-NULL */ if(listener == NULL) { return 0; @@ -59,7 +60,8 @@ void xine_send_event(xine_t *this, xine_event_t *event) { } } -int xine_remove_event_listener(xine_t *this, xine_event_listener_t listener) { +int xine_remove_event_listener(xine_t *this, + xine_event_listener_cb_t listener) { uint16_t i, found; found = 1; i = 0; diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c index 6a66d0133..fea86521e 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.80 2002/07/17 21:23:57 f1rmb Exp $ + * $Id: load_plugins.c,v 1.81 2002/09/04 23:31:13 guenter Exp $ * * * Load input/demux/audio_out/video_out/codec plugins @@ -31,6 +31,7 @@ #include <inttypes.h> #include <sys/types.h> #include <sys/stat.h> +#include <unistd.h> #include <dirent.h> #include <dlfcn.h> #include <string.h> @@ -39,6 +40,8 @@ #include <signal.h> #include "xine_internal.h" +#include "xine_plugin.h" +#include "plugin_catalog.h" #include "demuxers/demux.h" #include "input/input_plugin.h" #include "video_out.h" @@ -51,15 +54,6 @@ #define LOG */ -/* transition code; between xine 0.9.7 and 0.9.8, the dxr3enc driver - * was integrated in the dxr3 driver and no longer exists as a seperate - * plugin. upgraded installs may have an old dxr3enc driver left in the - * plugins dir, which we do not want to load. this define activates - * some code to check for this and print warnings. - * should probably be removed for version 1.0 - * --- Harm van der Heijden */ -#define IGNORE_DXR3ENC 1 - extern int errno; static char *plugin_name; @@ -90,1000 +84,652 @@ static void remove_segv_handler(void){ #endif -/* - * Demuxers plugins section - */ -void load_demux_plugins (xine_t *this, config_values_t *config) { - DIR *dir; - - if (this == NULL || config == NULL) { - printf (_("%s(%s@%d): parameter should be non null, exiting\n"), - __FILE__, __XINE_FUNCTION__, __LINE__); - abort(); - } - this->num_demuxer_plugins = 0; - install_segv_handler(); - - dir = opendir (XINE_PLUGINDIR) ; - - if (dir) { - struct dirent *pEntry; - - while ((pEntry = readdir (dir)) != NULL) { - char str[1024]; - void *plugin; - - int nLen = strlen (pEntry->d_name); - - if ((strncasecmp(pEntry->d_name, - XINE_DEMUXER_PLUGIN_PREFIXNAME, - XINE_DEMUXER_PLUGIN_PREFIXNAME_LENGTH) == 0) && - ((pEntry->d_name[nLen-3]=='.') - && (pEntry->d_name[nLen-2]=='s') - && (pEntry->d_name[nLen-1]=='o'))) { - - /* - * demux plugin found => load it - */ - - sprintf (str, "%s/%s", XINE_PLUGINDIR, pEntry->d_name); - plugin_name = str; - - if(!(plugin = dlopen (str, RTLD_LAZY))) { - char *dl_error_msg = dlerror(); - xine_log (this, XINE_LOG_PLUGIN, - _("load_plugins: cannot open demux plugin %s:\n%s\n"), - str, dl_error_msg); +/* + * plugin list/catalog management functions + * + */ - } else { +static char *_strclone(const char *str){ + char *new; - void *(*initplug) (int, xine_t *); - - if((initplug = dlsym(plugin, "init_demuxer_plugin")) != NULL) { - demux_plugin_t *dxp; - - dxp = (demux_plugin_t *) initplug (DEMUXER_PLUGIN_IFACE_VERSION, this); - if (dxp) { - this->demuxer_plugins[this->num_demuxer_plugins] = dxp; - - xine_log (this, XINE_LOG_PLUGIN, - _("load_plugins: demux plugin found : %s\n"), - this->demuxer_plugins[this->num_demuxer_plugins]->get_identifier()); + new = xine_xmalloc(strlen(str)+1); + strcpy(new, str); + return new; +} - this->num_demuxer_plugins++; - } - } - - if(this->num_demuxer_plugins > DEMUXER_PLUGIN_MAX) { - printf ( _("load_plugins: too many demux plugins installed, exiting.\n")); - abort(); - } - } - } +static void _insert_plugin (xine_list_t *list, + char *filename, plugin_info_t *info){ + + plugin_node_t *entry; + vo_info_t *vo_new, *vo_old; + ao_info_t *ao_new, *ao_old; + decoder_info_t *decoder_new, *decoder_old; + uint32_t *types; + int i; + + /* FIXME: TODO: insert replacement/priority logic here */ + + entry = xine_xmalloc(sizeof(plugin_node_t)); + entry->filename = _strclone(filename); + entry->info = xine_xmalloc(sizeof(plugin_info_t)); + *(entry->info) = *info; + entry->info->id = _strclone(info->id); + entry->info->init = NULL; + + switch (info->type){ + + case PLUGIN_VIDEO_OUT: + vo_old = info->special_info; + vo_new = xine_xmalloc(sizeof(vo_info_t)); + vo_new->priority = vo_old->priority; + vo_new->description = _strclone(vo_old->description); + vo_new->visual_type = vo_old->visual_type; + entry->info->special_info = vo_new; + break; + + case PLUGIN_AUDIO_OUT: + ao_old = info->special_info; + ao_new = xine_xmalloc(sizeof(ao_info_t)); + ao_new->priority = ao_old->priority; + ao_new->description = _strclone(ao_old->description); + entry->info->special_info = ao_new; + break; + + case PLUGIN_AUDIO_DECODER: + case PLUGIN_VIDEO_DECODER: + decoder_old = info->special_info; + decoder_new = xine_xmalloc(sizeof(decoder_info_t)); + if (decoder_old == NULL) { + printf ("load_plugins: plugin %s from %s is broken: special_info=NULL\n", + info->id, entry->filename); + abort(); + } + for (i=0; decoder_old->supported_types[i] != 0; ++i); + types = xine_xmalloc((i+1)*sizeof(uint32_t)); + for (i=0; decoder_old->supported_types[i] != 0; ++i){ + types[i] = decoder_old->supported_types[i]; } - closedir(dir); + decoder_new->supported_types = types; + decoder_new->priority = decoder_old->priority; + entry->info->special_info = decoder_new; + break; } - - remove_segv_handler(); + /* - * init demuxer + * insert plugin into list + * FIXME: find right place depending on plugin priority */ + + xine_list_append_content (list, entry); +} + + +static plugin_catalog_t *_empty_catalog(void){ + + plugin_catalog_t *catalog; - this->cur_demuxer_plugin = NULL; + catalog = xine_xmalloc(sizeof(plugin_catalog_t)); + catalog->input = xine_list_new(); + catalog->demux = xine_list_new(); + catalog->spu = xine_list_new(); + catalog->audio = xine_list_new(); + catalog->video = xine_list_new(); + catalog->aout = xine_list_new(); + catalog->vout = xine_list_new(); + + return catalog; } -void xine_list_demux_plugins (config_values_t *config, - char **identifiers, char **mimetypes) { +/* + * First stage plugin loader (catalog builder) + * + ***************************************************************************/ + +static void collect_plugins(xine_t *this, char *path){ + DIR *dir; - xine_t *this; - int sizeid, sizemime; - int incsize; - char *s; - - this = xine_xmalloc (sizeof (xine_t)); - - sizeid = sizemime = incsize = 4096; - *identifiers = xine_xmalloc (sizeid); - *mimetypes = xine_xmalloc (sizemime); - - this->config = config; - install_segv_handler(); - - dir = opendir (XINE_PLUGINDIR) ; - +#ifdef LOG + printf ("load_plugins: collect_plugins in %s\n", path); +#endif + + dir = opendir(path); if (dir) { struct dirent *pEntry; while ((pEntry = readdir (dir)) != NULL) { - char str[1024]; - void *plugin; - - int nLen = strlen (pEntry->d_name); - - if ((strncasecmp(pEntry->d_name, - XINE_DEMUXER_PLUGIN_PREFIXNAME, - XINE_DEMUXER_PLUGIN_PREFIXNAME_LENGTH) == 0) && - ((pEntry->d_name[nLen-3]=='.') - && (pEntry->d_name[nLen-2]=='s') - && (pEntry->d_name[nLen-1]=='o'))) { - - /* - * demux plugin found => load it - */ - - sprintf (str, "%s/%s", XINE_PLUGINDIR, pEntry->d_name); - plugin_name = str; - - if(!(plugin = dlopen (str, RTLD_LAZY))) { - printf ("load_plugins: cannot open demux plugin %s:\n%s\n", - str, dlerror()); - } else { - void *(*initplug) (int, xine_t *); + char *str; + void *lib; + struct stat statbuffer; - if((initplug = dlsym(plugin, "init_demuxer_plugin")) != NULL) { - demux_plugin_t *dxp; - - dxp = (demux_plugin_t *) initplug(DEMUXER_PLUGIN_IFACE_VERSION, this); - if (dxp) { - /* realloc sucks, but it will make this code much simpler */ - s = dxp->get_identifier(); - if( strlen(s) + strlen(*identifiers) + 2 > sizeid ) { - sizeid += incsize; - *identifiers = realloc( *identifiers, sizeid ); - } - strcat(*identifiers, s); - strcat(*identifiers, "\n"); + str = xine_xmalloc(strlen(path) + strlen(pEntry->d_name) + 2); + sprintf (str, "%s/%s", XINE_PLUGINDIR, pEntry->d_name); + + if (stat(str, &statbuffer)) { + xine_log (this, XINE_LOG_PLUGIN, + _("load_plugins: unable to stat %s\n"), str); + } + else { + + switch (statbuffer.st_mode & S_IFMT){ + + case S_IFREG: + /* regular file, ie. plugin library, found => load it */ + + plugin_name = str; + + if(!(lib = dlopen (str, RTLD_LAZY))) { + char *dl_error_msg = dlerror(); + +#ifdef LOG + /* too noisy */ + printf ("load_plugins: cannot open plugin lib %s:\n%s\n", + str, dl_error_msg); +#endif + } + else { + + plugin_info_t *info; + + if ((info = dlsym(lib, "xine_plugin_info"))) { + + for (; info->type != PLUGIN_NONE; ++info){ - s = dxp->get_mimetypes(); - if( strlen(s) + strlen(*mimetypes) + 2 > sizemime ) { - sizemime += incsize; - *identifiers = realloc( *identifiers, sizemime ); + xine_log (this, XINE_LOG_PLUGIN, + _("load_plugins: plugin %s found\n"), str); + + switch (info->type){ + case PLUGIN_INPUT: + _insert_plugin(this->plugin_catalog->input, str, info); + break; + case PLUGIN_DEMUX: + _insert_plugin(this->plugin_catalog->demux, str, info); + break; + case PLUGIN_AUDIO_DECODER: + _insert_plugin(this->plugin_catalog->audio, str, info); + break; + case PLUGIN_VIDEO_DECODER: + _insert_plugin(this->plugin_catalog->video, str, info); + break; + case PLUGIN_SPU_DECODER: + _insert_plugin(this->plugin_catalog->spu, str, info); + break; + case PLUGIN_AUDIO_OUT: + _insert_plugin(this->plugin_catalog->aout, str, info); + break; + case PLUGIN_VIDEO_OUT: + _insert_plugin(this->plugin_catalog->vout, str, info); + break; + default: + xine_log (this, XINE_LOG_PLUGIN, + _("load_plugins: unknown plugin type %d in %s\n"), + info->type, str); + } } - strcat(*mimetypes, s); + + } + else { + char *dl_error_msg = dlerror(); + + xine_log (this, XINE_LOG_PLUGIN, + _("load_plugins: can't get plugin info from %s:\n%s\n"), + str, dl_error_msg); } + dlclose(lib); } - dlclose(plugin); - } - } - } - closedir(dir); - } - remove_segv_handler(); - - free(this); -} + break; + case S_IFDIR: + + if (*pEntry->d_name != '.'){ /* catches ".", ".." or ".hidden" dirs */ + collect_plugins(this, str); + } + } /* switch */ + } /* if (stat(...)) */ + free(str); + } /* while */ + } /* if (dir) */ +} /* collect_plugins */ -/** *************************************************************** - * Input plugins section + +/* + * generic 2nd stage plugin loader */ -void load_input_plugins (xine_t *this, - config_values_t *config) { - DIR *dir; - - this->num_input_plugins = 0; - - install_segv_handler(); - dir = opendir (XINE_PLUGINDIR) ; - - if (dir) { - struct dirent *pEntry; - - while ((pEntry = readdir (dir)) != NULL) { - char str[1024]; - void *plugin; - - int nLen = strlen (pEntry->d_name); - - if ((strncasecmp(pEntry->d_name, - XINE_INPUT_PLUGIN_PREFIXNAME, - XINE_INPUT_PLUGIN_PREFIXNAME_LENGTH) == 0) && - ((pEntry->d_name[nLen-3]=='.') - && (pEntry->d_name[nLen-2]=='s') - && (pEntry->d_name[nLen-1]=='o'))) { - - /* - * input plugin found => load it - */ - - sprintf (str, "%s/%s", XINE_PLUGINDIR, pEntry->d_name); - plugin_name = str; - - if(!(plugin = dlopen (str, RTLD_LAZY))) { - char *dl_error_msg = dlerror(); - - xine_log (this, XINE_LOG_PLUGIN, - _("load_plugins: cannot open input plugin %s:\n%s\n"), - str, dl_error_msg); - } else { - void *(*initplug) (int, xine_t *); - - if((initplug = dlsym(plugin, "init_input_plugin")) != NULL) { - input_plugin_t *ip; - - ip = (input_plugin_t *) initplug (INPUT_PLUGIN_IFACE_VERSION, this); - if (ip) { - this->input_plugins[this->num_input_plugins] = ip; - - xine_log (this, XINE_LOG_PLUGIN, - _("load_plugins: input plugin found : %s\n"), - this->input_plugins[this->num_input_plugins]->get_identifier(this->input_plugins[this->num_input_plugins])); +static void *_load_plugin(xine_t *this, + char *filename, plugin_info_t *target, + void *data) { - this->num_input_plugins++; - } + void *lib; - } else { - xine_log (this, XINE_LOG_PLUGIN, - _("load_plugins: %s is no valid input plugin (lacks init_input_plugin() function)\n"), str); - } + if(!(lib = dlopen (filename, RTLD_LAZY))) { + + xine_log (this, XINE_LOG_PLUGIN, + _("load_plugins: cannot (stage 2) open plugin lib %s:\n%s\n"), + filename, dlerror()); + + } else { + + plugin_info_t *info; + + if ((info = dlsym(lib, "xine_plugin_info"))) { + /* TODO: use sigsegv handler */ + while (info->type != PLUGIN_NONE){ + if (info->type == target->type + && info->API == target->API + && !strcasecmp(info->id, target->id) + && info->version == target->version){ - if(this->num_input_plugins > INPUT_PLUGIN_MAX) { - printf (_("%s(%d): too many input plugins installed, " - "exiting.\n"), __FILE__, __LINE__); - abort(); - } + return info->init(this, data); } } + + } else { + xine_log (this, XINE_LOG_PLUGIN, + "load_plugins: Yikes! %s doesn't contain plugin info.\n", + filename); } - closedir(dir); } - - remove_segv_handler(); - - if (this->num_input_plugins == 0) { - printf (_("load_plugins: no input plugins found in %s! - " - "Did you install xine correctly??\n"), XINE_PLUGINDIR); - abort(); - } - + return NULL; /* something failed if we came here... */ } -static char **_xine_get_featured_input_plugin_ids(xine_t *this, int feature) { - input_plugin_t *ip; - char **plugin_ids; - int i; - int n = 0; +/* + * load input+demuxer plugins + */ +static void load_plugins(xine_t *this) { - if(!this->num_input_plugins) - return NULL; + plugin_node_t *node; - plugin_ids = (char **) xine_xmalloc (this->num_input_plugins * sizeof (char *)); + /* + * input plugins + */ - for(i = 0; i < this->num_input_plugins; i++) { + node = xine_list_first_content (this->plugin_catalog->input); + while (node) { - ip = this->input_plugins[i]; +#ifdef LOG + printf("load_plugins: load input plugin %s from %s\n", + node->info->id, node->filename); +#endif - if(ip->get_capabilities(ip) & feature) { - plugin_ids[n] = (char *) malloc (strlen(ip->get_identifier(ip)) + 1 ); - strcpy (plugin_ids[n], ip->get_identifier(ip)); - /* printf("%s(%d): %s is featured\n", */ - /* __XINE_FUNCTION__, feature, ip->get_identifier(ip)); */ - n++; - } + node->plugin = _load_plugin(this, node->filename, node->info, NULL); + node = xine_list_next_content (this->plugin_catalog->input); } - plugin_ids[n] = NULL; - - return plugin_ids; -} - -char **xine_get_autoplay_input_plugin_ids(xine_t *this) { - - return (_xine_get_featured_input_plugin_ids(this, INPUT_CAP_AUTOPLAY)); -} + /* + * demux plugins + */ -char **xine_get_browsable_input_plugin_ids(xine_t *this) { + node = xine_list_first_content (this->plugin_catalog->demux); + while (node) { - return (_xine_get_featured_input_plugin_ids(this, INPUT_CAP_GET_DIR)); -} +#ifdef LOG + printf("load_plugins: load demux plugin %s from %s\n", + node->info->id, node->filename); +#endif -char *xine_get_input_plugin_description(xine_t *this, char *plugin_id) { - char *str; - input_plugin_t *ip; - int i; + node->plugin = _load_plugin(this, node->filename, node->info, NULL); - if((this == NULL) || (this->num_input_plugins < 1) || (plugin_id == NULL)) - return NULL; - - for(i = 0; i < this->num_input_plugins; i++) { - - ip = this->input_plugins[i]; - - if(!strcasecmp((ip->get_identifier(ip)), plugin_id)) { - str = strdup(ip->get_description(ip)); - return str; - } + node = xine_list_next_content (this->plugin_catalog->demux); } - - return NULL; } -uint32_t xine_get_input_plugin_capabilities(xine_t *this) { - - if (this && this->cur_input_plugin && this->cur_input_plugin->get_capabilities) - return this->cur_input_plugin->get_capabilities(this->cur_input_plugin); - - return INPUT_CAP_NOCAP; -} +static void map_decoders (xine_t *this) { -/** *************************************************************** - * Decoder plugins section - */ -static int decide_spu_insert(spu_decoder_t *p, int streamtype, int prio) { + plugin_catalog_t *catalog = this->plugin_catalog; + plugin_node_t *node; + int i; - if (!p->can_handle (p, (streamtype<<16) | BUF_SPU_BASE)) - return 0; +#ifdef LOG + printf ("load_plugins: map_decoders\n"); +#endif - if (p->priority < prio) - return 0; + /* clean up */ - /* All conditions successfully passed */ - return p->priority; -} + for (i=0; i<DECODER_MAX; i++) { + catalog->audio_decoder_map[i]=NULL; + catalog->video_decoder_map[i]=NULL; + catalog->spu_decoder_map[i]=NULL; + } -static int decide_video_insert(video_decoder_t *p, int streamtype, int prio) { + /* + * map audio decoders + */ + + node = xine_list_first_content (this->plugin_catalog->audio); + while (node) { - if (!p->can_handle (p, (streamtype<<16) | BUF_VIDEO_BASE)) - return 0; + decoder_info_t *di = (decoder_info_t *) node->info->special_info; + int *type; - if (p->priority < prio) - return 0; +#ifdef LOG + printf ("load_plugins: mapping decoder %s\n", node->info->id); +#endif - /* All conditions successfully passed */ - return p->priority; -} + type = di->supported_types; -static int decide_audio_insert(audio_decoder_t *p, int streamtype, int prio) { + while (type && (*type)) { - if (!p->can_handle (p, (streamtype<<16) | BUF_AUDIO_BASE)) - return 0; + int streamtype = ((*type)>>16) & 0xFF; + int priority; - if (p->priority < prio) - return 0; +#ifdef LOG + printf ("load_plugins: decoder handles stream type %02x, priority %d\n", + streamtype, di->priority); +#endif - /* All conditions successfully passed */ - return p->priority; -} + if (catalog->audio_decoder_map[streamtype]) { + priority = ((decoder_info_t *) catalog->audio_decoder_map[streamtype]->info->special_info)->priority; + } else + priority = 0; -/* - * load audio and video decoder plugins - */ -void load_decoder_plugins (xine_t *this, config_values_t *config) { - DIR *dir; - int i; - int spu_prio[DECODER_PLUGIN_MAX], video_prio[DECODER_PLUGIN_MAX], - audio_prio[DECODER_PLUGIN_MAX]; + if (di->priority > priority) { +#ifdef LOG + printf ("load_plugins: using decoder %s for stream type %02x\n", + node->info->id, streamtype); +#endif + catalog->audio_decoder_map[streamtype] = node; + } - if (this == NULL || config == NULL) { - printf ( _("%s(%s@%d): parameter should be non null, exiting\n"), - __FILE__, __XINE_FUNCTION__, __LINE__); - abort(); + type++; + } + + node = xine_list_next_content (this->plugin_catalog->audio); } - /* - * clean up first + /* + * map video decoders */ - this->cur_spu_decoder_plugin = NULL; - for (i=0; i<DECODER_PLUGIN_MAX; i++) { - this->spu_decoder_plugins[i] = NULL; - spu_prio[i] = 0; - } - this->num_spu_decoders_loaded = 0; + + node = xine_list_first_content (this->plugin_catalog->video); + while (node) { - this->cur_video_decoder_plugin = NULL; - for (i=0; i<DECODER_PLUGIN_MAX; i++) { - this->video_decoder_plugins[i] = NULL; - video_prio[i] = 0; - } - this->num_video_decoders_loaded = 0; + decoder_info_t *di = (decoder_info_t *) node->info->special_info; + int *type; - this->cur_audio_decoder_plugin = NULL; - for (i=0; i<DECODER_PLUGIN_MAX; i++) { - this->audio_decoder_plugins[i] = NULL; - audio_prio[i] = 0; - } - this->num_audio_decoders_loaded = 0; +#ifdef LOG + printf ("load_plugins: mapping decoder %s\n", node->info->id); +#endif - /* - * now scan for decoder plugins - */ + type = di->supported_types; - - install_segv_handler(); - - dir = opendir (XINE_PLUGINDIR) ; - - if (dir) { - struct dirent *pEntry; - - while ((pEntry = readdir (dir)) != NULL) { - char str[1024]; - void *plugin; - - int nLen = strlen (pEntry->d_name); - - if ((strncasecmp(pEntry->d_name, - XINE_DECODER_PLUGIN_PREFIXNAME, - XINE_DECODER_PLUGIN_PREFIXNAME_LENGTH) == 0) && - ((pEntry->d_name[nLen-3]=='.') - && (pEntry->d_name[nLen-2]=='s') - && (pEntry->d_name[nLen-1]=='o'))) { - - /* - * decoder plugin found => load it - */ - - sprintf (str, "%s/%s", XINE_PLUGINDIR, pEntry->d_name); - plugin_name = str; - - if(!(plugin = dlopen (str, RTLD_LAZY))) { - char *dl_error_msg = dlerror(); - - xine_log (this, XINE_LOG_PLUGIN, - _("load_plugins: failed to load plugin %s:\n%s\n"), - str, dl_error_msg); - - } else { - int plugin_prio; - - /* - * does this plugin provide an spu decoder plugin? - */ - { - void *(*initplug) (int, xine_t *); - - if((initplug = dlsym(plugin, "init_spu_decoder_plugin")) != NULL) { - - spu_decoder_t *sdp; - int streamtype; - - sdp = (spu_decoder_t *) initplug (SPU_DECODER_IFACE_VERSION, this); - if (sdp) { - - this->spu_decoders_loaded [this->num_spu_decoders_loaded] = sdp; - this->num_spu_decoders_loaded++; - - for (streamtype = 0; streamtype<DECODER_PLUGIN_MAX; streamtype++) { - if ((plugin_prio = - decide_spu_insert(sdp, streamtype, spu_prio[streamtype]))) { - - this->spu_decoder_plugins[streamtype] = sdp; - spu_prio[streamtype] = plugin_prio; - } - } - - xine_log (this, XINE_LOG_PLUGIN, - _("spu decoder plugin found : %s\n"), - sdp->get_identifier()); + while (type && (*type)) { - } - } - } + int streamtype = ((*type)>>16) & 0xFF; + int priority; - /* - * does this plugin provide an video decoder plugin? - */ - - { - void *(*initplug) (int, xine_t *); - if((initplug = dlsym(plugin, "init_video_decoder_plugin")) != NULL) { - - video_decoder_t *vdp; - int streamtype; - - vdp = (video_decoder_t *) initplug(VIDEO_DECODER_IFACE_VERSION, this); - if (vdp) { - - this->video_decoders_loaded [this->num_video_decoders_loaded] = vdp; - this->num_video_decoders_loaded++; - - for (streamtype = 0; streamtype<DECODER_PLUGIN_MAX; streamtype++) - if ((plugin_prio = - decide_video_insert(vdp, streamtype, video_prio[streamtype]))) { - - this->video_decoder_plugins[streamtype] = vdp; - video_prio[streamtype] = plugin_prio; - } - - xine_log (this, XINE_LOG_PLUGIN, - _("video decoder plugin found : %s\n"), - vdp->get_identifier()); +#ifdef LOG + printf ("load_plugins: decoder handles stream type %02x, priority %d\n", + streamtype, di->priority); +#endif - } - } - - /* - * does this plugin provide an audio decoder plugin? - */ - - if((initplug = dlsym(plugin, "init_audio_decoder_plugin")) != NULL) { - - audio_decoder_t *adp; - int streamtype; - - adp = (audio_decoder_t *) initplug(AUDIO_DECODER_IFACE_VERSION, this); - if (adp) { - - this->audio_decoders_loaded [this->num_audio_decoders_loaded] = adp; - this->num_audio_decoders_loaded++; - - for (streamtype = 0; streamtype<DECODER_PLUGIN_MAX; streamtype++) - if ((plugin_prio = - decide_audio_insert(adp, streamtype, audio_prio[streamtype]))) { - - this->audio_decoder_plugins[streamtype] = adp; - audio_prio[streamtype] = plugin_prio; - } - - xine_log (this, XINE_LOG_PLUGIN, - _("audio decoder plugin found : %s\n"), - adp->get_identifier()); + if (catalog->video_decoder_map[streamtype]) { + priority = ((decoder_info_t *) catalog->video_decoder_map[streamtype]->info->special_info)->priority; + } else + priority = 0; - } - } - - } - } + if (di->priority > priority) { +#ifdef LOG + printf ("load_plugins: using decoder %s for stream type %02x\n", + node->info->id, streamtype); +#endif + catalog->video_decoder_map[streamtype] = node; } + + type++; } - closedir(dir); - } - remove_segv_handler(); - this->cur_spu_decoder_plugin = NULL; - this->cur_video_decoder_plugin = NULL; - this->cur_audio_decoder_plugin = NULL; -} + node = xine_list_next_content (this->plugin_catalog->video); + } -/** *************************************************************** - * Video output plugins section - */ -char **xine_list_video_output_plugins (int visual_type) { + /* + * map spu decoders + */ + + node = xine_list_first_content (this->plugin_catalog->spu); + while (node) { - char **plugin_ids; - int num_plugins = 0; - DIR *dir; - int i,j; - int plugin_prios[50]; + decoder_info_t *di = (decoder_info_t *) node->info->special_info; + int *type; - plugin_ids = (char **) xine_xmalloc (50 * sizeof (char *)); - plugin_ids[0] = NULL; +#ifdef LOG + printf ("load_plugins: mapping decoder %s\n", node->info->id); +#endif - install_segv_handler(); - -#ifdef ENABLE_NLS - bindtextdomain("xine-lib", XINE_LOCALEDIR); -#endif + type = di->supported_types; - dir = opendir (XINE_PLUGINDIR); + while (type && (*type)) { - if (dir) { - struct dirent *dir_entry; + int streamtype = ((*type)>>16) & 0xFF; + int priority; - while ((dir_entry = readdir (dir)) != NULL) { - char str[1024]; - void *plugin; - int nLen = strlen (dir_entry->d_name); +#ifdef LOG + printf ("load_plugins: decoder handles stream type %02x, priority %d\n", + streamtype, di->priority); +#endif - if ((strncasecmp(dir_entry->d_name, - XINE_VIDEO_OUT_PLUGIN_PREFIXNAME, - XINE_VIDEO_OUT_PLUGIN_PREFIXNAME_LENGTH) == 0) && - ((dir_entry->d_name[nLen-3]=='.') - && (dir_entry->d_name[nLen-2]=='s') - && (dir_entry->d_name[nLen-1]=='o'))) { + if (catalog->spu_decoder_map[streamtype]) { + priority = ((decoder_info_t *) catalog->spu_decoder_map[streamtype]->info->special_info)->priority; + } else + priority = 0; + if (di->priority > priority) { #ifdef LOG - printf ("load_plugins: found a video output plugin: %s\n", - dir_entry->d_name); + printf ("load_plugins: using decoder %s for stream type %02x\n", + node->info->id, streamtype); #endif + catalog->spu_decoder_map[streamtype] = node; + } -#if IGNORE_DXR3ENC - if (!strncasecmp(dir_entry->d_name, - XINE_VIDEO_OUT_PLUGIN_PREFIXNAME "dxr3enc", - XINE_VIDEO_OUT_PLUGIN_PREFIXNAME_LENGTH + 7)) { - printf ("load_plugins: (ignoring obsolete dxr3enc driver)"); - continue; - } + type++; + } + + node = xine_list_next_content (this->plugin_catalog->spu); + } +} + +/* + * initialize catalog, load all plugins into new catalog + */ +void scan_plugins (xine_t *this) { + +#ifdef LOG + printf("load_plugins: scan_plugins()\n"); #endif + if (this == NULL || this->config == NULL) { + fprintf(stderr, "%s(%s@%d): parameter should be non null, exiting\n", + __FILE__, __XINE_FUNCTION__, __LINE__); + abort(); + } - sprintf (str, "%s/%s", XINE_PLUGINDIR, dir_entry->d_name); - plugin_name = str; - - /* - * now, see if we can open this plugin, - * check if it has got the right visual type - * and finally if all this went through get it's id - */ + this->plugin_catalog = _empty_catalog(); + /* TODO: add more plugin dir(s), maybe ~/.xine/plugins or /usr/local/... */ + collect_plugins(this, XINE_PLUGINDIR); - if(!(plugin = dlopen (str, RTLD_LAZY | RTLD_GLOBAL))) { + load_plugins (this); - printf("load_plugins: cannot load plugin %s:\n%s\n", - str, dlerror()); + map_decoders (this); +} - } else { - vo_info_t* (*getinfo) (); - vo_info_t *vo_info; - if ((getinfo = dlsym(plugin, "get_video_out_plugin_info")) != NULL) { - vo_info = getinfo(); +static char **_xine_get_featured_input_plugin_ids(xine_t *this, int feature) { - if ( (vo_info->visual_type == visual_type) - && (vo_info->interface_version == VIDEO_OUT_DRIVER_IFACE_VERSION) ) { -#ifdef LOG - printf("video output plugin found : %s (%s)\n", - vo_info->id, vo_info->description); -#endif + /* FIXME */ - /* sort the list by vo_info->priority */ +#if 0 - i = 0; - while ( (i<num_plugins) && (vo_info->priority<plugin_prios[i]) ) - i++; + input_plugin_t *ip; + char **plugin_ids; + int i; + int n = 0; - j = num_plugins; - while (j>i) { - plugin_ids[j] = plugin_ids[j-1]; - plugin_prios[j] = plugin_prios[j-1]; - j--; - } + if(!this->num_input_plugins) + return NULL; - plugin_ids[i] = (char *) malloc (strlen(vo_info->id)+1); - strcpy (plugin_ids[i], vo_info->id); - plugin_prios[i] = vo_info->priority; - - num_plugins++; - plugin_ids[num_plugins] = NULL; - } else { - - if(vo_info->interface_version != VIDEO_OUT_DRIVER_IFACE_VERSION) - printf ("load_plugins: %s has wrong interface version (%d)\n", - str, vo_info->interface_version); -#ifdef LOG - else if(vo_info->visual_type != visual_type) - printf ("load_plugins: %s has wrong visual type (%d)\n", - str, vo_info->visual_type); -#endif - } - } else { + plugin_ids = (char **) xine_xmalloc (this->num_input_plugins * sizeof (char *)); - printf("load_plugins: %s seems to be an invalid plugin " - "(lacks get_video_out_plugin_info() function)\n", str); + for(i = 0; i < this->num_input_plugins; i++) { - } - dlclose (plugin); - } - } + ip = this->input_plugins[i]; + + if(ip->get_capabilities(ip) & feature) { + plugin_ids[n] = (char *) malloc (strlen(ip->get_identifier(ip)) + 1 ); + strcpy (plugin_ids[n], ip->get_identifier(ip)); + /* printf("%s(%d): %s is featured\n", */ + /* __XINE_FUNCTION__, feature, ip->get_identifier(ip)); */ + n++; } - closedir(dir); - } else { - printf ("load_plugins: %s - cannot access plugin dir '%s': %s\n", - __XINE_FUNCTION__, XINE_PLUGINDIR, strerror(errno)); - } - - remove_segv_handler(); - if (!num_plugins) { - fprintf(stderr, "load_plugins: no video plugins found, make sure you have them " - "installed at %s\n", XINE_PLUGINDIR ); } + + plugin_ids[n] = NULL; + return plugin_ids; + +#endif + return NULL; } +char **xine_get_autoplay_input_plugin_ids(xine_t *this) { -vo_driver_t *xine_load_video_output_plugin(config_values_t *config, - char *id, - int visual_type, void *visual) { - DIR *dir; - vo_driver_t *vod; - -#ifdef ENABLE_NLS - bindtextdomain("xine-lib", XINE_LOCALEDIR); -#endif - -#if IGNORE_DXR3ENC - if (! strcasecmp(id, "dxr3enc")) { - printf( /* big poo poo */ - "load_plugins: *************************************************************\n" - "load_plugins: WARNING: video out driver \"dxr3enc\" no longer exists.\n" - "load_plugins: the mpeg encoding output is now integrated in the \"dxr3\"\n" - "load_plugins: driver.\n" - "load_plugins: *************************************************************\n" - ); - return 0; - } -#endif + return (_xine_get_featured_input_plugin_ids(this, INPUT_CAP_AUTOPLAY)); +} - install_segv_handler(); +char **xine_get_browsable_input_plugin_ids(xine_t *this) { - dir = opendir (XINE_PLUGINDIR); - - if (dir) { - struct dirent *dir_entry; - - while ((dir_entry = readdir (dir)) != NULL) { - char str[1024]; - void *plugin; - - int nLen = strlen (dir_entry->d_name); - - if ((strncasecmp(dir_entry->d_name, - XINE_VIDEO_OUT_PLUGIN_PREFIXNAME, - XINE_VIDEO_OUT_PLUGIN_PREFIXNAME_LENGTH) == 0) && - ((dir_entry->d_name[nLen-3]=='.') - && (dir_entry->d_name[nLen-2]=='s') - && (dir_entry->d_name[nLen-1]=='o'))) { - -#if IGNORE_DXR3ENC - if (! strncasecmp(dir_entry->d_name, - XINE_VIDEO_OUT_PLUGIN_PREFIXNAME "dxr3enc", - XINE_VIDEO_OUT_PLUGIN_PREFIXNAME_LENGTH + 7)) - { - printf("load_plugins: ignoring obsolete dxr3enc driver.\n"); - continue; - } -#endif + return (_xine_get_featured_input_plugin_ids(this, INPUT_CAP_GET_DIR)); +} - sprintf (str, "%s/%s", XINE_PLUGINDIR, dir_entry->d_name); - - if(!(plugin = dlopen (str, RTLD_LAZY | RTLD_GLOBAL))) { - printf("load_plugins: video output plugin %s failed to link:\n%s\n", - str, dlerror()); - } else { - vo_info_t* (*getinfo) (void); - vo_info_t *vo_info; +char *xine_get_input_plugin_description(xine_t *this, char *plugin_id) { - if ((getinfo = dlsym(plugin, "get_video_out_plugin_info")) != NULL) { - vo_info = getinfo(); + /* FIXME */ - if (!strcasecmp(id, vo_info->id) ) { +#if 0 + char *str; + input_plugin_t *ip; + int i; - if (vo_info->interface_version == VIDEO_OUT_DRIVER_IFACE_VERSION) { - - if(vo_info->visual_type == visual_type) { - void *(*initplug) (config_values_t *, void *); - - if((initplug = dlsym(plugin, "init_video_out_plugin")) != NULL) { - - vod = (vo_driver_t *) initplug(config, visual); - - if (vod) - printf("load_plugins: video output plugin %s successfully" - " loaded.\n", id); - else - printf("load_plugins: video output plugin %s: " - "init_video_out_plugin failed.\n", str); - - closedir(dir); - remove_segv_handler(); - - return vod; - } - } - else { - printf("load_plugins: video output plugin %s: " - "wrong interface visual type %d.\n", str, vo_info->visual_type); - } - } - else { - printf("load_plugins: video output plugin %s: " - "wrong interface version %d.\n", str, vo_info->interface_version); - } - } - } - } - } + if((this == NULL) || (this->num_input_plugins < 1) || (plugin_id == NULL)) + return NULL; + + for(i = 0; i < this->num_input_plugins; i++) { + + ip = this->input_plugins[i]; + + if(!strcasecmp((ip->get_identifier(ip)), plugin_id)) { + str = strdup(ip->get_description(ip)); + return str; } - closedir(dir); } +#endif - remove_segv_handler(); - - printf ("load_plugins: failed to find video output plugin <%s>\n", id); return NULL; } -/** *************************************************************** - * Audio output plugins section +/* + * video out plugins section */ -char **xine_list_audio_output_plugins(void) { - char **plugin_ids; - int num_plugins = 0; - DIR *dir; - int i,j; - int plugin_prios[50]; - - plugin_ids = (char **) xine_xmalloc (50 * sizeof (char *)); - plugin_ids[0] = NULL; - - install_segv_handler(); - -#ifdef ENABLE_NLS - bindtextdomain("xine-lib", XINE_LOCALEDIR); -#endif - - dir = opendir (XINE_PLUGINDIR); +xine_vo_driver_t *xine_open_video_driver (xine_t *this, + char *id, + int visual_type, void *visual) { - if (dir) { - struct dirent *dir_entry; - - while ((dir_entry = readdir (dir)) != NULL) { - char str[1024]; - void *plugin; - int nLen = strlen (dir_entry->d_name); - - if ((strncasecmp(dir_entry->d_name, - XINE_AUDIO_OUT_PLUGIN_PREFIXNAME, - XINE_AUDIO_OUT_PLUGIN_PREFIXNAME_LENGTH) == 0) && - ((dir_entry->d_name[nLen-3]=='.') - && (dir_entry->d_name[nLen-2]=='s') - && (dir_entry->d_name[nLen-1]=='o'))) { - - sprintf (str, "%s/%s", XINE_PLUGINDIR, dir_entry->d_name); - plugin_name = str; - - /* printf ("load_plugins: trying to load plugin %s\n", str); */ + plugin_node_t *node; + xine_vo_driver_t *driver; + vo_info_t *vo_info; - /* - * now, see if we can open this plugin, - * and get it's id - */ + driver = NULL; - if(!(plugin = dlopen (str, RTLD_LAZY))) { + node = xine_list_first_content (this->plugin_catalog->vout); + while (node) { - printf("load_plugins: cannot load plugin %s (%s)\n", - str, dlerror()); + vo_info = node->info->special_info; + if (vo_info->visual_type == visual_type) { + if (id) { + if (!strcasecmp (node->info->id, id)) { + driver = (xine_vo_driver_t*)_load_plugin (this, node->filename, + node->info, visual); + break; + } - } else { + } else { - ao_info_t* (*getinfo) (); - ao_info_t *ao_info; + driver = (xine_vo_driver_t*)_load_plugin (this, node->filename, + node->info, visual); + if (driver) + break; + + } + } + + node = xine_list_next_content (this->plugin_catalog->vout); + } -#ifdef LOG - printf ("load_plugins: plugin %s successfully loaded.\n", str); -#endif + if (!driver) + printf ("load_plugins: failed to load video output plugin <%s>\n", id); - if ((getinfo = dlsym(plugin, "get_audio_out_plugin_info")) != NULL) { - ao_info = getinfo(); + return driver; +} -#ifdef LOG - printf("load_plugins: id=%s (%s), priority=%d, interface_version=%d\n", - ao_info->id, ao_info->description, - ao_info->priority, ao_info->interface_version); -#endif +/* + * audio output plugins section + */ - if ( ao_info->interface_version == AUDIO_OUT_IFACE_VERSION) { +char **xine_list_audio_output_plugins(void) { - /* sort the list by ao_info->priority */ + return NULL; +} - i = 0; - while ( (i<num_plugins) && (ao_info->priority<plugin_prios[i]) ) - i++; - - j = num_plugins; - while (j>i) { - plugin_ids[j] = plugin_ids[j-1]; - plugin_prios[j] = plugin_prios[j-1]; - j--; - } - plugin_ids[i] = (char *) malloc (strlen(ao_info->id)+1); - strcpy (plugin_ids[i], ao_info->id); - plugin_prios[i] = ao_info->priority; +xine_ao_driver_t *xine_open_audio_driver (xine_t *this, char *id, + void *data) { - num_plugins++; - plugin_ids[num_plugins] = NULL; - } else { + plugin_node_t *node; + xine_ao_driver_t *driver; + ao_info_t *ao_info; - printf ("load_plugins: audio output plugin >%s< doesn't support interface version %d\n", - ao_info->id, AUDIO_OUT_IFACE_VERSION); + driver = NULL; - } - } else { + node = xine_list_first_content (this->plugin_catalog->aout); + while (node) { - printf("load_plugins: %s seems to be an invalid plugin " - "(lacks get_audio_out_plugin_info() function)\n", str); + ao_info = node->info->special_info; - } - dlclose (plugin); - } + if (id) { + if (!strcasecmp(node->info->id, id)) { + driver = (xine_ao_driver_t*)_load_plugin(this, node->filename, node->info, data); + break; } + } else { + driver = (xine_ao_driver_t*)_load_plugin (this, node->filename, node->info, data); + if (driver) + break; } - closedir(dir); - } else { - printf ("load_plugins: %s - cannot access plugin dir: %s", - __XINE_FUNCTION__, strerror(errno)); - } - - remove_segv_handler(); - - return plugin_ids; -} - -ao_driver_t *xine_load_audio_output_plugin(config_values_t *config, char *id) { - DIR *dir; - ao_driver_t *aod = NULL; - - install_segv_handler(); - -#ifdef ENABLE_NLS - bindtextdomain("xine-lib", XINE_LOCALEDIR); -#endif - - dir = opendir (XINE_PLUGINDIR); - - if (dir) { - struct dirent *pEntry; - - while ((pEntry = readdir (dir)) != NULL) { - char str[1024]; - void *plugin; - int nLen = strlen (pEntry->d_name); - - aod = NULL; - memset(&str, 0, 1024); - - if ((strncasecmp(pEntry->d_name, - XINE_AUDIO_OUT_PLUGIN_PREFIXNAME, - XINE_AUDIO_OUT_PLUGIN_PREFIXNAME_LENGTH) == 0) && - ((pEntry->d_name[nLen-3]=='.') - && (pEntry->d_name[nLen-2]=='s') - && (pEntry->d_name[nLen-1]=='o'))) { - - sprintf (str, "%s/%s", XINE_PLUGINDIR, pEntry->d_name); - /* RTLD_GLOBAL is needed when using ALSA09 */ - if(!(plugin = dlopen (str, RTLD_LAZY | RTLD_GLOBAL))) { - printf("load_plugins: audio output plugin %s failed to link: %s\n", - str, dlerror()); - /* return NULL; */ - } else { - void *(*initplug) (config_values_t *); - ao_info_t* (*getinfo) (); - ao_info_t *ao_info; - - if ((getinfo = dlsym(plugin, "get_audio_out_plugin_info")) != NULL) { - ao_info = getinfo(); - - if (!strcasecmp(id, ao_info->id)) { - - if((initplug = dlsym(plugin, "init_audio_out_plugin")) != NULL) { - - aod = (ao_driver_t *) initplug(config); - - if (aod) - printf("load_plugins: audio output plugin %s successfully" - " loaded.\n", id); - else - printf("load_plugins: audio output plugin %s: " - "init_audio_out_plugin failed.\n", str); - - closedir(dir); - remove_segv_handler(); - return aod; - } - } - } - } - } - } - closedir(dir); + node = xine_list_next_content (this->plugin_catalog->aout); } - remove_segv_handler(); - return NULL; -} + if (!driver) { + if (id) + printf ("load_plugins: failed to load audio output plugin <%s>\n", id); + else + printf ("load_plugins: audio output auto-probing didn't find any usable audio driver.\n"); + } + return driver; +} /** *************************************************************** * Autoplay featured plugins section */ char **xine_get_autoplay_mrls (xine_t *this, char *plugin_id, int *num_mrls) { + + /* FIXME */ + +#if 0 input_plugin_t *ip; char **autoplay_mrls = NULL; int i; @@ -1113,12 +759,22 @@ char **xine_get_autoplay_mrls (xine_t *this, char *plugin_id, int *num_mrls) { autoplay_mrls_done: return autoplay_mrls; + + +#endif + return NULL; } -/** *************************************************************** - * Browse featured plugins section +/* + * browse featured plugins section */ -mrl_t **xine_get_browse_mrls (xine_t *this, char *plugin_id, char *start_mrl, int *num_mrls) { +xine_mrl_t **xine_get_browse_mrls (xine_t *this, char *plugin_id, + char *start_mrl, int *num_mrls) { + + /* FIXME */ + +#if 0 + input_plugin_t *ip; mrl_t **browse_mrls = NULL; int i; @@ -1148,4 +804,79 @@ mrl_t **xine_get_browse_mrls (xine_t *this, char *plugin_id, char *start_mrl, in browse_mrls_done: return browse_mrls; + +#endif + return NULL; +} + +video_decoder_t *get_video_decoder (xine_t *this, uint8_t stream_type) { + + plugin_node_t *node; + +#ifdef LOG + printf ("load_plugins: looking for video decoder for streamtype %02x\n", + stream_type); +#endif + + node = this->plugin_catalog->video_decoder_map[stream_type]; + + if (!node) + return NULL; + + if (!node->plugin) + node->plugin = _load_plugin(this, node->filename, node->info, NULL); + + return node->plugin; +} + +audio_decoder_t *get_audio_decoder (xine_t *this, uint8_t stream_type) { + + plugin_node_t *node; + +#ifdef LOG + printf ("load_plugins: looking for audio decoder for streamtype %02x\n", + stream_type); +#endif + + node = this->plugin_catalog->audio_decoder_map[stream_type]; + + if (!node) + return NULL; + + if (!node->plugin) + node->plugin = _load_plugin(this, node->filename, node->info, NULL); + + return node->plugin; +} + +spu_decoder_t *get_spu_decoder (xine_t *this, uint8_t stream_type) { + return NULL; /* FIXME */ +} + + +/* + * dispose all currently loaded plugins (shutdown) + */ + +void dispose_plugins (xine_t *this) { + + /* FIXME: adapt old code */ + +#if 0 + for (i = 0; i < this->num_demuxer_plugins; i++) + this->demuxer_plugins[i]->close (this->demuxer_plugins[i]); + + for (i = 0; i < this->num_input_plugins; i++) + this->input_plugins[i]->dispose (this->input_plugins[i]); + + for (i = 0; i < this->num_audio_decoders_loaded; i++) + this->audio_decoders_loaded[i]->dispose (this->audio_decoders_loaded[i]); + + for (i = 0; i < this->num_video_decoders_loaded; i++) + this->video_decoders_loaded[i]->dispose (this->video_decoders_loaded[i]); + + for (i = 0; i < this->num_spu_decoders_loaded; i++) + this->spu_decoders_loaded[i]->dispose (this->spu_decoders_loaded[i]); + +#endif } diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c index be5291e78..af5b28a70 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.90 2002/09/01 13:50:07 heikos Exp $ + * $Id: metronom.c,v 1.91 2002/09/04 23:31:13 guenter Exp $ */ #ifdef HAVE_CONFIG_H @@ -137,7 +137,7 @@ static void unixscr_start (scr_plugin_t *scr, int64_t start_vpts) { pthread_mutex_unlock (&this->lock); - unixscr_set_speed (&this->scr, SPEED_NORMAL); + unixscr_set_speed (&this->scr, XINE_SPEED_NORMAL); } static int64_t unixscr_get_current (scr_plugin_t *scr) { @@ -183,7 +183,7 @@ static scr_plugin_t* unixscr_init () { pthread_mutex_init (&this->lock, NULL); - unixscr_set_speed (&this->scr, SPEED_PAUSE); + unixscr_set_speed (&this->scr, XINE_SPEED_PAUSE); printf("xine-scr_init: complete\n"); return &this->scr; @@ -215,13 +215,13 @@ static int64_t metronom_get_current_time (metronom_t *this) { static void metronom_stop_clock(metronom_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, SPEED_PAUSE); + if (*scr) (*scr)->set_speed(*scr, XINE_SPEED_PAUSE); } static void metronom_resume_clock(metronom_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, SPEED_NORMAL); + if (*scr) (*scr)->set_speed(*scr, XINE_SPEED_NORMAL); } @@ -657,7 +657,7 @@ static int metronom_sync_loop (metronom_t *this) { scr_plugin_t** scr; int64_t pts; - while (((xine_t*)this->xine)->status != XINE_QUIT) { + while (((xine_t*)this->xine)->status != XINE_STATUS_QUIT) { pts = this->scr_master->get_current(this->scr_master); for (scr = this->scr_list; scr < this->scr_list+MAX_SCR_PROVIDERS; scr++) diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c index bff328206..3e3eb521d 100644 --- a/src/xine-engine/osd.c +++ b/src/xine-engine/osd.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2000-2001 the xine project + * Copyright (C) 2000-2002 the xine project * - * This file is part of xine, a unix video player. + * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +33,6 @@ #include <sys/types.h> #include <dirent.h> -#include "events.h" #include "xine_internal.h" #include "video_out/alphablend.h" #include "xine-engine/bswap.h" @@ -828,7 +827,7 @@ static void osd_renderer_close (osd_renderer_t *this) { } -static void update_text_palette(void *this_gen, cfg_entry_t *entry) +static void update_text_palette(void *this_gen, xine_cfg_entry_t *entry) { osd_renderer_t *this = (osd_renderer_t *)this_gen; @@ -870,7 +869,7 @@ osd_renderer_t *osd_renderer_init( video_overlay_instance_t *video_overlay, conf this->textpalette = config->register_enum (config, "misc.osd_text_palette", 0, textpalettes_str, _("Palette (foreground-border-background) to use on subtitles"), - NULL, update_text_palette, this); + NULL, 10, update_text_palette, this); /* * set up function pointer diff --git a/src/xine-engine/plugin_catalog.h b/src/xine-engine/plugin_catalog.h new file mode 100644 index 000000000..e674f389d --- /dev/null +++ b/src/xine-engine/plugin_catalog.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2000-2002 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: plugin_catalog.h,v 1.2 2002/09/04 23:31:13 guenter Exp $ + * + * xine-internal header: Definitions for plugin lists + * + */ + +#ifndef _PLUGIN_CATALOG_H +#define _PLUGIN_CATALOG_H + +#include "xine_plugin.h" +#include "xineutils.h" + +#define DECODER_MAX 256 + +typedef struct { + char *filename; + plugin_info_t *info; + void *plugin; +} plugin_node_t ; + +struct plugin_catalog_s { + xine_list_t *input; + xine_list_t *demux; + xine_list_t *spu; + xine_list_t *audio; + xine_list_t *video; + xine_list_t *aout; + xine_list_t *vout; + + plugin_node_t *audio_decoder_map[DECODER_MAX]; + plugin_node_t *video_decoder_map[DECODER_MAX]; + plugin_node_t *spu_decoder_map[DECODER_MAX]; +}; +typedef struct plugin_catalog_s plugin_catalog_t; + +/* + * load plugins into catalog + * + * all input+demux plugins will be fully loaded+initialized + * decoder plugins are loaded on demand + * video/audio output plugins have special load/probe functions + */ +void scan_plugins (xine_t *this); + + +/* + * dispose all currently loaded plugins (shutdown) + */ + +void dispose_plugins (xine_t *this); + +#endif diff --git a/src/xine-engine/tvmode.c b/src/xine-engine/tvmode.c index 6c5bf45c3..700e6d774 100644 --- a/src/xine-engine/tvmode.c +++ b/src/xine-engine/tvmode.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: tvmode.c,v 1.7 2002/08/03 17:33:06 siggi Exp $ + * $Id: tvmode.c,v 1.8 2002/09/04 23:31:13 guenter Exp $ * * tvmode - TV output selection * @@ -30,103 +30,76 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <ctype.h> #include <unistd.h> -#include <limits.h> #include "nvtvd.h" -#include "xine_internal.h" -/* FIXME: how to include that? */ -/*#include "xine.h" */ #include "xine_internal.h" #include "xineutils.h" -#define ABS(x) ((x)>0?(x):-(x)) -#define APPROX(x,y) (ABS((x)-(y)) < 1e-2) /* less than 1% difference */ - /* * PRIVATE */ -/* TODO: config */ -static TVConnect opt_connect = CONNECT_AUTO; -static int opt_flicker = -1; - -typedef struct { - int width, height; - int fps; - int quality; - char overscan[16]; -} scan_mode_t; - /* FIXME: currently the used backend only supports one (1) connection * to a server and needs this global, external pointer */ -/* Thus we do not care about saving data in a own structure now... */ BackCardRec *back_card = 0; BackAccessRec *back_access = 0; -static int tv_stream_width, tv_stream_height; -static double tv_stream_fps; -static int tv_current_type, tv_current_system; -static int tv_current_width, tv_current_height; -static double tv_current_fps; -static TVCrtRegs tv_old_crt; -static TVRegs tv_old_tv; - -static int tv_verbose; -static int tv_capabilities; -static int tv_policy; -static int tv_prefered_fps; -static double tv_aspect; - -/* This is the list of possible modes for the used refresh rates */ -static const char *tv_scan_mode; - -/* Constant data */ -enum { TV_CAP_PAL = 1, TV_CAP_PAL60 = 2, TV_CAP_NTSC = 4 }; -static char *tv_systems_list[] = { - "No TV connected", "PAL only", "NTSC only", - "PAL and PAL60", "PAL and NTSC", "PAL, PAL60, NTSC", NULL -}; -static const int tv_system_caps[] = { - 0, TV_CAP_PAL, TV_CAP_NTSC, - TV_CAP_PAL|TV_CAP_PAL60, TV_CAP_PAL|TV_CAP_NTSC, - TV_CAP_PAL|TV_CAP_PAL60|TV_CAP_NTSC -}; - -#define SCAN_NATIVE_25 576 -#define SCAN_NATIVE_30 480 -static char *tv_scan_mode_default = -"768x576*25,800x576*25,720x576*25,704x576*25," /* Best PAL modes */ -"768x480*30,800x480*30,720x480*30," /* Best NTSC modes */ -"640x576*25,640x480*30,480x576*25,480x480*30," /* Smaller width modes */ -"800x600,800x450,1024x768"; /* Non-Native modes */ -/* Modes that are not included due to common misconfigurations: - * 640x400*30,640x480*25 - */ -enum { TV_POL_FPS_BEST = 0, TV_POL_FPS_MATCH, - TV_POL_FPS_LIST, TV_POL_MATCH_FPS }; -static char *tv_policies_list[] = { - "FPS - Best Native Match", "FPS - Best Match", "FPS - List Order", - "Best Match - FPS", NULL -}; - -static char *tv_aspect_list[] = { - "4:3", "16:9", NULL -}; -static const double tv_aspect_aspects[] = { 4.0/3.0, 16.0/9.0 }; +static int current_type, current_width, current_height; +static double current_fps; +static TVCrtRegs old_crt; +static TVRegs old_tv; + +static int tvmode_enabled; +static int was_enabled = 0; + + +/* TODO: config, and better */ +static TVSystem opt_system = TV_SYSTEM_PAL; +static TVConnect opt_connect = CONNECT_AUTO; + +/* This is the list of possible modes for the used TV system. + * TODO: + * if select_origsize == false: + * The one closest (but larger) to the input stream size is selected. + * if select_origsize == true: + * The first available mode is selected (stick to tv resolution) */ +static int scan_mode_pal[][2] = { + { 768, 576 }, { 800, 576 }, { 720, 576 }, + { 800, 600 }, + { 720, 480 }, { 640, 480 }, + { 800, 450 }, + { 1024, 768 }, + { 0 } +} ; /* Overscan sizes to be scaned for - note that we do *not* scan for 'Small' */ static char *scan_overscan[] = { - "DVD", "Interl", "Huge", "Large", "Normal", 0 -}; + "Interl", "Huge", "Large", "DVD", "Normal", 0 +} ; +/* TODO: flexible */ +static int opt_flicker = -1; +static double opt_aspect = 4.0 / 3.0; /* Just turn off warnings */ -void xine_tvmode_exit (void); -void xine_tvmode_exit2 (xine_t *this); +static void _tvmode_init(xine_t *this); +void xine_tvmode_exit (xine_t *this); +/* + * Config callback for tvmode enability. + */ +static void nvtvmode_enable_cb(void *this_gen, xine_cfg_entry_t *entry) { + xine_t *this = (xine_t *) this_gen; + + tvmode_enabled = entry->num_value; + + if(!tvmode_enabled && was_enabled) { + xine_tvmode_exit(this); + was_enabled = 0; + } +} /* Try to connect to nvtvd server */ static void tvmode_connect(xine_t *this) { @@ -143,158 +116,35 @@ static void tvmode_connect(xine_t *this) { back_card = 0; } - if (back_card) - { - printf ("tvmode: connected to nvtvd\n"); - back_card->openCard (card); + if (back_card) { + back_card->openCard (card); + was_enabled = 1; } else - printf ("tvmode: cannot connect to nvtvd - TV mode switching disabled\n"); + printf("tvmode: cannot connect to nvtvd - no TV mode switching available\n"); } /* Disconnect from server */ static void tvmode_disconnect (xine_t *this) { back_card->closeCard (); - printf ("tvmode: disconnected\n"); back_card = 0; } /* Save current CRT and TV register configuration */ static void tvmode_savestate (xine_t *this) { - back_card->getMode (&tv_old_crt, &tv_old_tv); + back_card->getMode (&old_crt, &old_tv); } /* Restore CRT and TV register configuration */ static void tvmode_restorestate (xine_t *this) { - printf ("tvmode: switching back to regular display\n"); - back_card->setMode (0, &tv_old_crt, &tv_old_tv); - tv_current_type = 0; + back_card->setMode (0, &old_crt, &old_tv); + current_type = 0; } -/* Connect to nvtvd server if possible and save current card config */ -static void tvmode_startup (xine_t *this) { - if (tv_capabilities && ! back_card) - tvmode_connect (this); - if (back_card) - tvmode_savestate (this); -} - - -/* Disconnect and recover */ -static void tvmode_closedown (xine_t *this) { - if (back_card) { - tvmode_restorestate (this); - tvmode_disconnect (this); - } -} - - -/* Sort callback */ -static int tvmode_cmp_scanmode_cb (const void *a, const void *b) { - return ((const scan_mode_t *) b) -> quality - - ((const scan_mode_t *) a) -> quality; -} - - -/* Parse mode string and set mode scan table accordingly */ -/* Returns next free mode slot */ -/* Table will be sorted based on prefwidth/prefheight/fps, when sortmode!=0 */ -static scan_mode_t *set_modes (xine_t *this, scan_mode_t *modes, int maxnum, - scan_mode_t *sortmodes, - const char *string, int fps, - int prefwidth, int minwidth, int maxwidth, - int prefheight, int minheight, int maxheight) { - const char *s = string; - int num = 0; - int i, w, h, f; - char overscan[16], *os; - - /* Check whether system is available */ - if (fps == 30 && ! (tv_capabilities & (TV_CAP_PAL60 | TV_CAP_NTSC))) - return modes; - if (fps == 25 && ! (tv_capabilities & TV_CAP_PAL)) - return modes; - - if (tv_verbose) - printf ("tmode: selecting modes, preferred %dx%d fps %d, min %dx%d\n", - prefwidth, prefheight, fps, minwidth, minheight); - /* scan modes */ - while (num < maxnum) { - while (isspace ((int) *s) || *s == ',') s++; - if (! *s) - break; - i = w = h = -1; - sscanf (s, " %d x %d %n", &w, &h, &i); - if (i < 2 || w <= 0 || h <= 0) { - printf ("tvmode: mode line syntax error after '%s'\n", s); - break; - } - s += i; - overscan [0] = 0; - if (*s == '/') { - s++; - os = overscan; - while (isspace ((int) *s)) s++; - while (isalnum ((int) *s) && os < &overscan[16-1]) - *os++ = *s++; - *os = 0; - } - f = fps; - if (*s == '*') { - f = -1; - sscanf (s, "* %d %n", &f, &i); - if (i < 1 || f <= 0) { - printf ("tvmode: mode line syntax error after '%s'\n", s); - break; - } - s += i; - } - if (w >= minwidth && w <= maxwidth - && h >= minheight && h <= maxheight - && f == fps) { - - int diff = prefwidth*prefheight - w*h; - modes[num].width = w; - modes[num].width = w; - modes[num].height = h; - modes[num].fps = f; - strncpy (modes[num].overscan, overscan, 16); - /* Set quality = Size diff in pixels + Diff in fps - * + penalty for too small sizes */ - modes[num].quality = - ABS (diff) - ABS (f - fps) - - (prefwidth > w ? 1000 * h : 0) - - (prefheight > h ? 2000 * w : 0); - if (tv_verbose) - printf ("tvmode: entry %dx%d [%s] fps %d quality %d\n", - w, h, overscan, f, modes[num].quality); - num++; - } else { - if (tv_verbose) - printf ("tvmode: entry %dx%d [%s] fps %d rejected\n", - w, h, overscan, f); - } - if (*s != ',') { - if (*s) - printf ("tvmode: mode line syntax error after '%s'\n", s); - break; - } - } - if (num >= maxnum) - printf ("tvmode: mode array overflow - some modes are not tested\n"); - if (! sortmodes) - return modes + num; - /* Now sort */ - qsort (sortmodes, (modes-sortmodes) + num, sizeof (scan_mode_t), - tvmode_cmp_scanmode_cb); - if (tv_verbose) - printf ("tvmode: sorted\n"); - return modes + num; -} - /* Set CRT and TV registers to given TV-Out configuration */ static void tvmode_settvstate (xine_t *this, int width, int height, double fps) { @@ -303,184 +153,43 @@ static void tvmode_settvstate (xine_t *this, int width, int height, double fps) TVCrtRegs crt; TVRegs tv; int found = 0; - scan_mode_t modes[256]; /* FIXME: shouldn't be fix */ - scan_mode_t *m = modes; - scan_mode_t *last_mode; - int best_rate; - char **scano; - char *current_overscan = ""; - TVSystem sys; - int i; - - if (tv_verbose) - printf ("tvmode: Requested mode for %dx%d, %g fps\n", - width, height, fps); - + int *scanm; + char **scano; + /* Modify the settings */ back_card->getSettings (&settings); - settings.connector = opt_connect; - if (opt_flicker >= 0) - settings.flicker = opt_flicker; - - /* Check fps for capability selection */ - best_rate = tv_prefered_fps; - if (APPROX (fps, 60) || APPROX (fps, 30) || - APPROX (fps, 20) || APPROX (fps, 15)) - best_rate = 30; - if (APPROX (fps, 50) || APPROX (fps, 25) || - APPROX (fps, 50.0/3) || APPROX (fps, 12.5)) - best_rate = 25; - - /* Scan mode strings and create scan table */ - /* TODO: do that at initialization and save possible combinations ?!? */ - switch (tv_policy) { - case TV_POL_FPS_BEST: - if (APPROX (fps, 24)) /* FIXME: hardcoded for this policy only */ - best_rate = 30; - if (best_rate == 30) - { - m = set_modes (this, m, &modes[256]-m, m, tv_scan_mode, 30, - width, 0, INT_MAX, - SCAN_NATIVE_30, SCAN_NATIVE_30, SCAN_NATIVE_30); - m = set_modes (this, m, &modes[256]-m, m, tv_scan_mode, 30, - width, 0, INT_MAX, height, 0, INT_MAX); - } - m = set_modes (this, m, &modes[256]-m, m, tv_scan_mode, 25, - width, 0, INT_MAX, - SCAN_NATIVE_25, SCAN_NATIVE_25, SCAN_NATIVE_25); - m = set_modes (this, m, &modes[256]-m, m, tv_scan_mode, 25, - width, 0, INT_MAX, height, 0, INT_MAX); - if (best_rate != 30) - { - m = set_modes (this, m, &modes[256]-m, m, tv_scan_mode, 30, - width, 0, INT_MAX, - SCAN_NATIVE_30, SCAN_NATIVE_30, SCAN_NATIVE_30); - m = set_modes (this, m, &modes[256]-m, m, tv_scan_mode, 30, - width, 0, INT_MAX, height, 0, INT_MAX); - } - break; - case TV_POL_FPS_MATCH: - if (best_rate == 30) - m = set_modes (this, m, &modes[256]-m, m, tv_scan_mode, 30, - width, 0, INT_MAX, height, 0, INT_MAX); - m = set_modes (this, m, &modes[256]-m, m, tv_scan_mode, 25, - width, 0, INT_MAX, height, 0, INT_MAX); - if (best_rate != 30) - m = set_modes (this, m, &modes[256]-m, m, tv_scan_mode, 30, - width, 0, INT_MAX, height, 0, INT_MAX); - break; - case TV_POL_FPS_LIST: - if (best_rate == 30) - m = set_modes (this, m, &modes[256]-m, NULL, tv_scan_mode, 30, - width, 0, INT_MAX, height, 0, INT_MAX); - m = set_modes (this, m, &modes[256]-m, NULL, tv_scan_mode, 25, - width, 0, INT_MAX, height, 0, INT_MAX); - if (best_rate != 30) - m = set_modes (this, m, &modes[256]-m, NULL, tv_scan_mode, 30, - 0, 0, INT_MAX, 0, 0, INT_MAX); - break; - case TV_POL_MATCH_FPS: - if (height <= SCAN_NATIVE_30 && best_rate == 30) { - m = set_modes (this, m, &modes[256]-m, NULL, tv_scan_mode, 30, - width, 0, INT_MAX, height, 0, INT_MAX); - m = set_modes (this, m, &modes[256]-m, modes, tv_scan_mode, 25, - width, 0, INT_MAX, height, 0, INT_MAX); - } else { - m = set_modes (this, m, &modes[256]-m, NULL, tv_scan_mode, 25, - width, 0, INT_MAX, height, 0, INT_MAX); - m = set_modes (this, m, &modes[256]-m, modes, tv_scan_mode, 30, - width, 0, INT_MAX, height, 0, INT_MAX); - } - break; - default: - abort (); + if (opt_connect > CONNECT_NONE) { + settings.connector = opt_connect; + } else { + settings.connector = CONNECT_BOTH; } - last_mode = m; - - if (tv_verbose) { - printf ("tvmode: ->"); - for (i = 0; i < last_mode-modes; i++) - printf (" %dx%d/%s*%d", modes[i].width, modes[i].height, - modes[i].overscan, modes[i].fps); - printf ("\n"); + if (opt_flicker >= 0) { + settings.flicker = opt_flicker; } - - /* Select first mode that is actually known to the chip */ - for (m = modes; m < last_mode && !found; m++) { - sys = TV_SYSTEM_PAL; - if (m->fps == 30 && (tv_capabilities & TV_CAP_PAL60)) - sys = TV_SYSTEM_PAL_60; - else if (m->fps == 30 && (tv_capabilities & TV_CAP_NTSC)) - sys = TV_SYSTEM_NTSC; - if (! *m->overscan) { - for (scano = scan_overscan; *scano && !found; scano++) { - if (tv_verbose) - printf ("tvmore: trying to use %dx%d [%s] fps %d\n", - m->width, m->height, *scano, m->fps); - if (back_card->findBySize (sys, m->width, m->height, *scano, - &mode, &crt, &tv)) { - tv_current_width = m->width; - tv_current_height = m->height; - tv_current_system = sys; - tv_current_fps = m->fps; - current_overscan = *scano; - found++; - } else if (sys == TV_SYSTEM_PAL_60 && - (tv_capabilities & TV_CAP_NTSC) && - back_card->findBySize (TV_SYSTEM_NTSC, - m->width, m->height, *scano, - &mode, &crt, &tv)) { - tv_current_width = m->width; - tv_current_height = m->height; - tv_current_system = TV_SYSTEM_NTSC; - tv_current_fps = m->fps; - current_overscan = *scano; - found++; - } - } - } else { - if (tv_verbose) - printf ("tvmore: trying to use %dx%d [%s] fps %d\n", - m->width, m->height, m->overscan, m->fps); - if (back_card->findBySize (sys, m->width, m->height, m->overscan, + /* TODO: do that at initialization and save possible combinations */ + /* Find supported TV mode */ + for (scanm = &scan_mode_pal[0][0]; *scanm && ! found; scanm += 2) { + for (scano = scan_overscan; *scano && ! found; scano++) { + printf("tvmode: trying to use %dx%d %s\n", + scanm[0], scanm[1], *scano); + if (back_card->findBySize (opt_system, scanm[0], scanm[1], *scano, &mode, &crt, &tv)) { - tv_current_width = m->width; - tv_current_height = m->height; - tv_current_system = sys; - tv_current_fps = m->fps; - current_overscan = m->overscan; - found++; - } else if (sys == TV_SYSTEM_PAL_60 && - (tv_capabilities & TV_CAP_NTSC) && - back_card->findBySize (TV_SYSTEM_NTSC, - m->width, m->height, m->overscan, - &mode, &crt, &tv)) { - tv_current_width = m->width; - tv_current_height = m->height; - tv_current_system = TV_SYSTEM_NTSC; - tv_current_fps = m->fps; - current_overscan = m->overscan; + current_width = scanm[0]; + current_height = scanm[1]; + current_fps = 25; /* TODO: currently this is PAL only */ found++; } } } - - /* Modify found Crt settings */ - crt.PrivFlags &= ~TV_MODE_MACROVISION; /* Switch to mode */ if (found) { - printf ("tvmode: Switching to TV %dx%d [%s] fps %g %s\n", - tv_current_width, tv_current_height, current_overscan, - tv_current_fps, tv_current_system == TV_SYSTEM_PAL ? "PAL" : - tv_current_system == TV_SYSTEM_PAL_60 ? "PAL60" : - tv_current_system == TV_SYSTEM_NTSC ? "NTSC" : "UNKNOWN"); back_card->setModeSettings (TV_PRIV_TVMODE | TV_PRIV_DUALVIEW, &crt, &tv, &settings); - tv_current_type = 1; + current_type = 1; } else { - printf ("tvmode: cannot find any valid TV mode - TV output disabled\n"); - tvmode_closedown (this); + printf("tvmode: cannot find any valid TV mode - TV output disabled\n"); + xine_tvmode_exit (this); } } @@ -490,184 +199,87 @@ static void tvmode_settvstate (xine_t *this, int width, int height, double fps) */ /* Set to 'regular'(0) or 'tv'(1) state, that is if it is enabled */ -int xine_tvmode_switch2 (xine_t *this, int type, int width, int height, double fps) { +int xine_tvmode_switch (xine_t *this, int type, int width, int height, double fps) { + if(tvmode_enabled) { + + /* + * Wasn't initialized + */ + if(!was_enabled) + _tvmode_init(this); + if (back_card) { + printf("tvmode: switching to %s\n", type ? "TV" : "default"); switch (type) { case 0: tvmode_restorestate (this); break; case 1: - tv_stream_width = width; - tv_stream_height = height; - tv_stream_fps = fps; tvmode_settvstate (this, width, height, fps); break; default: - printf ("tvmode: illegal type for switching\n"); + printf("tvmode: illegal type for switching\n"); tvmode_restorestate (this); } + } else { + printf("tvmode: not connected to nvtvd for switching\n"); } - return tv_current_type; + + } + + return current_type; } /* Addapt (maximum) output size to visible area and set pixel aspect and fps */ -void xine_tvmode_size2 (xine_t *this, int *width, int *height, +void xine_tvmode_size (xine_t *this, int *width, int *height, double *pixelratio, double *fps) { - switch (tv_current_type) { + if(tvmode_enabled) { + + switch (current_type) { case 1: - if (width && *width > tv_current_width) - *width = tv_current_width; - if (height && *height > tv_current_height) - *height = tv_current_height; - if (pixelratio) - *pixelratio = ((double) tv_current_width / tv_current_height) - / tv_aspect; - if (fps) - *fps = tv_current_fps; - break; + if (width && *width > current_width) + *width = current_width; + if (height && *height > current_height) + *height = current_height; + if (pixelratio) + *pixelratio = ((double) current_width / current_height) / opt_aspect; + if (fps) + *fps = current_fps; + break; } -} - -/* Configuration callbacks */ -static void tvmode_system_cb (void *data, cfg_entry_t *entry) { - xine_t *this = (xine_t *) data; - tv_capabilities = tv_system_caps [entry->num_value]; - if (tv_capabilities && !back_card) - tvmode_startup (this); - else if (!tv_capabilities && back_card) - tvmode_closedown (this); -} -static void tvmode_policy_cb (void *data, cfg_entry_t *entry) { - xine_t *this = (xine_t *) data; - tv_policy = entry->num_value; - xine_tvmode_switch2 (this, tv_current_type, tv_stream_width, - tv_stream_height, tv_stream_fps); -} -static void tvmode_mode_cb (void *data, cfg_entry_t *entry) { - xine_t *this = (xine_t *) data; - tv_scan_mode = entry->str_value; - if (this && *tv_scan_mode == '-') - /*^^^^^^^ FIXME: this check can be removed in new API */ - this->config->update_string (this->config, "tv.modes", tv_scan_mode_default); - xine_tvmode_switch2 (this, tv_current_type, tv_stream_width, - tv_stream_height, tv_stream_fps); -} -static void tvmode_aspect_cb (void *data, cfg_entry_t *entry) { - xine_t *this = (xine_t *) data; - tv_aspect = tv_aspect_aspects[entry->num_value]; - xine_tvmode_switch2 (this, tv_current_type, tv_stream_width, - tv_stream_height, tv_stream_fps); -} -static void tvmode_preferred_fps_cb (void *data, cfg_entry_t *entry) { - xine_t *this = (xine_t *) data; - tv_prefered_fps = entry->num_value ? 25 : 30; - xine_tvmode_switch2 (this, tv_current_type, tv_stream_width, - tv_stream_height, tv_stream_fps); -} -static void tvmode_verbose_cb (void *data, cfg_entry_t *entry) { - tv_verbose = entry->num_value; -} - - -/* Connect to nvtvd server if possible and register settings */ -void xine_tvmode_init2 (xine_t *this) { - /* TODO: - * more config options that can be imagined: - * - disable deinterlacing for tv mode only - * - flickerfilter - * - input filters - * - connectors + dual view - * - color systems (PAL / PAL_M / etc.) - * - FILM (24 fps) -> 50 / 60Hz / 50Hz+Speedup ? - */ - tv_capabilities = tv_system_caps [this->config->register_enum ( - this->config, "tv.capabilities", - 0, tv_systems_list, _("TV System"), - "Capabilities of the connected TV system", - tvmode_system_cb, this)]; - tv_policy = this->config->register_enum ( - this->config, "tv.policy", - 0, tv_policies_list, _("Mode Selection Policy"), - "FPS - Best Native Match:\n" - "Select system (50/60Hz) according to frame rate and TV system,\n" - "select 60Hz for FILM (24 fps),\n" - "select native resolutions only if available,\n" - "select best matching mode for given video size.\n" - "This policy prefers correct frame rates to better resolutions." - "Recommended.\n\n" - "FPS - Best Match:\n" - "Select system (50/60Hz) according to frame rate,\n" - "select 50Hz for FILM (24 fps),\n" - "select best matching mode for given video size.\n\n" - "FPS - List Order:\n" - "Select system (50/60Hz) according to frame rate,\n" - "select 50Hz for FILM (24 fps),\n" - "select first available mode in the modes list.\n\n" - "Best Match - FPS:\n" - "Select best matching mode for the given video size,\n" - "select system (50/60Hz) according to frame rate and TV system.\n" - "This policy prefers better resolutions to correct frame rates.", - tvmode_policy_cb, this); - tv_scan_mode = this->config->register_string ( - this->config, "tv.modes", - tv_scan_mode_default, _("Modes"), - "Specify valid resolutions.\n" - "<width>x<height>[/<overscan>][*<fps>][, ...]\n" - "Enter '-' to use default list.\n" - "When no overscan mode is given, the following list is tried:\n" - "'Interl', 'Huge', 'Large', 'DVD', 'Normal'\n" - "When no FPS value is given, mode is valid for both, " - "25 (PAL) and 30 (PAL60/NTSC).", - tvmode_mode_cb, this); - tv_prefered_fps = this->config->register_bool ( - this->config, "tv.preferPAL", 1, _("Prefer PAL"), - "Prefer 50Hz modes to 60Hz modes for videos " - "with nonstandard frame rates", - tvmode_preferred_fps_cb, this) - ? 25 : 30; - tv_verbose = this->config->register_bool ( - this->config, "tv.verbose", 0, _("Verbose resolution selection"), - NULL, tvmode_verbose_cb, this); - if (*tv_scan_mode == '-') - this->config->update_string (this->config, "tv.modes", tv_scan_mode_default); - tv_aspect = tv_aspect_aspects [this->config->register_enum ( - this->config, "tv.aspect", - 0, tv_aspect_list, _("Screen Aspect Ratio"), NULL, - tvmode_aspect_cb, this)]; - tvmode_startup (this); -} - -/* Restore old CRT and TV registers and close nvtvd connection */ -void xine_tvmode_exit2 (xine_t *this) { - - tvmode_closedown (this); + } } -/***************************************************************** - * - * compatibility functions - * FIXME: these should be replaced by the *2-functions in the next release - */ - -void xine_tvmode_init () { - tvmode_connect (NULL); +/* Connect to nvtvd server if possible and fetch settings */ +static void _tvmode_init(xine_t *this) { + if(tvmode_enabled) { + tvmode_connect (this); if (back_card) - tvmode_savestate (NULL); + tvmode_savestate (this); + } } - -void xine_tvmode_exit () { - - tvmode_closedown (NULL); +void xine_tvmode_init (xine_t *this) { + + tvmode_enabled = this->config->register_bool(this->config, "misc.nv_tvmode", + 0, + _("NVidia TV-Out support."), + NULL, 10, + nvtvmode_enable_cb, this); + _tvmode_init(this); } -int xine_tvmode_switch (int type, int width, int height, double fps){ - return xine_tvmode_switch2(NULL, type, width, height, fps); -} +/* Restore old CRT and TV registers and close nvtvd connection */ +void xine_tvmode_exit (xine_t *this) { -void xine_tvmode_size (int *width, int *height, double *pixelaspect, double *fps){ - xine_tvmode_size2 (NULL, width, height, pixelaspect, fps); + if(tvmode_enabled || was_enabled) { + if (back_card) { + tvmode_restorestate (this); + tvmode_disconnect (this); + } + } } + diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index b031b0a8c..af6fa4b93 100644 --- a/src/xine-engine/video_decoder.c +++ b/src/xine-engine/video_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_decoder.c,v 1.95 2002/09/04 10:49:25 mroi Exp $ + * $Id: video_decoder.c,v 1.96 2002/09/04 23:31:13 guenter Exp $ * */ @@ -38,8 +38,9 @@ */ static spu_decoder_t* update_spu_decoder(xine_t *this, int type) { + int streamtype = (type>>16) & 0xFF; - spu_decoder_t *spu_decoder = this->spu_decoder_plugins [streamtype]; + spu_decoder_t *spu_decoder = get_spu_decoder (this, streamtype); if (spu_decoder && this->cur_spu_decoder_plugin != spu_decoder) { @@ -263,7 +264,7 @@ void *video_decoder_loop (void *this_gen) { streamtype = (buf->type>>16) & 0xFF; - decoder = this->video_decoder_plugins [streamtype]; + decoder = get_video_decoder (this, streamtype); if (decoder) { diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index 5b539fc89..14c0a3ac1 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.102 2002/08/03 20:42:32 siggi Exp $ + * $Id: video_out.c,v 1.103 2002/09/04 23:31:13 guenter Exp $ * * frame allocation / queuing / scheduling / output functions */ @@ -36,9 +36,9 @@ #include <pthread.h> #include <assert.h> +#include "xine_internal.h" #include "video_out.h" #include "metronom.h" -#include "xine_internal.h" #include "xineutils.h" /* @@ -51,7 +51,7 @@ typedef struct { vo_instance_t vo; /* public part */ - vo_driver_t *driver; + xine_vo_driver_t *driver; metronom_t *metronom; xine_t *xine; @@ -365,7 +365,7 @@ static vo_frame_t * duplicate_frame( vos_t *this, vo_frame_t *img ) { image_size = img->pitches[0] * img->height; - if (img->format == IMGFMT_YV12) { + if (img->format == XINE_IMGFMT_YV12) { if (img->base[0]) xine_fast_memcpy(dupl->base[0], img->base[0], image_size); if (img->base[1]) @@ -382,7 +382,7 @@ static vo_frame_t * duplicate_frame( vos_t *this, vo_frame_t *img ) { dupl->vpts = 0; dupl->duration = img->duration; - if (img->format == IMGFMT_YV12) { + if (img->format == XINE_IMGFMT_YV12) { if (img->copy) { int height = img->height; uint8_t* src[3]; @@ -620,7 +620,7 @@ static void paused_loop( vos_t *this, int64_t vpts ) /* prevent decoder thread from allocating new frames */ this->free_img_buf_queue->locked_for_read = 1; - while( this->xine->speed == SPEED_PAUSE ) { + while( this->xine->speed == XINE_SPEED_PAUSE ) { /* we need at least one free frame to keep going */ if( this->display_img_buf_queue->first && @@ -747,7 +747,7 @@ static void *video_out_loop (void *this_gen) { do { vpts = this->metronom->get_current_time (this->metronom); - if( this->xine->speed == SPEED_PAUSE ) + if( this->xine->speed == XINE_SPEED_PAUSE ) paused_loop( this, vpts ); usec_to_sleep = (next_frame_vpts - vpts) * 100 / 9; @@ -798,6 +798,70 @@ static uint32_t vo_get_capabilities (vo_instance_t *this_gen) { return this->driver->get_capabilities (this->driver); } +static vo_frame_t * vo_duplicate_frame( vo_instance_t *this_gen, vo_frame_t *img ) { + + vo_frame_t *dupl; + /* vos_t *this = (vos_t *) this_gen; */ + int image_size; + + dupl = vo_get_frame (this_gen, img->width, img->height, img->ratio, + img->format, VO_BOTH_FIELDS ); + + image_size = img->pitches[0] * img->height; + + if (img->format == XINE_IMGFMT_YV12) { + /* The dxr3 video out plugin does not allocate memory for the dxr3 + * decoder, so we must check for NULL */ + if (img->base[0]) + xine_fast_memcpy(dupl->base[0], img->base[0], image_size); + if (img->base[1]) + xine_fast_memcpy(dupl->base[1], img->base[1], img->pitches[1] * ((img->height+1)/2)); + if (img->base[2]) + xine_fast_memcpy(dupl->base[2], img->base[2], img->pitches[2] * ((img->height+1)/2)); + } else { + if (img->base[0]) + xine_fast_memcpy(dupl->base[0], img->base[0], image_size); + } + + dupl->bad_frame = 0; + dupl->pts = 0; + dupl->vpts = 0; + dupl->duration = img->duration; + + /* Support copy; Dangerous, since some decoders may use a source that's + * not dupl->base. It's up to the copy implementation to check for NULL */ + if (img->format == XINE_IMGFMT_YV12) { + if (img->copy) { + int height = img->height; + uint8_t* src[3]; + + src[0] = dupl->base[0]; + src[1] = dupl->base[1]; + src[2] = dupl->base[2]; + while ((height -= 16) >= 0) { + dupl->copy(dupl, src); + src[0] += 16 * img->pitches[0]; + src[1] += 8 * img->pitches[1]; + src[2] += 8 * img->pitches[2]; + } + } + } else { + if (img->copy) { + int height = img->height; + uint8_t* src[3]; + + src[0] = dupl->base[0]; + + while ((height -= 16) >= 0) { + dupl->copy(dupl, src); + src[0] += 16 * img->pitches[0]; + } + } + } + + return dupl; +} + static void vo_open (vo_instance_t *this_gen) { vos_t *this = (vos_t *) this_gen; @@ -886,7 +950,7 @@ static void vo_enable_overlay (vo_instance_t *this_gen, int overlay_enabled) { } -vo_instance_t *vo_new_instance (vo_driver_t *driver, xine_t *xine) { +vo_instance_t *vo_new_instance (xine_vo_driver_t *driver, xine_t *xine) { vos_t *this; int i; diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h index 0d0ba633b..056ff72dc 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.58 2002/08/15 03:12:26 miguelfreitas Exp $ + * $Id: video_out.h,v 1.59 2002/09/04 23:31:13 guenter Exp $ * * * xine version of video_out.h @@ -46,26 +46,11 @@ extern "C" { #include <inttypes.h> #include <pthread.h> -#if 0 -#if defined(XINE_COMPILE) -#include "configfile.h" -#include "metronom.h" -#include "buffer.h" -#else -#include "xine/configfile.h" -#include "xine/metronom.h" -#include "xine/buffer.h" -#endif -#endif - typedef struct vo_frame_s vo_frame_t; -typedef struct vo_driver_s vo_driver_t ; typedef struct vo_instance_s vo_instance_t; -typedef struct vo_info_s vo_info_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 xine_s xine_t; typedef struct vo_private_s vo_private_t; @@ -103,7 +88,7 @@ struct vo_frame_s { /* "backward" references to where this frame originates from */ vo_instance_t *instance; - vo_driver_t *driver; + xine_vo_driver_t *driver; int id; /* debugging - track this frame */ @@ -215,11 +200,6 @@ struct vo_instance_s { */ #define VO_NUM_RECENT_FRAMES 2 -/* image formats that can be supported by display drivers: */ - -#define IMGFMT_YV12 0x32315659 -#define IMGFMT_YUY2 (('2'<<24)|('Y'<<16)|('U'<<8)|'Y') -/*#define IMGFMT_RGB (('R'<<24)|('G'<<16)|('B'<<8)) unused */ /* possible ratios for the VO_PROP_ASPECT_RATIO call */ @@ -254,7 +234,7 @@ struct vo_instance_s { #define VO_CAP_AUTOPAINT_COLORKEY 0x00000200 /* driver can set AUTOPAINT_COLORKEY value */ /* - * vo_driver_s contains the functions every display driver + * 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 * driver. Some of the function pointers will be copied @@ -264,27 +244,27 @@ struct vo_instance_s { #define VIDEO_OUT_DRIVER_IFACE_VERSION 6 -struct vo_driver_s { +struct xine_vo_driver_s { - uint32_t (*get_capabilities) (vo_driver_t *this); /* for constants see above */ + uint32_t (*get_capabilities) (xine_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) (vo_driver_t *this); + vo_frame_t* (*alloc_frame) (xine_vo_driver_t *this); /* * check if the given image fullfills the format specified * (re-)allocate memory if necessary */ - void (*update_frame_format) (vo_driver_t *this, vo_frame_t *img, + void (*update_frame_format) (xine_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) (vo_driver_t *this, vo_frame_t *vo_img); + void (*display_frame) (xine_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 @@ -298,18 +278,18 @@ struct vo_driver_s { * * any function pointer from this group may be set to NULL. */ - 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); + 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); /* * these can be used by the gui directly: */ - int (*get_property) (vo_driver_t *this, int property); - int (*set_property) (vo_driver_t *this, + int (*get_property) (xine_vo_driver_t *this, int property); + int (*set_property) (xine_vo_driver_t *this, int property, int value); - void (*get_property_min_max) (vo_driver_t *this, + void (*get_property_min_max) (xine_vo_driver_t *this, int property, int *min, int *max); /* @@ -319,16 +299,16 @@ struct vo_driver_s { * etc. to the driver */ - int (*gui_data_exchange) (vo_driver_t *this, int data_type, + int (*gui_data_exchange) (xine_vo_driver_t *this, int data_type, void *data); - void (*exit) (vo_driver_t *this); + void (*exit) (xine_vo_driver_t *this); /* 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) (vo_driver_t *this); + int (*redraw_needed) (xine_vo_driver_t *this); }; @@ -379,7 +359,7 @@ 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, - vo_driver_t *output, vo_frame_t *vo_img, int enabled); + xine_vo_driver_t *output, vo_frame_t *vo_img, int enabled); }; video_overlay_instance_t *video_overlay_new_instance (); @@ -390,14 +370,14 @@ video_overlay_instance_t *video_overlay_new_instance (); * a given video driver */ -vo_instance_t *vo_new_instance (vo_driver_t *driver, xine_t *xine) ; +vo_instance_t *vo_new_instance (xine_vo_driver_t *driver, xine_t *xine) ; /* * to build a dynamic video output plugin * you have to implement these functions: * * - * vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual); + * xine_vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual); * * init and set up driver so it is fully operational * @@ -410,25 +390,8 @@ vo_instance_t *vo_new_instance (vo_driver_t *driver, xine_t *xine) ; * * * - * vo_info_t *get_video_out_plugin_info (); - * - * peek at some (static) information about the plugin without initializing it - * - * parameters: none - * - * return value: vo_info_t* : some information about the plugin */ -struct vo_info_s { - - int interface_version; /* plugin interface version */ - char *id; /* id of this plugin */ - char *description; /* human-readable description of this plugin */ - int visual_type; /* visual type supported by this plugin */ - int priority; /* priority of this plugin for auto-probing */ - -}; - #ifdef __cplusplus } #endif diff --git a/src/xine-engine/video_overlay.c b/src/xine-engine/video_overlay.c index aa752ba51..11a520917 100644 --- a/src/xine-engine/video_overlay.c +++ b/src/xine-engine/video_overlay.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2000-2001 the xine project + * Copyright (C) 2000-2002 the xine project * - * This file is part of xine, a unix video player. + * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_overlay.c,v 1.23 2002/09/01 05:52:15 jcdutton Exp $ + * $Id: video_overlay.c,v 1.24 2002/09/04 23:31:13 guenter Exp $ * */ @@ -29,7 +29,6 @@ #include <fcntl.h> #include "buffer.h" -#include "events.h" #include "xine_internal.h" #include "video_out/alphablend.h" #include "xine-engine/bswap.h" @@ -548,8 +547,8 @@ static int video_overlay_event( video_overlay_t *this, int64_t vpts ) { /* This is called from video_out.c * 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, - vo_driver_t *output, vo_frame_t *vo_img, int enabled) { +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) { video_overlay_t *this = (video_overlay_t *) this_gen; int i; int32_t handle; diff --git a/src/xine-engine/vo_scale.c b/src/xine-engine/vo_scale.c index 2bad85bd9..25ebd7265 100644 --- a/src/xine-engine/vo_scale.c +++ b/src/xine-engine/vo_scale.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: vo_scale.c,v 1.4 2002/08/28 14:20:09 miguelfreitas Exp $ + * $Id: vo_scale.c,v 1.5 2002/09/04 23:31:13 guenter Exp $ * * Contains common code to calculate video scaling parameters. * In short, it will map frame dimensions to screen/window size. @@ -61,15 +61,17 @@ void vo_scale_compute_ideal_size (vo_scale_t *this) { switch (this->user_ratio) { case ASPECT_AUTO: switch (this->delivered_ratio_code) { - case XINE_ASPECT_RATIO_ANAMORPHIC: /* anamorphic */ - case XINE_ASPECT_RATIO_PAN_SCAN: /* we display pan&scan as widescreen */ + case XINE_VO_ASPECT_ANAMORPHIC: /* anamorphic */ + case XINE_VO_ASPECT_PAN_SCAN: /* we display pan&scan as widescreen */ desired_ratio = 16.0 /9.0; break; - case XINE_ASPECT_RATIO_211_1: /* 2.11:1 */ +#if 0 /* FIXME */ + case XINE_VO_ASPECT_211_1: /* 2.11:1 */ desired_ratio = 2.11/1.0; break; - case XINE_ASPECT_RATIO_SQUARE: /* square pels */ - case XINE_ASPECT_RATIO_DONT_TOUCH: /* probably non-mpeg stream => don't touch aspect ratio */ +#endif + case XINE_VO_ASPECT_SQUARE: /* square pels */ + case XINE_VO_ASPECT_DONT_TOUCH: /* probably non-mpeg stream => don't touch aspect ratio */ desired_ratio = image_ratio; break; case 0: /* forbidden -> 4:3 */ @@ -77,7 +79,7 @@ void vo_scale_compute_ideal_size (vo_scale_t *this) { default: printf ("vo_scale: unknown aspect ratio (%d) in stream => using 4:3\n", this->delivered_ratio_code); - case XINE_ASPECT_RATIO_4_3: /* 4:3 */ + case XINE_VO_ASPECT_4_3: /* 4:3 */ desired_ratio = 4.0 / 3.0; break; } @@ -96,22 +98,24 @@ void vo_scale_compute_ideal_size (vo_scale_t *this) { desired_ratio = 4.0 / 3.0; } - corr_factor = this->display_ratio * desired_ratio / image_ratio ; - - if (fabs(corr_factor - 1.0) < 0.005) { - this->ideal_width = this->delivered_width; - this->ideal_height = this->delivered_height; - - } else { - - if (corr_factor >= 1.0) { - this->ideal_width = this->delivered_width * corr_factor + 0.5; - this->ideal_height = this->delivered_height; - } else { - this->ideal_width = this->delivered_width; - this->ideal_height = this->delivered_height / corr_factor + 0.5; - } + this->video_pixel_aspect = desired_ratio / image_ratio; + + assert (this->gui_pixel_aspect != 0.0); + if (fabs (this->video_pixel_aspect / this->gui_pixel_aspect - 1.0) + < 0.005) { + this->video_pixel_aspect = this->gui_pixel_aspect; + } + +#if 0 + + /* onefield_xv divide by 2 the number of lines */ + if (this->deinterlace_enabled + && (this->deinterlace_method == DEINTERLACE_ONEFIELDXV) + && (this->cur_frame->format == XINE_IMGFMT_YV12)) { + this->displayed_height = this->displayed_height / 2; + this->displayed_yoffset = this->displayed_yoffset / 2; } +#endif } } @@ -241,13 +245,15 @@ void vo_scale_compute_output_size (vo_scale_t *this) { int vo_scale_redraw_needed (vo_scale_t *this) { int gui_x, gui_y, gui_width, gui_height, gui_win_x, gui_win_y; + double gui_aspect; int ret = 0; if( this->frame_output_cb ) { this->frame_output_cb (this->user_data, this->ideal_width, this->ideal_height, + this->video_pixel_aspect, &gui_x, &gui_y, &gui_width, &gui_height, - &gui_win_x, &gui_win_y ); + &gui_aspect, &gui_win_x, &gui_win_y ); } else { printf ("vo_scale: error! frame_output_cb must be set!\n"); } diff --git a/src/xine-engine/vo_scale.h b/src/xine-engine/vo_scale.h index 934da69e5..cbd04c4cb 100644 --- a/src/xine-engine/vo_scale.h +++ b/src/xine-engine/vo_scale.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: vo_scale.h,v 1.1 2002/08/15 03:12:27 miguelfreitas Exp $ + * $Id: vo_scale.h,v 1.2 2002/09/04 23:31:13 guenter Exp $ * * vo_scale.h * @@ -93,6 +93,14 @@ struct vo_scale_s { int gui_win_x, gui_win_y; /* + * video + display pixel aspect + * One pixel of height 1 has this width + * This may be corrected by the driver in order to fit the video seamlessly + */ + double gui_pixel_aspect; + double video_pixel_aspect; + + /* * "output" size: * * this is finally the ideal size "fitted" into the @@ -113,12 +121,16 @@ struct vo_scale_s { void *user_data; void (*frame_output_cb) (void *user_data, int video_width, int video_height, + double video_pixel_aspect, int *dest_x, int *dest_y, int *dest_height, int *dest_width, + double *dest_pixel_aspect, int *win_x, int *win_y); void (*dest_size_cb) (void *user_data, int video_width, int video_height, + double video_pixel_aspect, + double *dest_pixel_aspect, int *dest_width, int *dest_height); /* borders */ diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 3fb22f370..866775863 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.148 2002/08/29 22:48:00 f1rmb Exp $ + * $Id: xine.c,v 1.149 2002/09/04 23:31:13 guenter Exp $ * * top-level xine functions * @@ -41,6 +41,7 @@ #endif #include "xine_internal.h" +#include "plugin_catalog.h" #include "audio_out.h" #include "video_out.h" #include "demuxers/demux.h" @@ -58,18 +59,20 @@ #define LOGO_DELAY 500000 /* usec */ -static void play_logo_internal(xine_t *this) { +static void play_logo_internal (xine_t *this) { pthread_mutex_lock (&this->logo_lock); this->playing_logo = 1; - if( !xine_play_internal(this, this->logo_mrl, 0, 0) ) + if( !xine_open_internal(this, this->logo_mrl) ) this->playing_logo = 0; - else - this->status = XINE_LOGO; + else { + xine_play_internal (this, 0, 0); + this->status = XINE_STATUS_LOGO; + } pthread_mutex_unlock (&this->logo_lock); } /* config callback for logo mrl changing */ -static void _logo_change_cb(void *data, cfg_entry_t *cfg) { +static void _logo_change_cb(void *data, xine_cfg_entry_t *cfg) { xine_t *this = (xine_t *) data; pthread_mutex_lock (&this->logo_lock); @@ -78,10 +81,10 @@ static void _logo_change_cb(void *data, cfg_entry_t *cfg) { /* * Start playback of new mrl only if - * current status is XINE_STOP or XINE_LOGO + * current status is XINE_STATUS_STOP or XINE_STATUS_LOGO */ pthread_mutex_lock (&this->xine_lock); - if((this->status == XINE_LOGO) || (this->status == XINE_STOP)) { + if((this->status == XINE_STATUS_LOGO) || (this->status == XINE_STATUS_STOP)) { xine_stop_internal(this); this->metronom->adjust_clock(this->metronom, this->metronom->get_current_time(this->metronom) + 30 * 90000 ); @@ -104,7 +107,7 @@ void * xine_notify_stream_finished_thread (void * this_gen) { xine_usec_sleep (LOGO_DELAY); pthread_mutex_lock (&this->xine_lock); - if (this->status == XINE_STOP) { + if (this->status == XINE_STATUS_STOP) { play_logo_internal(this); } pthread_mutex_unlock (&this->xine_lock); @@ -115,7 +118,7 @@ void * xine_notify_stream_finished_thread (void * this_gen) { void xine_notify_stream_finished (xine_t *this) { int err; - if (this->status == XINE_QUIT) + if (this->status == XINE_STATUS_QUIT) return; if (this->finished_thread_running) @@ -161,8 +164,9 @@ void xine_report_codec( xine_t *this, int codec_type, uint32_t fourcc, uint32_t } } -int xine_register_report_codec_cb(xine_t *this, xine_report_codec_t report_codec, - void *user_data) { +int xine_register_report_codec_cb(xine_t *this, + xine_report_codec_cb_t report_codec, + void *user_data) { this->report_codec_cb = report_codec; this->report_codec_user_data = user_data; @@ -197,7 +201,7 @@ void xine_internal_osd (xine_t *this, char *str, int duration) { } } -static void update_osd_display(void *this_gen, cfg_entry_t *entry) +static void update_osd_display(void *this_gen, xine_cfg_entry_t *entry) { xine_t *this = (xine_t *) this_gen; @@ -211,14 +215,14 @@ static void xine_set_speed_internal (xine_t *this, int speed) { /* see coment on audio_out loop about audio_paused */ if( this->audio_out ) { - this->audio_out->audio_paused = (speed != SPEED_NORMAL) + - (speed == SPEED_PAUSE); + this->audio_out->audio_paused = (speed != XINE_SPEED_NORMAL) + + (speed == XINE_SPEED_PAUSE); - if (speed != SPEED_NORMAL && speed != SPEED_PAUSE) + if (speed != XINE_SPEED_NORMAL && speed != XINE_SPEED_PAUSE) this->audio_out->control(this->audio_out, AO_CTRL_FLUSH_BUFFERS); this->audio_out->control(this->audio_out, - speed == SPEED_PAUSE ? AO_CTRL_PLAY_PAUSE : AO_CTRL_PLAY_RESUME); + speed == XINE_SPEED_PAUSE ? AO_CTRL_PLAY_PAUSE : AO_CTRL_PLAY_RESUME); } this->speed = speed; @@ -229,7 +233,7 @@ void xine_stop_internal (xine_t *this) { printf ("xine_stop\n"); - if (this->status == XINE_STOP) { + if (this->status == XINE_STATUS_STOP) { printf ("xine_stop ignored\n"); return; } @@ -237,11 +241,11 @@ void xine_stop_internal (xine_t *this) { if (this->audio_out) this->audio_out->control(this->audio_out, AO_CTRL_FLUSH_BUFFERS); - xine_set_speed_internal(this, SPEED_NORMAL); + xine_set_speed_internal(this, XINE_SPEED_NORMAL); /* Don't change status if we're quitting */ - if(this->status != XINE_QUIT) - this->status = XINE_STOP; + if(this->status != XINE_STATUS_QUIT) + this->status = XINE_STATUS_STOP; printf ("xine_stop: stopping demuxer\n"); if(this->cur_demuxer_plugin) { @@ -271,7 +275,7 @@ void xine_stop (xine_t *this) { this->metronom->adjust_clock(this->metronom, this->metronom->get_current_time(this->metronom) + 30 * 90000 ); - if(this->status == XINE_STOP) { + if(this->status == XINE_STATUS_STOP) { play_logo_internal(this); } @@ -280,94 +284,96 @@ void xine_stop (xine_t *this) { /* - * ***** - * Demuxers probing stuff + * demuxer probing */ -static int try_demux_with_stages(xine_t *this, const char *MRL, - int stage1, int stage2) { - int s = 0, i; +static int probe_demux (xine_t *this, char *MRL, int stage1, int stage2) { + + int i; int stages[3]; stages[0] = stage1; stages[1] = stage2; stages[2] = -1; - if(stages[0] == -1) { - printf (_("%s(%d) wrong first stage = %d !!\n"), - __XINE_FUNCTION__, __LINE__, stage1); + if (stages[0] == -1) { + printf ("xine: probe_demux stage1 = %d is not allowed \n", stage1); return 0; } - while(stages[s] != -1) { - for(i = 0; i < this->num_demuxer_plugins; i++) { - /* printf ("trying demuxer %s\n", this->demuxer_plugins[i]->get_identifier()); */ - if(this->demuxer_plugins[i]->open(this->demuxer_plugins[i], - this->cur_input_plugin, - stages[s]) == DEMUX_CAN_HANDLE) { + i = 0; + while (stages[i] != -1) { + + plugin_node_t *node; + + node = xine_list_first_content (this->plugin_catalog->demux); + + while (node) { + demux_plugin_t *plugin; + + plugin = (demux_plugin_t *) node->plugin; + + if (plugin->open (plugin, + this->cur_input_plugin, + stages[i]) == DEMUX_CAN_HANDLE) { - this->cur_demuxer_plugin = this->demuxer_plugins[i]; + this->cur_demuxer_plugin = plugin; return 1; } + node = xine_list_next_content (this->plugin_catalog->demux); } - s++; + i++; } return 0; } + /* - * Try to find a demuxer which handle the MRL stream + * try to find a demuxer which handle the MRL stream */ -static int find_demuxer(xine_t *this, const char *MRL) { +static int find_demuxer(xine_t *this, char *MRL) { this->cur_demuxer_plugin = NULL; - switch(this->demux_strategy) { + switch (this->demux_strategy) { case DEMUX_DEFAULT_STRATEGY: - if(try_demux_with_stages(this, MRL, STAGE_BY_CONTENT, STAGE_BY_EXTENSION)) + if (probe_demux (this, MRL, STAGE_BY_CONTENT, STAGE_BY_EXTENSION)) return 1; break; case DEMUX_REVERT_STRATEGY: - if(try_demux_with_stages(this, MRL, STAGE_BY_EXTENSION, STAGE_BY_CONTENT)) + if (probe_demux (this, MRL, STAGE_BY_EXTENSION, STAGE_BY_CONTENT)) return 1; break; case DEMUX_CONTENT_STRATEGY: - if(try_demux_with_stages(this, MRL, STAGE_BY_CONTENT, -1)) + if (probe_demux (this, MRL, STAGE_BY_CONTENT, -1)) return 1; break; case DEMUX_EXTENSION_STRATEGY: - if(try_demux_with_stages(this, MRL, STAGE_BY_EXTENSION, -1)) + if (probe_demux (this, MRL, STAGE_BY_EXTENSION, -1)) return 1; break; - } return 0; } -int xine_play_internal (xine_t *this, char *mrl, - int start_pos, int start_time) { +int xine_open_internal (xine_t *this, char *mrl) { - double share ; - off_t pos, len; - int i; - int demux_status; - - printf ("xine_play: xine open %s, start pos = %d, start time = %d (sec)\n", - mrl, start_pos, start_time); + printf ("xine_open: mrl '%s'\n", mrl); - if (this->speed != SPEED_NORMAL) { - xine_set_speed_internal (this, SPEED_NORMAL); + if (this->speed != XINE_SPEED_NORMAL) { + xine_set_speed_internal (this, XINE_SPEED_NORMAL); } /* * stop engine only for different mrl */ - if ((this->status == XINE_PLAY && strcmp (mrl, this->cur_mrl)) || (this->status == XINE_LOGO)) { + if ((this->status == XINE_STATUS_PLAY && strcmp (mrl, this->cur_mrl)) + || (this->status == XINE_STATUS_LOGO)) { if(this->cur_demuxer_plugin) { this->playing_logo = 0; @@ -385,16 +391,16 @@ int xine_play_internal (xine_t *this, char *mrl, if (this->audio_out) this->audio_out->control(this->audio_out, AO_CTRL_FLUSH_BUFFERS); - this->status = XINE_STOP; + this->status = XINE_STATUS_STOP; } else { } if (strcmp (mrl, this->cur_mrl)) { /* Is it an 'opt:' mrlstyle ? */ - if(config_file_change_opt(this->config, mrl)) { + if (xine_config_change_opt(this->config, mrl)) { xine_event_t event; - this->status = XINE_STOP; + this->status = XINE_STATUS_STOP; event.type = XINE_EVENT_PLAYBACK_FINISHED; pthread_mutex_unlock (&this->xine_lock); @@ -404,21 +410,29 @@ int xine_play_internal (xine_t *this, char *mrl, } } - if (this->status == XINE_STOP ) { + if (this->status == XINE_STATUS_STOP ) { + + plugin_node_t *node; + /* * find input plugin */ this->cur_input_plugin = NULL; - - for (i = 0; i < this->num_input_plugins; i++) { - if (this->input_plugins[i]->open(this->input_plugins[i], mrl)) { - this->cur_input_plugin = this->input_plugins[i]; + node = xine_list_first_content (this->plugin_catalog->input); + while (node) { + input_plugin_t *plugin; + + plugin = (input_plugin_t *) node->plugin; + + if (plugin->open (plugin, mrl)) { + this->cur_input_plugin = plugin; break; } + node = xine_list_next_content (this->plugin_catalog->input); } if (!this->cur_input_plugin) { - xine_log (this, XINE_LOG_FORMAT, + xine_log (this, XINE_LOG_FORMAT, _("xine: cannot find input plugin for this MRL\n")); this->cur_demuxer_plugin = NULL; this->err = XINE_ERROR_NO_INPUT_PLUGIN; @@ -429,7 +443,7 @@ int xine_play_internal (xine_t *this, char *mrl, printf ("xine: using input plugin >%s< for this MRL (%s).\n", this->cur_input_plugin->get_identifier(this->cur_input_plugin), mrl); - xine_log (this, XINE_LOG_FORMAT, + xine_log (this, XINE_LOG_FORMAT, _("using input plugin '%s' for MRL '%s'\n"), this->cur_input_plugin->get_identifier(this->cur_input_plugin), mrl); @@ -439,7 +453,7 @@ int xine_play_internal (xine_t *this, char *mrl, */ if (!find_demuxer(this, mrl)) { - xine_log (this, XINE_LOG_FORMAT, + xine_log (this, XINE_LOG_FORMAT, _("xine: couldn't find demuxer for >%s<\n"), mrl); this->cur_input_plugin->close(this->cur_input_plugin); this->err = XINE_ERROR_NO_DEMUXER_PLUGIN; @@ -450,7 +464,22 @@ int xine_play_internal (xine_t *this, char *mrl, _("system layer format '%s' detected.\n"), this->cur_demuxer_plugin->get_identifier()); } - + + strncpy (this->cur_mrl, mrl, 1024); + + printf ("xine: xine_open done.\n"); + + return 1; +} + +int xine_play_internal (xine_t *this, int start_pos, int start_time) { + + double share ; + off_t pos, len; + int demux_status; + + printf ("xine: xine_play_internal\n"); + /* * start demuxer */ @@ -462,31 +491,31 @@ int xine_play_internal (xine_t *this, char *mrl, } else pos = 0; - if( this->status == XINE_STOP ) { + if (this->status == XINE_STATUS_STOP) { + demux_status = this->cur_demuxer_plugin->start (this->cur_demuxer_plugin, this->video_fifo, this->audio_fifo, pos, start_time); - } - else { + } else { demux_status = this->cur_demuxer_plugin->seek (this->cur_demuxer_plugin, pos, start_time); } + if (demux_status != DEMUX_OK) { xine_log (this, XINE_LOG_MSG, _("xine_play: demuxer failed to start\n")); this->err = XINE_ERROR_DEMUXER_FAILED; - if( this->status == XINE_STOP ) + if( this->status == XINE_STATUS_STOP ) this->cur_input_plugin->close(this->cur_input_plugin); return 0; } else { - this->status = XINE_PLAY; - strncpy (this->cur_mrl, mrl, 1024); + this->status = XINE_STATUS_PLAY; /* osd will be updated as soon as we know cur_input_time */ if( !this->playing_logo ) @@ -496,17 +525,27 @@ int xine_play_internal (xine_t *this, char *mrl, return 1; } -int xine_play (xine_t *this, char *mrl, - int start_pos, int start_time) { -int ret; +int xine_open (xine_t *this, char *mrl) { + int ret; + + pthread_mutex_lock (&this->xine_lock); + ret = xine_open_internal (this, mrl); + pthread_mutex_unlock (&this->xine_lock); + + return ret; +} + +int xine_play (xine_t *this, int start_pos, int start_time) { + int ret; pthread_mutex_lock (&this->xine_lock); - ret = xine_play_internal (this, mrl, start_pos, start_time); + ret = xine_play_internal (this, start_pos, start_time); pthread_mutex_unlock (&this->xine_lock); return ret; } + int xine_eject (xine_t *this) { int status; @@ -517,7 +556,7 @@ int xine_eject (xine_t *this) { pthread_mutex_lock (&this->xine_lock); status = 0; - if (((this->status == XINE_STOP) || (this->status == XINE_LOGO)) + if (((this->status == XINE_STATUS_STOP) || (this->status == XINE_STATUS_LOGO)) && this->last_input_plugin && this->last_input_plugin->eject_media) { status = this->last_input_plugin->eject_media (this->last_input_plugin); @@ -531,7 +570,7 @@ void xine_exit (xine_t *this) { int i; - this->status = XINE_QUIT; + this->status = XINE_STATUS_QUIT; xine_stop(this); @@ -554,7 +593,7 @@ void xine_exit (xine_t *this) { this->video_out->exit (this->video_out); this->video_fifo->dispose (this->video_fifo); - this->status = XINE_QUIT; + this->status = XINE_STATUS_QUIT; printf ("xine_exit: bye!\n"); @@ -563,20 +602,7 @@ void xine_exit (xine_t *this) { this->metronom->exit (this->metronom); - for (i = 0; i < this->num_demuxer_plugins; i++) - this->demuxer_plugins[i]->close (this->demuxer_plugins[i]); - - for (i = 0; i < this->num_input_plugins; i++) - this->input_plugins[i]->dispose (this->input_plugins[i]); - - for (i = 0; i < this->num_audio_decoders_loaded; i++) - this->audio_decoders_loaded[i]->dispose (this->audio_decoders_loaded[i]); - - for (i = 0; i < this->num_video_decoders_loaded; i++) - this->video_decoders_loaded[i]->dispose (this->video_decoders_loaded[i]); - - for (i = 0; i < this->num_spu_decoders_loaded; i++) - this->spu_decoders_loaded[i]->dispose (this->spu_decoders_loaded[i]); + dispose_plugins (this); xine_profiler_print_results (); @@ -589,45 +615,26 @@ void xine_exit (xine_t *this) { } -xine_t *xine_init (vo_driver_t *vo, - ao_driver_t *ao, - config_values_t *config) { +xine_t *xine_new (void) { - xine_t *this = xine_xmalloc (sizeof (xine_t)); - static char *demux_strategies[] = {"default", "reverse", "content", - "extension", NULL}; + xine_t *this; int i; - /* setting default logo mrl */ - pthread_mutex_init (&this->logo_lock, NULL); - - pthread_mutex_lock (&this->logo_lock); - this->logo_mrl = config->register_string(config, "misc.logo_mrl", XINE_LOGO_FILE, - _("logo mrl, displayed in video output window"), - NULL, _logo_change_cb, (void *) this); - pthread_mutex_unlock (&this->logo_lock); - - this->video_driver = vo; - - /* initialize color conversion tables and functions */ - init_yuv_conversion(); - - /* init log buffers */ - for (i = 0; i < XINE_LOG_NUM; i++) - this->log_buffers[i] = new_scratch_buffer (25); + this = xine_xmalloc (sizeof (xine_t)); + if (!this) { + printf ("xine: failed to malloc xine_t\n"); + abort(); + } + #ifdef ENABLE_NLS + /* + * i18n + */ + bindtextdomain("xine-lib", XINE_LOCALEDIR); #endif - - printf ("xine: xine_init entered\n"); - - this->err = XINE_ERROR_NONE; - this->config = config; - /* probe for optimized memcpy or config setting */ - xine_probe_fast_memcpy(config); - /* * init locks */ @@ -641,61 +648,115 @@ xine_t *xine_init (vo_driver_t *vo, this->finished_thread_running = 0; /* - * init event listeners + * config + */ + + this->config = xine_config_init (); + + /* + * log buffers + */ + + for (i = 0; i < XINE_LOG_NUM; i++) + this->log_buffers[i] = new_scratch_buffer (25); + + /* + * defaults */ - this->num_event_listeners = 0; /* Initially there are none */ - this->cur_input_plugin = NULL; /* In case the input plugin event handlers - * are called too early. */ + + this->err = XINE_ERROR_NONE; + this->spu_channel_auto = -1; + this->spu_channel_letterbox = -1; + this->spu_channel_pan_scan = -1; + this->spu_channel_user = -1; + this->cur_input_pos = 0; + this->cur_input_length = 0; + this->last_input_plugin = NULL; + this->num_event_listeners = 0; /* initially there are none */ + this->cur_input_plugin = NULL; this->cur_spu_decoder_plugin = NULL; - this->report_codec_cb = NULL; + this->report_codec_cb = NULL; + + /* + * plugins + */ + scan_plugins(this); + /* - * create a metronom + * logo */ - this->metronom = metronom_init (ao != NULL, (void *)this); + pthread_mutex_init (&this->logo_lock, NULL); + + pthread_mutex_lock (&this->logo_lock); + this->logo_mrl = this->config->register_string(this->config, + "misc.logo_mrl", + XINE_LOGO_FILE, + _("logo mrl, displayed in video output window"), + NULL, 0, _logo_change_cb, + (void *) this); + pthread_mutex_unlock (&this->logo_lock); + + return this; + +} + +void xine_init (xine_t *this, + xine_ao_driver_t *ao, + xine_vo_driver_t *vo) { + + static char *demux_strategies[] = {"default", "reverse", "content", + "extension", NULL}; + + this->video_driver = vo; + + /* initialize color conversion tables and functions */ + init_yuv_conversion(); + + /* - * load input and demuxer plugins + * create a metronom */ - load_input_plugins (this, config); - - this->demux_strategy = config->register_enum (config, "misc.demux_strategy", 0, - demux_strategies, "demuxer selection strategy", - NULL, NULL, NULL); + this->metronom = metronom_init ( (ao != NULL), this); + + /* probe for optimized memcpy or config setting */ + xine_probe_fast_memcpy (this->config); - load_demux_plugins(this, config); + /* + * content detection strategy + */ - this->spu_channel_auto = -1; - this->spu_channel_letterbox = -1; - this->spu_channel_pan_scan = -1; - this->spu_channel_user = -1; - this->cur_input_pos = 0; - this->cur_input_length = 0; - this->last_input_plugin = NULL; + this->demux_strategy = this->config->register_enum (this->config, + "misc.demux_strategy", + 0, + demux_strategies, + "media format detection strategy", + NULL, 10, NULL, NULL); /* * init and start decoder threads */ - load_decoder_plugins (this, config); - this->video_out = vo_new_instance (vo, this); video_decoder_init (this); - this->osd_renderer = osd_renderer_init (this->video_out->get_overlay_instance (this->video_out), config ); + this->osd_renderer = osd_renderer_init (this->video_out->get_overlay_instance (this->video_out), this->config ); this->osd = this->osd_renderer->new_object (this->osd_renderer, 300, 100); this->osd_renderer->set_font (this->osd, "cetus", 24); this->osd_renderer->set_text_palette (this->osd, TEXTPALETTE_WHITE_BLACK_TRANSPARENT, OSD_TEXT1 ); this->osd_renderer->set_position (this->osd, 10,10); - this->osd_display = config->register_bool(config, "misc.osd_display", 1, - "Show status on play, pause, ff, ...", NULL, - update_osd_display, this ); + this->osd_display = this->config->register_bool (this->config, + "misc.osd_display", 1, + "Show status on play, pause, ff, ...", + NULL, 0, + update_osd_display, this ); - if(ao) + if (ao) this->audio_out = ao_new_instance (ao, this); audio_decoder_init (this); @@ -719,14 +780,9 @@ xine_t *xine_init (vo_driver_t *vo, this->osd_renderer->hide (this->osd, 300000); } - play_logo_internal(this); + this->status = XINE_STATUS_STOP; - return this; -} - -int xine_get_spu_channel (xine_t *this) { - - return this->spu_channel_user; + play_logo_internal(this); } void xine_select_spu_channel (xine_t *this, int channel) { @@ -752,7 +808,7 @@ void xine_select_spu_channel (xine_t *this, int channel) { pthread_mutex_unlock (&this->xine_lock); } -int xine_get_current_position (xine_t *this) { +static int xine_get_current_position (xine_t *this) { off_t len; double share; @@ -779,68 +835,11 @@ int xine_get_status(xine_t *this) { int status; status = this->status; - if( status == XINE_LOGO ) - status = XINE_STOP; + if( status == XINE_STATUS_LOGO ) + status = XINE_STATUS_STOP; return status; } -/* *** - * Version information/check - */ - -/* - * Return version in string, like "0.5.0" - */ -char *xine_get_str_version(void) { - return VERSION; -} - -/* - * Return major version - */ -int xine_get_major_version(void) { - return XINE_MAJOR; -} - -/* - * Return minor version - */ -int xine_get_minor_version(void) { - return XINE_MINOR; -} - -/* - * Return sub version - */ -int xine_get_sub_version(void) { - return XINE_SUB; -} - -/* - * Check if xine version is <= to specifier version. - */ -int xine_check_version(int major, int minor, int sub) { - - if((XINE_MAJOR > major) || - ((XINE_MAJOR == major) && (XINE_MINOR > minor)) || - ((XINE_MAJOR == major) && (XINE_MINOR == minor) && (XINE_SUB >= sub))) - return 1; - - return 0; -} - -/* - * manually adjust a/v sync - */ - -void xine_set_av_offset (xine_t *this, int offset_pts) { - this->metronom->set_option (this->metronom, METRONOM_AV_OFFSET, offset_pts); -} - -int xine_get_av_offset (xine_t *this) { - return this->metronom->get_option (this->metronom, METRONOM_AV_OFFSET); -} - /* * trick play */ @@ -849,31 +848,31 @@ void xine_set_speed (xine_t *this, int speed) { pthread_mutex_lock (&this->xine_lock); - if (speed <= SPEED_PAUSE) - speed = SPEED_PAUSE; - else if (speed > SPEED_FAST_4) - speed = SPEED_FAST_4; + if (speed <= XINE_SPEED_PAUSE) + speed = XINE_SPEED_PAUSE; + else if (speed > XINE_SPEED_FAST_4) + speed = XINE_SPEED_FAST_4; /* osd */ pthread_mutex_lock (&this->osd_lock); switch (speed) { - case SPEED_PAUSE: + case XINE_SPEED_PAUSE: xine_internal_osd (this, "<", 90000); break; - case SPEED_SLOW_4: + case XINE_SPEED_SLOW_4: xine_internal_osd (this, "<>", 20000 * speed); break; - case SPEED_SLOW_2: + case XINE_SPEED_SLOW_2: xine_internal_osd (this, "@>", 20000 * speed); break; - case SPEED_NORMAL: + case XINE_SPEED_NORMAL: xine_internal_osd (this, ">", 20000 * speed); break; - case SPEED_FAST_2: + case XINE_SPEED_FAST_2: xine_internal_osd (this, "$$", 20000 * speed); break; - case SPEED_FAST_4: + case XINE_SPEED_FAST_4: xine_internal_osd (this, "$$$", 20000 * speed); break; } @@ -894,11 +893,7 @@ int xine_get_speed (xine_t *this) { * time measurement / seek */ -int xine_get_current_time (xine_t *this) { - return this->cur_input_time; -} - -int xine_get_stream_length (xine_t *this) { +static int xine_get_stream_length (xine_t *this) { if(this->cur_demuxer_plugin) return this->cur_demuxer_plugin->get_stream_length (this->cur_demuxer_plugin); @@ -906,7 +901,17 @@ int xine_get_stream_length (xine_t *this) { return 0; } -int xine_get_audio_capabilities(xine_t *this) { +int xine_get_pos_length (xine_t *this, int *pos_stream, + int *pos_time, int *length_time) { + + *pos_stream = xine_get_current_position (this); + *pos_time = this->cur_input_time * 1000; + *length_time = xine_get_stream_length (this) * 1000; + + return 1; +} + +static int xine_get_audio_capabilities(xine_t *this) { if(this->audio_out) return (this->audio_out->get_capabilities(this->audio_out)); @@ -914,7 +919,7 @@ int xine_get_audio_capabilities(xine_t *this) { return AO_CAP_NOCAP; } -int xine_get_audio_property(xine_t *this, int property) { +static int xine_get_audio_property(xine_t *this, int property) { if(this->audio_out) return(this->audio_out->get_property(this->audio_out, property)); @@ -922,7 +927,7 @@ int xine_get_audio_property(xine_t *this, int property) { return 0; } -int xine_set_audio_property(xine_t *this, int property, int value) { +static int xine_set_audio_property(xine_t *this, int property, int value) { if(this->audio_out) return(this->audio_out->set_property(this->audio_out, property, value)); @@ -932,7 +937,7 @@ int xine_set_audio_property(xine_t *this, int property, int value) { int xine_get_current_frame (xine_t *this, int *width, int *height, int *ratio_code, int *format, - uint8_t **y, uint8_t **u, uint8_t **v) { + uint8_t *img) { vo_frame_t *frame; @@ -947,14 +952,31 @@ int xine_get_current_frame (xine_t *this, int *width, int *height, *ratio_code = frame->ratio; *format = frame->format; - *y = frame->base[0]; - *u = frame->base[1]; - *v = frame->base[2]; + switch (frame->format) { + + case XINE_IMGFMT_YV12: + memcpy (img, frame->base[0], frame->width*frame->height); + memcpy (img+frame->width*frame->height, frame->base[1], + frame->width*frame->height/4); + memcpy (img+frame->width*frame->height+frame->width*frame->height/4, + frame->base[1], + frame->width*frame->height/4); + break; + + case XINE_IMGFMT_YUY2: + memcpy (img, frame->base[0], frame->width * frame->height * 2); + break; + + default: + printf ("xine: error, snapshot function not implemented for format 0x%x\n", + frame->format); + abort (); + } return 1; } -void xine_get_spu_lang (xine_t *this, char *str) { +int xine_get_spu_lang (xine_t *this, int channel, char *str) { switch (this->spu_channel_user) { case -2: @@ -966,7 +988,7 @@ void xine_get_spu_lang (xine_t *this, char *str) { this->cur_input_plugin->get_optional_data (this->cur_input_plugin, this->str, INPUT_OPTIONAL_DATA_SPULANG); sprintf (str, "*(%s)", this->str); - return; + return 1; } } if (this->spu_channel_auto == -1) @@ -977,10 +999,10 @@ void xine_get_spu_lang (xine_t *this, char *str) { default: sprintf (str, "%3d", this->spu_channel_user); } - + return 0; } -void xine_get_audio_lang (xine_t *this, char *str) { +int xine_get_audio_lang (xine_t *this, int channel, char *str) { switch (this->audio_channel_user) { case -2: @@ -994,7 +1016,7 @@ void xine_get_audio_lang (xine_t *this, char *str) { sprintf (str, "*(%s)", this->str); - return; + return 1; } } if (this->audio_channel_auto == -1) @@ -1005,6 +1027,7 @@ void xine_get_audio_lang (xine_t *this, char *str) { default: sprintf (str, "%3d", this->audio_channel_user); } + return 0; } int xine_is_stream_seekable (xine_t *this) { @@ -1062,6 +1085,19 @@ char **xine_get_log (xine_t *this, int buf) { return this->log_buffers[buf]->get_content (this->log_buffers[buf]); } +void xine_register_log_cb (xine_t *self, xine_log_cb_t *cb, void *user_data) { + + printf ("xine: xine_register_log_cb: not implemented yet.\n"); + abort(); +} + + int xine_get_error (xine_t *this) { return this->err; } + +int xine_trick_mode (xine_t *this, int mode, int value) { + printf ("xine: xine_trick_mode not implemented yet.\n"); + abort (); +} + diff --git a/src/xine-engine/xine_interface.c b/src/xine-engine/xine_interface.c new file mode 100644 index 000000000..fe8e822e3 --- /dev/null +++ b/src/xine-engine/xine_interface.c @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2000-2002 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: xine_interface.c,v 1.2 2002/09/04 23:31:13 guenter Exp $ + * + * convenience/abstraction layer, functions to implement + * libxine's public interface + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> +#include <pthread.h> +#include <stdarg.h> +#if defined (__linux__) +#include <endian.h> +#elif defined (__FreeBSD__) +#include <machine/endian.h> +#endif + +#include "xine_internal.h" +#include "audio_out.h" +#include "video_out.h" +#include "demuxers/demux.h" + +/* + * version information / checking + */ + +char *xine_get_version_string(void) { + return VERSION; +} + +void xine_get_version (int *major, int *minor, int *sub) { + *major = XINE_MAJOR; + *minor = XINE_MINOR; + *sub = XINE_SUB; +} + +int xine_check_version(int major, int minor, int sub) { + + if((XINE_MAJOR > major) || + ((XINE_MAJOR == major) && (XINE_MINOR > minor)) || + ((XINE_MAJOR == major) && (XINE_MINOR == minor) && (XINE_SUB >= sub))) + return 1; + + return 0; +} + +/* + * public config object access functions + */ + +char* xine_config_register_string (xine_t *self, + char *key, + char *def_value, + char *description, + char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { + + return self->config->register_string (self->config, + key, + def_value, + description, + help, + exp_level, + changed_cb, + cb_data); + +} + +int xine_config_register_range (xine_t *self, + char *key, + int def_value, + int min, int max, + char *description, + char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { + return self->config->register_range (self->config, + key, def_value, min, max, + description, help, exp_level, + changed_cb, cb_data); +} + + +int xine_config_register_enum (xine_t *self, + char *key, + int def_value, + char **values, + char *description, + char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { + return self->config->register_enum (self->config, + key, def_value, values, + description, help, exp_level, + changed_cb, cb_data); +} + + +int xine_config_register_num (xine_t *self, + char *key, + int def_value, + char *description, + char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { + return self->config->register_num (self->config, + key, def_value, + description, help, exp_level, + changed_cb, cb_data); +} + + +int xine_config_register_bool (xine_t *self, + char *key, + int def_value, + char *description, + char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { + return self->config->register_bool (self->config, + key, def_value, + description, help, exp_level, + changed_cb, cb_data); +} + + +/* + * helper function: + * + * copy current config entry data to public struct + * and return it + */ + +xine_cfg_entry_t *xine_config_get_current_entry (xine_t *this) { + + config_values_t *config = this->config; + + if (!config->cur) + return NULL; + + config->public_entry.key = config->cur->key; + config->public_entry.type = config->cur->type; + + config->public_entry.unknown_value = config->cur->unknown_value; + config->public_entry.str_value = config->cur->str_value; + config->public_entry.str_default = config->cur->str_default; + config->public_entry.str_sticky = config->cur->str_sticky; + config->public_entry.num_value = config->cur->num_value; + config->public_entry.num_default = config->cur->num_default; + config->public_entry.range_min = config->cur->range_min; + config->public_entry.range_max = config->cur->range_max; + config->public_entry.enum_values = config->cur->enum_values; + + config->public_entry.description = config->cur->description; + config->public_entry.help = config->cur->help; + config->public_entry.callback = config->cur->callback; + config->public_entry.callback_data = config->cur->callback_data; + config->public_entry.exp_level = config->cur->exp_level; + + return &config->public_entry; +} + +/* + * get first config item + */ +xine_cfg_entry_t *xine_config_get_first_entry (xine_t *this) { + + config_values_t *config = this->config; + + config->cur = config->first; + + return xine_config_get_current_entry (this); +} + + +/* + * get next config item (iterate through the items) + * this will return NULL when called after returning the last item + */ +xine_cfg_entry_t *xine_config_get_next_entry (xine_t *this) { + + config_values_t *config = this->config; + + config->cur = config->cur->next; + + return xine_config_get_current_entry (this); +} + + +/* + * search for a config entry by key + */ + +xine_cfg_entry_t *xine_config_lookup_entry (xine_t *this, char *key) { + + config_values_t *config = this->config; + + config->cur = config->lookup_entry (config, key); + + return xine_config_get_current_entry (this); +} + + +/* + * update a config entry (which was returned from lookup_entry() ) + */ +void xine_config_update_entry (xine_t *this, xine_cfg_entry_t *entry){ + printf ("xine_interface: xine_config_update_entry: not implemented\n"); + abort(); +} + + +void xine_reset_config (xine_t *this){ + printf ("xine_interface: xine_reset_config: not implemented\n"); + abort(); +} + +int xine_gui_send_vo_data (xine_t *this, + int type, void *data) { + + return this->video_driver->gui_data_exchange (this->video_driver, type, data); +} + +void xine_set_param (xine_t *this, int param, int value) { + + switch (param) { + case XINE_PARAM_SPEED: + xine_set_speed (this, value); + break; + + case XINE_PARAM_AV_OFFSET: + this->metronom->set_option (this->metronom, METRONOM_AV_OFFSET, value); + break; + + case XINE_PARAM_AUDIO_CHANNEL_LOGICAL: + pthread_mutex_lock (&this->xine_lock); + if (value < -2) + value = -2; + this->audio_channel_user = value; + pthread_mutex_unlock (&this->xine_lock); + break; + + case XINE_PARAM_SPU_CHANNEL: + xine_select_spu_channel (this, value); + break; + + case XINE_PARAM_VIDEO_CHANNEL: + pthread_mutex_lock (&this->xine_lock); + if (value<0) + value = 0; + this->video_channel = value; + pthread_mutex_unlock (&this->xine_lock); + break; + } +} + +int xine_get_param (xine_t *this, int param) { + + switch (param) { + case XINE_PARAM_SPEED: + return this->speed; + + case XINE_PARAM_AV_OFFSET: + return this->metronom->get_option (this->metronom, METRONOM_AV_OFFSET); + + case XINE_PARAM_AUDIO_CHANNEL_LOGICAL: + return this->audio_channel_user; + + case XINE_PARAM_SPU_CHANNEL: + return this->spu_channel_user; + + case XINE_PARAM_VIDEO_CHANNEL: + return this->video_channel; + + default: + printf ("xine_interface: unknown param %d\n", param); + abort (); + } + + return 0; +} + +uint32_t xine_get_stream_info (xine_t *self, int info) { + printf ("xine_interface: xine_get_stream_info: not implemented\n"); + abort(); +} diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index efe20c3e9..7c38ee929 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.92 2002/07/14 20:55:17 miguelfreitas Exp $ + * $Id: xine_internal.h,v 1.93 2002/09/04 23:31:13 guenter Exp $ * */ @@ -30,6 +30,16 @@ extern "C" { #include <inttypes.h> +/* + * include public part of xine header + */ + +#ifdef XINE_COMPILE +#include "include/xine.h" +#else +#include "xine.h" +#endif + #ifdef XINE_COMPILE #include "input/input_plugin.h" #include "demuxers/demux.h" @@ -37,29 +47,31 @@ extern "C" { #include "input_plugin.h" #include "demux.h" #endif + #include "video_out.h" #include "audio_out.h" #include "metronom.h" #include "spu_decoder.h" -#include "events.h" #include "lrb.h" + #ifdef XINE_COMPILE #include "libspudec/spu_decoder_api.h" #else #include "spu_decoder_api.h" #endif + #include "osd.h" #include "scratch.h" #include "xineintl.h" +#include "plugin_catalog.h" -#define INPUT_PLUGIN_MAX 50 -#define DEMUXER_PLUGIN_MAX 50 -#define DECODER_PLUGIN_MAX 256 #define VIDEO_DECODER_IFACE_VERSION 10 #define AUDIO_DECODER_IFACE_VERSION 9 -#define AUDIO_OUT_PLUGIN_MAX 50 -#define VIDEO_OUT_PLUGIN_MAX 50 -#define XINE_MAX_EVENT_LISTENERS 50 +#define XINE_MAX_EVENT_LISTENERS 50 + +/* used by plugin loader */ +#define XINE_VERSION_CODE XINE_MAJOR_VERSION*10000+XINE_MINOR_VERSION*100+XINE_SUB_VERSION + /* * generic xine video decoder plugin interface @@ -73,10 +85,6 @@ typedef struct video_decoder_s video_decoder_t; struct video_decoder_s { - int interface_version; - - int (*can_handle) (video_decoder_t *this, int buf_type); - void (*init) (video_decoder_t *this, vo_instance_t *video_out); void (*decode_data) (video_decoder_t *this, buf_element_t *buf); @@ -107,10 +115,6 @@ typedef struct audio_decoder_s audio_decoder_t; struct audio_decoder_s { - int interface_version; - - int (*can_handle) (audio_decoder_t *this, int buf_type); - void (*init) (audio_decoder_t *this, ao_instance_t *audio_out); void (*decode_data) (audio_decoder_t *this, buf_element_t *buf); @@ -128,34 +132,17 @@ struct audio_decoder_s { }; /* - * gui callback functions - * - */ - -/* - * player status constants: + * log constants */ -#define XINE_STOP 0 -#define XINE_PLAY 1 -#define XINE_QUIT 2 -#define XINE_LOGO 3 - -/* - * log output - */ #define XINE_LOG_FORMAT 0 /* stream format, decoders, video size... */ #define XINE_LOG_MSG 1 /* warnings, errors, ... */ #define XINE_LOG_PLUGIN 2 #define XINE_LOG_NUM 3 /* # of log buffers defined */ -typedef void (*xine_event_listener_t) (void *user_data, xine_event_t *); - -#define XINE_CODEC_AUDIO 0 -#define XINE_CODEC_VIDEO 1 - -typedef void (*xine_report_codec_t) (void *user_data, int codec_type, - uint32_t fourcc, char *description, int handled); +/* + * the big xine struct, holding everything together + */ struct xine_s { @@ -170,14 +157,12 @@ struct xine_s { /* Logo manipulation mutex */ pthread_mutex_t logo_lock; - input_plugin_t *input_plugins[INPUT_PLUGIN_MAX]; - int num_input_plugins; + plugin_catalog_t *plugin_catalog; + input_plugin_t *cur_input_plugin; /* kept to do proper ejecting (otherwise we eject the logo) */ input_plugin_t *last_input_plugin; - demux_plugin_t *demuxer_plugins[DEMUXER_PLUGIN_MAX]; - int num_demuxer_plugins; demux_plugin_t *cur_demuxer_plugin; int demux_strategy; @@ -190,11 +175,8 @@ struct xine_s { spu_functions_t *spu_out; pthread_t spu_thread; - spu_decoder_t *spu_decoder_plugins[DECODER_PLUGIN_MAX]; spu_decoder_t *cur_spu_decoder_plugin; int spu_finished; - spu_decoder_t *spu_decoders_loaded[DECODER_PLUGIN_MAX]; - int num_spu_decoders_loaded; /* *_user: -2 => off -1 => auto (use *_auto value) @@ -209,16 +191,14 @@ struct xine_s { int spu_channel_pan_scan; int spu_channel; - vo_driver_t *video_driver; + xine_vo_driver_t *video_driver; vo_instance_t *video_out; fifo_buffer_t *video_fifo; pthread_t video_thread; - video_decoder_t *video_decoder_plugins[DECODER_PLUGIN_MAX]; video_decoder_t *cur_video_decoder_plugin; - video_decoder_t *video_decoders_loaded[DECODER_PLUGIN_MAX]; - int num_video_decoders_loaded; int video_finished; int video_in_discontinuity; + int video_channel; osd_renderer_t *osd_renderer; osd_object_t *osd; @@ -228,10 +208,7 @@ struct xine_s { fifo_buffer_t *audio_fifo; lrb_t *audio_temp; pthread_t audio_thread; - audio_decoder_t *audio_decoder_plugins[DECODER_PLUGIN_MAX]; audio_decoder_t *cur_audio_decoder_plugin; - audio_decoder_t *audio_decoders_loaded[DECODER_PLUGIN_MAX]; - int num_audio_decoders_loaded; uint32_t audio_track_map[50]; int audio_track_map_entries; int audio_finished; @@ -244,7 +221,7 @@ struct xine_s { pthread_mutex_t finished_lock; /* Array of event handlers. */ - xine_event_listener_t event_listeners[XINE_MAX_EVENT_LISTENERS]; + xine_event_listener_cb_t event_listeners[XINE_MAX_EVENT_LISTENERS]; void *event_listener_user_data[XINE_MAX_EVENT_LISTENERS]; uint16_t num_event_listeners; @@ -259,7 +236,7 @@ struct xine_s { pthread_t finished_thread; int finished_thread_running; - xine_report_codec_t report_codec_cb; + xine_report_codec_cb_t report_codec_cb; void *report_codec_user_data; int playing_logo; @@ -268,282 +245,51 @@ struct xine_s { }; /* - * read config file and init a config object - * (if it exists) - */ -config_values_t *xine_config_file_init (char *filename); - -/* - * init xine - call once at startup - */ - -xine_t *xine_init (vo_driver_t *vo, - ao_driver_t *ao, - config_values_t *config); - -/* - * open a stream sekk to a given position and play it - * - * name : mrl to open - * start_pos : position in input source (0..65535) - * start_time : position measured in seconds from stream start - * - * if both parameters are !=0 start_pos will be used - * for non-seekable streams both values will be ignored - * - * returns 1 on succ, 0 on failure - */ -int xine_play (xine_t *this, char *MRL, int start_pos, int start_time); -int xine_play_internal (xine_t *this, char *MRL, int start_pos, int start_time); - - -/* - * set/get playback speed - * - * constants see below - */ - -void xine_set_speed (xine_t *this, int speed); -int xine_get_speed (xine_t *this); - -#define SPEED_PAUSE 0 -#define SPEED_SLOW_4 1 -#define SPEED_SLOW_2 2 -#define SPEED_NORMAL 4 -#define SPEED_FAST_2 8 -#define SPEED_FAST_4 16 - -/* - * manually adjust a/v sync - */ - -void xine_set_av_offset (xine_t *this, int offset_pts); -int xine_get_av_offset (xine_t *this); - -/* - * stop playing - */ -void xine_stop_internal (xine_t *this); -void xine_stop (xine_t *this); - -/* - * tell current input plugin to eject media. - */ -int xine_eject(xine_t *this); - -/* - * return current status (XINE_PLAY/XINE_STOP...) - */ -int xine_get_status (xine_t *this); - -/* - * get current position in stream - * returns position (range : 0 - 65535) - */ -int xine_get_current_position (xine_t *this); - -/* - * get current position measured in seconds from - * the beginning of the stream - */ -int xine_get_current_time (xine_t *this); - -/* - * estimate length of input stream in seconds - * may return 0 if stream is not seekable - */ -int xine_get_stream_length (xine_t *this); - -/* - * return the current physical audio channel - */ -int xine_get_audio_channel (xine_t *this); - -/* - * return the current logical audio channel - */ -int xine_get_audio_selection (xine_t *this); - -/* - * try to find out current audio language - */ -void xine_get_audio_lang (xine_t *this, char *str); - -/* - * set desired logical audio channel (-1 => auto) - */ -void xine_select_audio_channel (xine_t *this, int channel); - -/* - * return the current SPU channel - */ -int xine_get_spu_channel (xine_t *this); - -/* - * set desired SPU channel - */ -void xine_select_spu_channel (xine_t *this, int channel); - -/* - * try to find out current spu language - */ -void xine_get_spu_lang (xine_t *this, char *str); - -/* - * check if the stream is seekable (at the moment) - */ - -int xine_is_stream_seekable (xine_t *this); - -/* - * exit xine - */ -void xine_exit (xine_t *this); - -/* - * browsing support - */ - -/* - * some input plugins are browseable - * returns a list of ids of these plugins - */ -char **xine_get_browsable_input_plugin_ids (xine_t *this) ; - -/* - * browse function - * asks input plugin named <plugin_id> to return - * a list of available MRLs in domain/directory <start_mrl> - * - * start_mrl may be NULL indicating the toplevel domain/dir - * returns start_mrl if start_mrl is a valid MRL, not a directory - * returns NULL if start_mrl is an invalid MRL, not even a directory - */ - -mrl_t **xine_get_browse_mrls (xine_t *this, char *plugin_id, - char *start_mrl, int *num_mrls); - -/* - * autoplay support - */ - -/* - * some input plugins can generate autoplay lists - * returns a list of ids of these plugins - */ -char **xine_get_autoplay_input_plugin_ids (xine_t *this) ; - -/* - * get autoplay MRL list for input plugin named <plugin_id> - */ -char **xine_get_autoplay_mrls (xine_t *this, char *plugin_id, int *num_mrls); - -/* - * internal use only + * private function prototypes: */ +int xine_open_internal (xine_t *this, char *MRL); +int xine_play_internal (xine_t *this, + int start_pos, int start_time); +void xine_stop_internal (xine_t *this); void xine_notify_stream_finished (xine_t *this); -void xine_report_codec( xine_t *this, int codec_type, uint32_t fourcc, uint32_t buf_type, int handled ); -void xine_internal_osd (xine_t *this, char *str, int duration); +void xine_report_codec (xine_t *this, int codec_type, + uint32_t fourcc, uint32_t buf_type, int handled ); +void xine_internal_osd (xine_t *this, char *str, int duration); -/* - * video decoder stuff - */ - -/* - * init video decoders, allocate video fifo, - * start video decoder thread - */ - -void video_decoder_init (xine_t *this); - -/* - * quit video thread - */ - -void video_decoder_shutdown (xine_t *this); - -/* - * spu decoder stuff - */ - -/* - * init audio decoders, allocate audio fifo, - * start audio decoder thread - */ - -void audio_decoder_init (xine_t *this); - -/* - * quit audio thread - */ - -void audio_decoder_shutdown (xine_t *this); +void video_decoder_init (xine_t *this); +void video_decoder_shutdown (xine_t *this); +void audio_decoder_init (xine_t *this); +void audio_decoder_shutdown (xine_t *this); /* - * Load input/demux/audio_out/video_out plugins + * demuxer helper functions from demux.c */ -/* plugin naming scheme */ -#define XINE_INPUT_PLUGIN_PREFIXNAME "xineplug_inp_" -#define XINE_INPUT_PLUGIN_PREFIXNAME_LENGTH 13 - -#define XINE_DEMUXER_PLUGIN_PREFIXNAME "xineplug_dmx_" -#define XINE_DEMUXER_PLUGIN_PREFIXNAME_LENGTH 13 - -#define XINE_VIDEO_OUT_PLUGIN_PREFIXNAME "xineplug_vo_out_" -#define XINE_VIDEO_OUT_PLUGIN_PREFIXNAME_LENGTH 16 +void xine_demux_flush_engine (xine_t *this); -#define XINE_AUDIO_OUT_PLUGIN_PREFIXNAME "xineplug_ao_out_" -#define XINE_AUDIO_OUT_PLUGIN_PREFIXNAME_LENGTH 16 +void xine_demux_control_newpts (xine_t *this, int64_t pts, uint32_t flags ); -#define XINE_DECODER_PLUGIN_PREFIXNAME "xineplug_decode_" -#define XINE_DECODER_PLUGIN_PREFIXNAME_LENGTH 16 +void xine_demux_control_start (xine_t *this ); -/* - * load all available demuxer plugins - */ -void load_demux_plugins (xine_t *this, - config_values_t *config); - -/* - * list (open and close) all available demuxer plugins - */ -void xine_list_demux_plugins (config_values_t *config, - char **identifiers, char **mimetypes); - -/* - * load all available input plugins - */ - -void load_input_plugins (xine_t *this, - config_values_t *config); +void xine_demux_control_end (xine_t *this, uint32_t flags ); /* - * load all available decoder plugins + * plugin management */ -void load_decoder_plugins (xine_t *this, - config_values_t *config); /* - * output driver load support functions + * on-demand loading of audio/video/spu decoder plugins */ -/* video */ - -#define VISUAL_TYPE_X11 1 -#define VISUAL_TYPE_AA 2 -#define VISUAL_TYPE_FB 3 -#define VISUAL_TYPE_GTK 4 -#define VISUAL_TYPE_DFB 5 +video_decoder_t *get_video_decoder (xine_t *this, uint8_t stream_type); +audio_decoder_t *get_audio_decoder (xine_t *this, uint8_t stream_type); +spu_decoder_t *get_spu_decoder (xine_t *this, uint8_t stream_type); -/* - * list_video_output_plugins +/* + * plugin_loader functions * - * returns a list of available video output plugins for - * the specified visual type - the list is sorted by plugin - * priority */ char **xine_list_video_output_plugins (int visual_type); @@ -554,8 +300,8 @@ char **xine_list_video_output_plugins (int visual_type); * load a specific video output plugin */ -vo_driver_t *xine_load_video_output_plugin(config_values_t *config, - char *id, int visual_type, void *visual); +xine_vo_driver_t *xine_load_video_output_plugin(xine_t *this, + char *id, int visual_type, void *visual); /* * audio output plugin dynamic loading stuff @@ -576,101 +322,18 @@ char **xine_list_audio_output_plugins (); * load a specific audio output plugin */ -ao_driver_t *xine_load_audio_output_plugin(config_values_t *config, char *id); - -/* - * sending events - * event dispatcher mechanism - */ - -/* - * register an event listener callback. - * returns 0 if the listener was registerd, non-zero if it could not. - */ - -int xine_register_event_listener(xine_t *this, xine_event_listener_t listener, - void *user_data); - -/* - * attempt to remove a registered event listener. - * returns 0 if the listener was removed, non-zero if not (e.g. not found). - */ - -int xine_remove_event_listener(xine_t *this, xine_event_listener_t listener); - -/* - * send an event to all listeners. - */ +xine_ao_driver_t *xine_load_audio_output_plugin (xine_t *self, char *id); -void xine_send_event(xine_t *this, xine_event_t *event); -/* - * register an codec reporting callback. - * return 0 if ok - * obs: set to NULL to unregister - */ - -int xine_register_report_codec_cb(xine_t *this, xine_report_codec_t report_codec, - void *user_data); - - -/* - * snapshot function - * - * returns: - * width, height : size of image (be aware that u,v may be subsampled) - * ratio_code : aspect ratio of the frame - * format : subsampling format YUV 4:2:0 or 4:2:2 - * y : lumiance information - * u,v : subsample color information - */ -int xine_get_current_frame (xine_t *this, int *width, int *height, - int *ratio_code, int *format, - uint8_t **y, uint8_t **u, - uint8_t **v); - -#define XINE_ASPECT_RATIO_SQUARE 1 -#define XINE_ASPECT_RATIO_4_3 2 -#define XINE_ASPECT_RATIO_ANAMORPHIC 3 -#define XINE_ASPECT_RATIO_211_1 4 -#define XINE_ASPECT_RATIO_PAN_SCAN 41 -#define XINE_ASPECT_RATIO_DONT_TOUCH 42 - -osd_renderer_t *xine_get_osd_renderer (xine_t *this); - -/* - * xine log functions - */ - -char **xine_get_log_names (xine_t *this); -void xine_log (xine_t *this, int buf, const char *format, ...); -char **xine_get_log (xine_t *this, int buf); -int xine_get_log_section_count (xine_t *this); - - -/* - * xine error reporting - */ - -#define XINE_ERROR_NONE 0 -#define XINE_ERROR_NO_INPUT_PLUGIN 1 -#define XINE_ERROR_NO_DEMUXER_PLUGIN 2 -#define XINE_ERROR_DEMUXER_FAILED 3 - -int xine_get_error (xine_t *this); - - -/* - * demuxer helper functions from demux.c - */ +void xine_set_speed (xine_t *this, int speed) ; -void xine_demux_flush_engine(xine_t *this); +int xine_get_spu_lang (xine_t *this, int channel, char *str) ; -void xine_demux_control_newpts( xine_t *this, int64_t pts, uint32_t flags ); +void xine_select_spu_channel (xine_t *this, int channel) ; -void xine_demux_control_start( xine_t *this ); +int xine_get_audio_channel (xine_t *this) ; -void xine_demux_control_end( xine_t *this, uint32_t flags ); +int xine_get_spu_channel (xine_t *this) ; #ifdef __cplusplus } diff --git a/src/xine-engine/xine_plugin.h b/src/xine-engine/xine_plugin.h new file mode 100644 index 000000000..c9ebc6055 --- /dev/null +++ b/src/xine-engine/xine_plugin.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2000-2002 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: xine_plugin.h,v 1.2 2002/09/04 23:31:13 guenter Exp $ + * + * generic plugin definitions + * + */ + +#ifndef XINE_PLUGIN_H +#define XINE_PLUGIN_H + +#define PLUGIN_NONE 0 +#define PLUGIN_INPUT 1 +#define PLUGIN_DEMUX 2 +#define PLUGIN_AUDIO_DECODER 3 +#define PLUGIN_VIDEO_DECODER 4 +#define PLUGIN_SPU_DECODER 5 +#define PLUGIN_AUDIO_OUT 6 +#define PLUGIN_VIDEO_OUT 7 + + +typedef struct { + uint8_t type; /* one of the PLUGIN_* constants above */ + uint8_t API; /* API version supported by this plugin */ + const char *id; /* a name that identifies this plugin */ + uint32_t version; /* version number, increased every release */ + void *special_info; /* plugin-type specific, see structs below */ + void *(*init)(xine_t *, void *); /* used to get/initialize an instance*/ +} plugin_info_t; + + +/* special_info for a video output plugin */ +typedef struct { + int priority; /* priority of this plugin for auto-probing */ + char *description; /* human-readable description of this plugin */ + int visual_type; /* visual type supported by this plugin */ +} vo_info_t; + +/* special info for a audio output plugin */ +typedef struct { + char *description; + int priority; +} ao_info_t ; + +/* special_info for a decoder plugin */ +typedef struct { + uint32_t *supported_types;/* streamtypes this decoder can handle */ + int priority; +} decoder_info_t; + +#endif |