diff options
-rw-r--r-- | doc/MRLs | 71 | ||||
-rw-r--r-- | include/xine.h.in | 6 | ||||
-rw-r--r-- | src/xine-engine/audio_decoder.c | 5 | ||||
-rw-r--r-- | src/xine-engine/configfile.c | 16 | ||||
-rw-r--r-- | src/xine-engine/load_plugins.c | 25 | ||||
-rw-r--r-- | src/xine-engine/video_decoder.c | 7 | ||||
-rw-r--r-- | src/xine-engine/xine.c | 184 | ||||
-rw-r--r-- | src/xine-engine/xine_internal.h | 3 |
8 files changed, 278 insertions, 39 deletions
diff --git a/doc/MRLs b/doc/MRLs new file mode 100644 index 000000000..45b43ecfd --- /dev/null +++ b/doc/MRLs @@ -0,0 +1,71 @@ +proposition of generic syntax of MRLs +===================================== + +This document defines a draft for a syntactic specification of MRLs as +used by xine-lib. The language of MRLs is designed to be a true subset +of the language of URIs as given in RFC2396. A type 2 grammar for the +language of MRLs is given in EBNF below. + +Semantically, MRLs consist of two distinct parts that are evaluated by +different components of the xine architecture. The first part, +derivable from the symbol <input_source> in the given grammar, is +completely handed to the input plugins, with input plugins signaling +if they can handle the MRL. +The second part, derivable from <stream_setup> and delimited from the +first by a crosshatch ('#') contains parameters that modify the +initialization and playback behaviour of the stream to which the MRL +is passed. The possible parameters should be self-explaining, when +looking into the grammar. + +The following definition should be regarded as a guideline only. +Of course any given input plugin only understands a subset of all +possible MRLs. On the other hand, invalid MRLs according to this +definition might be understood for convenience reasons. +Some user awareness is required at this point. + +EBNF grammar for MRLs: + +<mrl> ::= <input_source>[#<stream_setup>] +<input_source> ::= (<absolute_mrl>|<relative_mrl>) +<absolute_mrl> ::= <input>:(<net_path>|<abs_path>)[?<query>] +<relative_mrl> ::= (<abs_path>|<rel_path>) +<net_path> ::= //<authority>[<abs_path>] +<abs_path> ::= /<path_segments> +<rel_path> ::= <rel_segment>[<abs_path>] +<rel_segment> ::= <rel_char>{<rel_char>} +<rel_char> ::= (<unreserved>|<escaped>|;|@|&|=|+|$|,) +<input> ::= <alpha>{(<alpha>|<digit>|+|-|.)} +<authority> ::= (<server>|<reg_name>) +<server> ::= [[<userinfo>@]<host>[:<port>]] +<userinfo> ::= {(<unreserved>|<escaped>|;|:|&|=|+|$|,)} +<host> ::= (<hostname>|<ipv4_address>) +<hostname> ::= {<domainlabel>.}<toplabel>[.] +<domainlabel> ::= (<alphanum>|<alphanum>{(<alphanum>|-)}<alphanum>) +<toplabel> ::= (<alpha>|<alpha>{(<alphanum>|-)}<alphanum>) +<ipv4_address> ::= <digit>{<digit>}.<digit>{<digit>}.<digit>{<digit>}.<digit>{<digit>} +<port> ::= {<digit>} +<reg_name> ::= <reg_char>{<reg_char>} +<reg_char> ::= (<unreserved>|<escaped>|;|:|@|&|=|+|$|,) +<path_segments> ::= <segment>{/<segment>} +<segment> ::= {<path_char>}{;<param>} +<param> ::= {<path_char>} +<path_char> ::= (<unreserved>|<escaped>|:|@|&|=|+|$|,) +<query> ::= {<mrl_char>} +<stream_setup> ::= <stream_option>;{<stream_option>} +<stream_option> ::= (<configoption>|<demux>|novideo|noaudio|nospu) +<configoption> ::= <configentry>:<configvalue> +<configentry> ::= <unreserved>{<unreserved>} +<configvalue> ::= <conf_char>{<conf_char>} +<demux> ::= demux:<stream_char>{<stream_char>} +<stream_char> ::= (<unreserved>|<escaped>|:|@|&|=|+|$|,) +<mrl_char> ::= (<reserved>|<unreserved>|<escaped>) +<reserved> ::= (;|/|?|:|@|&|=|+|$|,) +<unreserved> ::= (<alphanum>|<mark>) +<mark> ::= (-|_|.|!|~|*|'|(|)) +<escaped> ::= %<hex><hex> +<hex> ::= (<digit>|A|B|C|D|E|F|a|b|c|d|e|f) +<alphanum> ::= (<alpha>|<digit>) +<alpha> ::= (<lowalpha>|<upalpha>) +<lowalpha> ::= (a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z) +<upalpha> ::= (A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z) +<digit> ::= (0|1|2|3|4|5|6|7|8|9) diff --git a/include/xine.h.in b/include/xine.h.in index f48b4d508..1a84ff8bb 100644 --- a/include/xine.h.in +++ b/include/xine.h.in @@ -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.h.in,v 1.30 2002/10/28 03:24:42 miguelfreitas Exp $ + * $Id: xine.h.in,v 1.31 2002/10/31 16:58:13 mroi Exp $ * * public xine-lib (libxine) interface and documentation * @@ -293,6 +293,7 @@ void xine_register_log_cb (xine_t *self, xine_log_cb_t cb, #define XINE_ERROR_NO_INPUT_PLUGIN 1 #define XINE_ERROR_NO_DEMUX_PLUGIN 2 #define XINE_ERROR_DEMUX_FAILED 3 +#define XINE_ERROR_MALFORMED_MRL 4 /* * xine engine parameters @@ -369,6 +370,9 @@ void xine_register_log_cb (xine_t *self, xine_log_cb_t cb, #define XINE_STREAM_INFO_HAS_CHAPTERS 17 #define XINE_STREAM_INFO_HAS_VIDEO 18 #define XINE_STREAM_INFO_HAS_AUDIO 19 +#define XINE_STREAM_INFO_IGNORE_VIDEO 20 +#define XINE_STREAM_INFO_IGNORE_AUDIO 21 +#define XINE_STREAM_INFO_IGNORE_SPU 22 /* xine_get_meta_info */ diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c index 890298251..82dc22baf 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.87 2002/10/29 16:02:43 mroi Exp $ + * $Id: audio_decoder.c,v 1.88 2002/10/31 16:58:14 mroi Exp $ * * * functions that implement audio decoding @@ -173,6 +173,9 @@ void *audio_decoder_loop (void *stream_gen) { default: + if (stream->stream_info[XINE_STREAM_INFO_IGNORE_AUDIO]) + break; + xine_profiler_start_count (prof_audio_decode); if ( (buf->type & 0xFF000000) == BUF_AUDIO_BASE ) { diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c index c82bdde17..76c3a293d 100644 --- a/src/xine-engine/configfile.c +++ b/src/xine-engine/configfile.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: configfile.c,v 1.39 2002/10/31 10:45:36 mroi Exp $ + * $Id: configfile.c,v 1.40 2002/10/31 16:58:15 mroi Exp $ * * config object (was: file) management - implementation * @@ -792,13 +792,11 @@ int xine_config_change_opt(config_values_t *config, const char *opt) { printf ("configfile: change_opt '%s'\n", opt); #endif - if(config && opt && (!strncasecmp(opt, "opt:", 4))) { - char *optsafe; + if(config && opt) { char *key, *value; - xine_strdupa(optsafe, opt); - key = &optsafe[4]; - value = strrchr(optsafe, '='); + key = strdup(opt); + value = strrchr(key, ':'); if(key && strlen(key) && value && strlen(value)) { @@ -824,14 +822,14 @@ int xine_config_change_opt(config_values_t *config, const char *opt) { break; case CONFIG_TYPE_UNKNOWN: -#ifdef LOG - printf("configfile: change_opt() try to update an CONFIG_TYPE_UNKNOWN entry\n"); -#endif + entry->unknown_value = strdup(value); + handled = 1; break; } } } + free(key); } return handled; diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c index 71d7a8750..510d5d04a 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.107 2002/10/27 01:52:15 guenter Exp $ + * $Id: load_plugins.c,v 1.108 2002/10/31 16:58:16 mroi Exp $ * * * Load input/demux/audio_out/video_out/codec plugins @@ -697,6 +697,29 @@ demux_plugin_t *find_demux_plugin (xine_stream_t *stream, input_plugin_t *input) return NULL; } +demux_plugin_t *find_demux_plugin_by_name(xine_stream_t *stream, const char *name, input_plugin_t *input) { + + plugin_catalog_t *catalog = stream->xine->plugin_catalog; + plugin_node_t *node; + demux_plugin_t *plugin; + + pthread_mutex_lock(&catalog->lock); + node = xine_list_first_content(catalog->demux); + + while (node) { + if (strcasecmp(node->info->id, name) == 0) { + if ((plugin = ((demux_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream, input))) { + pthread_mutex_unlock (&catalog->lock); + return plugin; + } + } + node = xine_list_next_content(catalog->demux); + } + + pthread_mutex_unlock(&catalog->lock); + return NULL; +} + const char *const *xine_get_autoplay_input_plugin_ids(xine_t *this) { plugin_catalog_t *catalog; diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index 9b3eff3ba..e59ef3255 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.106 2002/10/29 16:02:49 mroi Exp $ + * $Id: video_decoder.c,v 1.107 2002/10/31 16:58:23 mroi Exp $ * */ @@ -135,6 +135,8 @@ void *video_decoder_loop (void *stream_gen) { case BUF_SPU_PACKAGE: case BUF_SPU_NAV: xine_profiler_start_count (prof_spu_decode); + if (stream->stream_info[XINE_STREAM_INFO_IGNORE_SPU]) + break; if (!stream->spu_decoder_plugin) { update_spu_decoder(stream, buf->type); } @@ -281,6 +283,9 @@ void *video_decoder_loop (void *stream_gen) { default: xine_profiler_start_count (prof_video_decode); + + if (stream->stream_info[XINE_STREAM_INFO_IGNORE_VIDEO]) + break; if ( (buf->type & 0xFF000000) == BUF_VIDEO_BASE ) { diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index a7f6142a8..a6990ff6b 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.185 2002/10/30 17:51:13 miguelfreitas Exp $ + * $Id: xine.c,v 1.186 2002/10/31 16:58:24 mroi Exp $ * * top-level xine functions * @@ -368,6 +368,7 @@ static int xine_open_internal (xine_stream_t *stream, const char *mrl) { int header_count_audio; int header_count_video; + char *stream_setup; #ifdef LOG printf ("xine: xine_open_internal '%s'...\n", mrl); @@ -384,43 +385,176 @@ static int xine_open_internal (xine_stream_t *stream, const char *mrl) { #endif /* - * find an input plugin + * look for a stream_setup in MRL */ + + if ((stream_setup = strchr(mrl, '#'))) { + char *input_source = (char *)malloc(stream_setup - mrl + 1); + memcpy(input_source, mrl, stream_setup - mrl); + input_source[stream_setup - mrl] = '\0'; + + /* + * find an input plugin + */ - if (!(stream->input_plugin = find_input_plugin (stream, mrl))) { - xine_log (stream->xine, XINE_LOG_MSG, - _("xine: cannot find input plugin for this MRL\n")); + if (!(stream->input_plugin = find_input_plugin (stream, input_source))) { + xine_log (stream->xine, XINE_LOG_MSG, + _("xine: cannot find input plugin for this MRL\n")); - stream->err = XINE_ERROR_NO_INPUT_PLUGIN; - return 0; - } - stream->input_class = stream->input_plugin->input_class; - stream->meta_info[XINE_META_INFO_INPUT_PLUGIN] - = strdup (stream->input_class->get_identifier (stream->input_class)); + stream->err = XINE_ERROR_NO_INPUT_PLUGIN; + free(input_source); + return 0; + } + stream->input_class = stream->input_plugin->input_class; + stream->meta_info[XINE_META_INFO_INPUT_PLUGIN] + = strdup (stream->input_class->get_identifier (stream->input_class)); + free(input_source); #ifdef LOG - printf ("xine: input plugin %s found\n", - stream->input_plugin->input_class->get_identifier(stream->input_plugin->input_class)); + printf ("xine: input plugin %s found\n", + stream->input_plugin->input_class->get_identifier(stream->input_plugin->input_class)); #endif - /* - * find a demux plugin - */ - if (!(stream->demux_plugin=find_demux_plugin (stream, stream->input_plugin))) { - xine_log (stream->xine, XINE_LOG_MSG, - _("xine: couldn't find demux for >%s<\n"), mrl); - stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; + while (stream_setup && *stream_setup && *(++stream_setup)) { + if (strncasecmp(stream_setup, "demux", 5) == 0) { + if (*(stream_setup += 5) == ':') { + /* demuxer specified by name */ + char *tmp = ++stream_setup; + char *demux_name; + stream_setup = strchr(stream_setup, ';'); + if (stream_setup) { + demux_name = (char *)malloc(stream_setup - tmp + 1); + memcpy(demux_name, tmp, stream_setup - tmp); + demux_name[stream_setup - tmp] = '\0'; + } else { + demux_name = (char *)malloc(strlen(tmp)); + memcpy(demux_name, tmp, strlen(tmp)); + demux_name[strlen(tmp)] = '\0'; + } + if (!(stream->demux_plugin = find_demux_plugin_by_name(stream, demux_name, stream->input_plugin))) { + xine_log(stream->xine, XINE_LOG_MSG, + _("xine: specified demuxer %s failed to start\n"), demux_name); + stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; + stream->status = XINE_STATUS_STOP; + free(demux_name); + return 0; + } +#ifdef LOG + printf ("xine: demux and input plugin found\n"); +#endif - stream->status = XINE_STATUS_STOP; - return 0; + stream->meta_info[XINE_META_INFO_SYSTEMLAYER] + = strdup (stream->demux_plugin->demux_class->get_identifier(stream->demux_plugin->demux_class)); + free(demux_name); + } else { + printf("xine: error while parsing mrl\n"); + stream->err = XINE_ERROR_MALFORMED_MRL; + stream->status = XINE_STATUS_STOP; + return 0; + } + continue; + } + if (strncasecmp(stream_setup, "novideo", 7) == 0) { + stream_setup += 7; + if (*stream_setup == ';' || *stream_setup == '\0') { + stream->stream_info[XINE_STREAM_INFO_IGNORE_VIDEO] = 1; + } else { + printf("xine: error while parsing mrl\n"); + stream->err = XINE_ERROR_MALFORMED_MRL; + stream->status = XINE_STATUS_STOP; + return 0; + } + printf("xine: ignoring video\n"); + continue; + } + if (strncasecmp(stream_setup, "noaudio", 7) == 0) { + stream_setup += 7; + if (*stream_setup == ';' || *stream_setup == '\0') { + stream->stream_info[XINE_STREAM_INFO_IGNORE_AUDIO] = 1; + } else { + printf("xine: error while parsing mrl\n"); + stream->err = XINE_ERROR_MALFORMED_MRL; + stream->status = XINE_STATUS_STOP; + return 0; + } + printf("xine: ignoring audio\n"); + continue; + } + if (strncasecmp(stream_setup, "nospu", 5) == 0) { + stream_setup += 5; + if (*stream_setup == ';' || *stream_setup == '\0') { + stream->stream_info[XINE_STREAM_INFO_IGNORE_SPU] = 1; + } else { + printf("xine: error while parsing mrl\n"); + stream->err = XINE_ERROR_MALFORMED_MRL; + stream->status = XINE_STATUS_STOP; + return 0; + } + printf("xine: ignoring subpicture\n"); + continue; + } + { + /* when we got here, the stream setup parameter must be a config entry */ + char *tmp = stream_setup; + if ((stream_setup = strchr(stream_setup, ';'))) { + char *config_entry = (char *)malloc(stream_setup - tmp + 1); + memcpy(config_entry, tmp, stream_setup - tmp); + config_entry[stream_setup - tmp] = '\0'; + xine_config_change_opt(stream->xine->config, config_entry); + free(config_entry); + } else { + xine_config_change_opt(stream->xine->config, tmp); + } + } + } + + } else { + + /* no stream setup found in MRL, continue as ususal */ + + /* + * find an input plugin + */ + + if (!(stream->input_plugin = find_input_plugin (stream, mrl))) { + xine_log (stream->xine, XINE_LOG_MSG, + _("xine: cannot find input plugin for this MRL\n")); + + stream->err = XINE_ERROR_NO_INPUT_PLUGIN; + return 0; + } + stream->input_class = stream->input_plugin->input_class; + stream->meta_info[XINE_META_INFO_INPUT_PLUGIN] + = strdup (stream->input_class->get_identifier (stream->input_class)); + +#ifdef LOG + printf ("xine: input plugin %s found\n", + stream->input_plugin->input_class->get_identifier(stream->input_plugin->input_class)); +#endif } + + if (!stream->demux_plugin) { + + /* + * find a demux plugin + */ + if (!(stream->demux_plugin=find_demux_plugin (stream, stream->input_plugin))) { + xine_log (stream->xine, XINE_LOG_MSG, + _("xine: couldn't find demux for >%s<\n"), mrl); + stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; + + stream->status = XINE_STATUS_STOP; + return 0; + } + #ifdef LOG - printf ("xine: demux and input plugin found\n"); + printf ("xine: demux and input plugin found\n"); #endif - stream->meta_info[XINE_META_INFO_SYSTEMLAYER] - = strdup (stream->demux_plugin->demux_class->get_identifier(stream->demux_plugin->demux_class)); + stream->meta_info[XINE_META_INFO_SYSTEMLAYER] + = strdup (stream->demux_plugin->demux_class->get_identifier(stream->demux_plugin->demux_class)); + } /* * send and decode headers diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index 0beb014ae..ee4f83e77 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.110 2002/10/30 17:51:13 miguelfreitas Exp $ + * $Id: xine_internal.h,v 1.111 2002/10/31 16:58:25 mroi Exp $ * */ @@ -228,6 +228,7 @@ void xine_handle_stream_end (xine_stream_t *stream, int non_user); input_plugin_t *find_input_plugin (xine_stream_t *stream, const char *mrl); demux_plugin_t *find_demux_plugin (xine_stream_t *stream, input_plugin_t *input); +demux_plugin_t *find_demux_plugin_by_name (xine_stream_t *stream, const char *name, input_plugin_t *input); /* create decoder fifos and threads */ |