summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDarren Salt <linux@youmustbejoking.demon.co.uk>2008-01-24 13:47:01 +0000
committerDarren Salt <linux@youmustbejoking.demon.co.uk>2008-01-24 13:47:01 +0000
commitd3f318eec71d38ce34f590daef0fed1f6cbf2eae (patch)
tree0d9e5b6b1e1832e206a229d2da3f24a39af2d8e5 /src
parent2f9b558e6ff6f599e4e6ef3422f48b17c44f178b (diff)
parent7598a6152ba55ef0ff8dda7f1b7729d2bb22a594 (diff)
downloadxine-lib-d3f318eec71d38ce34f590daef0fed1f6cbf2eae.tar.gz
xine-lib-d3f318eec71d38ce34f590daef0fed1f6cbf2eae.tar.bz2
Merge from -plugin-loader branch.
base64.{c,h} functions are given "xine_" prefixes and are exported. --HG-- rename : src/xine-utils/base64.h => include/xine/base64.h rename : src/xine-engine/configfile.h => include/xine/configfile.h rename : src/xine-engine/plugin_catalog.h => include/xine/plugin_catalog.h rename : src/xine-utils/xineutils.h => include/xine/xineutils.h rename : src/input/base64.c => src/xine-utils/base64.c
Diffstat (limited to 'src')
-rw-r--r--src/input/Makefile.am2
-rw-r--r--src/input/base64.h91
-rw-r--r--src/input/input_cdda.c3
-rw-r--r--src/xine-engine/configfile.c355
-rw-r--r--src/xine-engine/load_plugins.c191
-rw-r--r--src/xine-engine/xine.c3
-rw-r--r--src/xine-utils/Makefile.am1
-rw-r--r--src/xine-utils/base64.c (renamed from src/input/base64.c)71
8 files changed, 558 insertions, 159 deletions
diff --git a/src/input/Makefile.am b/src/input/Makefile.am
index 37ba30a0e..ca7e6dabd 100644
--- a/src/input/Makefile.am
+++ b/src/input/Makefile.am
@@ -112,7 +112,7 @@ xineplug_inp_dvb_la_CPPFLAGS = $(AM_CPPFLAGS) $(XDG_BASEDIR_CPPFLAGS)
xineplug_inp_rtsp_la_SOURCES = input_rtsp.c net_buf_ctrl.c
xineplug_inp_rtsp_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) libreal/libreal.la librtsp/librtsp.la
-xineplug_inp_cdda_la_SOURCES = input_cdda.c media_helper.c sha1.c sha1.h base64.c base64.h
+xineplug_inp_cdda_la_SOURCES = input_cdda.c media_helper.c sha1.c sha1.h
xineplug_inp_cdda_la_DEPS = $(XDG_BASEDIR_DEPS)
xineplug_inp_cdda_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(XDG_BASEDIR_LIBS)
xineplug_inp_cdda_la_CPPFLAGS = $(AM_CPPFLAGS) $(XDG_BASEDIR_CPPFLAGS)
diff --git a/src/input/base64.h b/src/input/base64.h
deleted file mode 100644
index 5cc94d7f0..000000000
--- a/src/input/base64.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2000 Robert Kaye
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * Base64 encoding modified for Musicbrainz
- * relicensed under the GNU General Public License for use in xine-lib
- */
-/* --------------------------------------------------------------------------
-
- MusicBrainz -- The Internet music metadatabase
-
- Copyright (C) 2000 Robert Kaye
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
-
-----------------------------------------------------------------------------*/
-/*
- * Program: RFC-822 routines (originally from SMTP)
- *
- * Author: Mark Crispin
- * Networks and Distributed Computing
- * Computing & Communications
- * University of Washington
- * Administration Building, AG-44
- * Seattle, WA 98195
- * Internet: MRC@CAC.Washington.EDU
- *
- * Date: 27 July 1988
- * Last Edited: 10 September 1998
- *
- * Sponsorship: The original version of this work was developed in the
- * Symbolic Systems Resources Group of the Knowledge Systems
- * Laboratory at Stanford University in 1987-88, and was funded
- * by the Biomedical Research Technology Program of the National
- * Institutes of Health under grant number RR-00785.
- *
- * Original version Copyright 1988 by The Leland Stanford Junior University
- * Copyright 1998 by the University of Washington
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notices appear in all copies and that both the
- * above copyright notices and this permission notice appear in supporting
- * documentation, and that the name of the University of Washington or The
- * Leland Stanford Junior University not be used in advertising or publicity
- * pertaining to distribution of the software without specific, written prior
- * permission. This software is made available "as is", and
- * THE UNIVERSITY OF WASHINGTON AND THE LELAND STANFORD JUNIOR UNIVERSITY
- * DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE,
- * INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL THE UNIVERSITY OF
- * WASHINGTON OR THE LELAND STANFORD JUNIOR UNIVERSITY BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- * CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef BASE64_H
-#define BASE64_H
-
-unsigned char *rfc822_binary (void *src,unsigned long srcl,unsigned long *len);
-
-#endif
diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c
index f8819f9f4..0e378c299 100644
--- a/src/input/input_cdda.c
+++ b/src/input/input_cdda.c
@@ -65,7 +65,6 @@
*/
#include "sha1.h"
-#include "base64.h"
#include <xine/xine_internal.h>
#include <xine/xineutils.h>
#include <xine/input_plugin.h>
@@ -1936,7 +1935,7 @@ static void _cdda_cdindex(cdda_input_plugin_t *this, cdrom_toc *toc) {
sha_final(digest, &sha);
- base64 = rfc822_binary(digest, 20, &size);
+ base64 = xine_rfc822_binary(digest, 20, &size);
base64[size] = 0;
_x_meta_info_set_utf8(this->stream, XINE_META_INFO_CDINDEX_DISCID, base64);
diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c
index 2934b7fef..550c0372f 100644
--- a/src/xine-engine/configfile.c
+++ b/src/xine-engine/configfile.c
@@ -32,6 +32,7 @@
#include <string.h>
#include <unistd.h>
#include <xine/configfile.h>
+#include "bswap.h"
#define LOG_MODULE "configfile"
#define LOG_VERBOSE
@@ -453,6 +454,8 @@ static void config_reset_value(cfg_entry_t *entry) {
entry->num_value = 0;
}
+static void config_shallow_copy(xine_cfg_entry_t *dest, cfg_entry_t *src);
+
static cfg_entry_t *config_register_key (config_values_t *this,
const char *key,
int exp_level,
@@ -486,6 +489,14 @@ static cfg_entry_t *config_register_key (config_values_t *this,
entry->callback_data = cb_data;
}
+ /* we created a new entry, call the callback */
+ if (this->new_entry_cb) {
+ xine_cfg_entry_t cb_entry;
+
+ config_shallow_copy(&cb_entry, entry);
+ this->new_entry_cb(this->new_entry_cbdata, &cb_entry);
+ }
+
return entry;
}
@@ -1193,6 +1204,322 @@ static void config_unregister_cb (config_values_t *this, const char *key) {
}
}
+static void config_set_new_entry_callback (config_values_t *this, xine_config_cb_t new_entry_cb, void* cbdata) {
+ pthread_mutex_lock(&this->config_lock);
+ this->new_entry_cb = new_entry_cb;
+ this->new_entry_cbdata = cbdata;
+ pthread_mutex_unlock(&this->config_lock);
+}
+
+static void config_unset_new_entry_callback (config_values_t *this) {
+ pthread_mutex_lock(&this->config_lock);
+ this->new_entry_cb = NULL;
+ this->new_entry_cbdata = NULL;
+ pthread_mutex_unlock(&this->config_lock);
+}
+
+static int put_int(uint8_t *buffer, int pos, int value) {
+ int32_t value_int32 = (int32_t)value;
+
+ buffer[pos] = value_int32 & 0xFF;
+ buffer[pos + 1] = (value_int32 >> 8) & 0xFF;
+ buffer[pos + 2] = (value_int32 >> 16) & 0xFF;
+ buffer[pos + 3] = (value_int32 >> 24) & 0xFF;
+
+ return 4;
+}
+
+static int put_string(uint8_t *buffer, int pos, const char *value, int value_len) {
+ pos += put_int(buffer, pos, value_len);
+ memcpy(&buffer[pos], value, value_len);
+
+ return 4 + value_len;
+}
+
+static char* config_get_serialized_entry (config_values_t *this, const char *key) {
+ char *output = NULL;
+ cfg_entry_t *entry, *prev;
+
+ pthread_mutex_lock(&this->config_lock);
+ config_lookup_entry_int(this, key, &entry, &prev);
+
+ if (entry) {
+ /* now serialize this stuff
+ fields to serialize :
+ int type;
+ int range_min;
+ int range_max;
+ int exp_level;
+ int num_default;
+ int num_value;
+ char *key;
+ char *str_default;
+ char *description;
+ char *help;
+ char **enum_values;
+ */
+
+ int key_len = 0;
+ int str_default_len = 0;
+ int description_len = 0;
+ int help_len = 0;
+ unsigned long output_len;
+ unsigned long total_len;
+ int value_count;
+ int value_len[10];
+ int pos = 0;
+ int i;
+
+ if (entry->key)
+ key_len = strlen(entry->key);
+ if (entry->str_default)
+ str_default_len = strlen(entry->str_default);
+ if (entry->description)
+ description_len = strlen(entry->description);
+ if (entry->help)
+ help_len = strlen(entry->help);
+
+ /* integers */
+ /* value: 4 bytes */
+ total_len = 6 * sizeof(int32_t);
+
+ /* strings (size + char buffer)
+ * length: 4 bytes
+ * buffer: length bytes
+ */
+ total_len += sizeof(int32_t) + key_len;
+ total_len += sizeof(int32_t) + str_default_len;
+ total_len += sizeof(int32_t) + description_len;
+ total_len += sizeof(int32_t) + help_len;
+
+ /* enum values...
+ * value count: 4 bytes
+ * for each value:
+ * length: 4 bytes
+ * buffer: length bytes
+ */
+ value_count = 0;
+ total_len += sizeof(int32_t); /* value count */
+
+ char **cur_value = entry->enum_values;
+ if (cur_value) {
+ while (*cur_value && (value_count < (sizeof(value_len) / sizeof(int) ))) {
+ value_len[value_count] = strlen(*cur_value);
+ total_len += sizeof(int32_t) + value_len[value_count];
+ value_count++;
+ cur_value++;
+ }
+ }
+
+ /* Now we have the length needed to serialize the entry and the length of each string */
+ uint8_t *buffer = malloc (total_len);
+ if (!buffer) return NULL;
+
+ /* Let's go */
+
+ /* the integers */
+ pos += put_int(buffer, pos, entry->type);
+ pos += put_int(buffer, pos, entry->range_min);
+ pos += put_int(buffer, pos, entry->range_max);
+ pos += put_int(buffer, pos, entry->exp_level);
+ pos += put_int(buffer, pos, entry->num_default);
+ pos += put_int(buffer, pos, entry->num_value);
+
+ /* the strings */
+ pos += put_string(buffer, pos, entry->key, key_len);
+ pos += put_string(buffer, pos, entry->str_default, str_default_len);
+ pos += put_string(buffer, pos, entry->description, description_len);
+ pos += put_string(buffer, pos, entry->help, help_len);
+
+ /* the enum stuff */
+ pos += put_int(buffer, pos, value_count);
+ cur_value = entry->enum_values;
+
+ for (i = 0; i < value_count; i++) {
+ pos += put_string(buffer, pos, *cur_value, value_len[i]);
+ cur_value++;
+ }
+
+ /* and now the output encoding */
+ output = xine_base64_encode (buffer, total_len, &output_len);
+
+ free(buffer);
+ }
+ pthread_mutex_unlock(&this->config_lock);
+
+ return output;
+
+}
+
+static int get_int(uint8_t *buffer, int buffer_size, int pos, int *value) {
+ int32_t value_int32;
+
+ if ((pos + sizeof(int32_t)) > buffer_size)
+ return 0;
+
+ value_int32 = _X_LE_32(&buffer[pos]);
+ *value = (int)value_int32;
+ return sizeof(int32_t);
+}
+
+static int get_string(uint8_t *buffer, int buffer_size, int pos, char **value) {
+ int len;
+ int bytes = get_int(buffer, buffer_size, pos, &len);
+ *value = NULL;
+
+ if (!bytes || (len < 0) || (len > 1024*64))
+ return 0;
+
+ char *str = malloc(len + 1);
+ pos += bytes;
+ memcpy(str, &buffer[pos], len);
+ str[len] = 0;
+
+ *value = str;
+ return bytes + len;
+}
+
+static char* config_register_serialized_entry (config_values_t *this, const char *value) {
+ /*
+ fields serialized :
+ int type;
+ int range_min;
+ int range_max;
+ int exp_level;
+ int num_default;
+ int num_value;
+ char *key;
+ char *str_default;
+ char *description;
+ char *help;
+ char **enum_values;
+ */
+ int type;
+ int range_min;
+ int range_max;
+ int exp_level;
+ int num_default;
+ int num_value;
+ char *key = NULL;
+ char *str_default = NULL;
+ char *description = NULL;
+ char *help = NULL;
+ char **enum_values = NULL;
+
+ int bytes;
+ int pos;
+ void *output = NULL;
+ unsigned long output_len;
+ int value_count = 0;
+ int i;
+
+ output = xine_base64_decode (value, strlen(value), &output_len);
+
+ pos = 0;
+ pos += bytes = get_int(output, output_len, pos, &type);
+ if (!bytes) goto exit;
+
+ pos += bytes = get_int(output, output_len, pos, &range_min);
+ if (!bytes) goto exit;
+
+ pos += bytes = get_int(output, output_len, pos, &range_max);
+ if (!bytes) goto exit;
+
+ pos += bytes = get_int(output, output_len, pos, &exp_level);
+ if (!bytes) goto exit;
+
+ pos += bytes = get_int(output, output_len, pos, &num_default);
+ if (!bytes) goto exit;
+
+ pos += bytes = get_int(output, output_len, pos, &num_value);
+ if (!bytes) goto exit;
+
+ pos += bytes = get_string(output, output_len, pos, &key);
+ if (!bytes) goto exit;
+
+ pos += bytes = get_string(output, output_len, pos, &str_default);
+ if (!bytes) goto exit;
+
+ pos += bytes = get_string(output, output_len, pos, &description);
+ if (!bytes) goto exit;
+
+ pos += bytes = get_string(output, output_len, pos, &help);
+ if (!bytes) goto exit;
+
+ pos += bytes = get_int(output, output_len, pos, &value_count);
+ if (!bytes) goto exit;
+ if ((value_count < 0) || (value_count > 256)) goto exit;
+
+ enum_values = malloc (sizeof(void*) * value_count + 1);
+ for (i = 0; i < value_count; i++) {
+ pos += bytes = get_string(output, output_len, pos, &enum_values[i]);
+ if (!bytes) goto exit;
+ }
+ enum_values[value_count] = NULL;
+
+#ifdef LOG
+ printf("config entry deserialization:\n");
+ printf(" key : %s\n", key);
+ printf(" type : %d\n", type);
+ printf(" exp_level : %d\n", exp_level);
+ printf(" num_default: %d\n", num_default);
+ printf(" num_value : %d\n", num_value);
+ printf(" str_default: %s\n", str_default);
+ printf(" range_min : %d\n", range_min);
+ printf(" range_max : %d\n", range_max);
+ printf(" description: %s\n", description);
+ printf(" help : %s\n", help);
+ printf(" enum : %d values\n", value_count);
+
+ for (i = 0; i < value_count; i++) {
+ printf(" enum[%2d]: %s\n", i, enum_values[i]);
+ }
+ printf("\n");
+#endif
+
+ switch (type) {
+ case XINE_CONFIG_TYPE_STRING:
+ switch (num_value) {
+ case 0:
+ this->register_string(this, key, str_default, description, help, exp_level, NULL, NULL);
+ break;
+ default:
+ this->register_filename(this, key, str_default, num_value, description, help, exp_level, NULL, NULL);
+ break;
+ }
+ break;
+ case XINE_CONFIG_TYPE_RANGE:
+ this->register_range(this, key, num_default, range_min, range_max, description, help, exp_level, NULL, NULL);
+ break;
+ case XINE_CONFIG_TYPE_ENUM:
+ this->register_enum(this, key, num_default, enum_values, description, help, exp_level, NULL, NULL);
+ break;
+ case XINE_CONFIG_TYPE_NUM:
+ this->register_num(this, key, num_default, description, help, exp_level, NULL, NULL);
+ break;
+ case XINE_CONFIG_TYPE_BOOL:
+ this->register_bool(this, key, num_default, description, help, exp_level, NULL, NULL);
+ break;
+ case XINE_CONFIG_TYPE_UNKNOWN:
+ break;
+ }
+
+exit:
+ /* cleanup */
+ free(str_default);
+ free(description);
+ free(help);
+ free(output);
+
+ if (enum_values) {
+ for (i = 0; i < value_count; i++) {
+ free(enum_values[i]);
+ }
+ free(enum_values);
+ }
+
+ return key;
+}
config_values_t *_x_config_init (void) {
@@ -1219,18 +1546,22 @@ config_values_t *_x_config_init (void) {
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&this->config_lock, &attr);
- this->register_string = config_register_string;
- this->register_filename = config_register_filename;
- this->register_range = config_register_range;
- this->register_enum = config_register_enum;
- this->register_num = config_register_num;
- this->register_bool = config_register_bool;
- this->update_num = config_update_num;
- this->update_string = config_update_string;
- this->parse_enum = config_parse_enum;
- this->lookup_entry = config_lookup_entry;
- this->unregister_callback = config_unregister_cb;
- this->dispose = config_dispose;
+ this->register_string = config_register_string;
+ this->register_filename = config_register_filename;
+ this->register_range = config_register_range;
+ this->register_enum = config_register_enum;
+ this->register_num = config_register_num;
+ this->register_bool = config_register_bool;
+ this->register_serialized_entry = config_register_serialized_entry;
+ this->update_num = config_update_num;
+ this->update_string = config_update_string;
+ this->parse_enum = config_parse_enum;
+ this->lookup_entry = config_lookup_entry;
+ this->unregister_callback = config_unregister_cb;
+ this->dispose = config_dispose;
+ this->set_new_entry_callback = config_set_new_entry_callback;
+ this->unset_new_entry_callback = config_unset_new_entry_callback;
+ this->get_serialized_entry = config_get_serialized_entry;
return this;
}
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index b179a135d..94afc5b01 100644
--- a/src/xine-engine/load_plugins.c
+++ b/src/xine-engine/load_plugins.c
@@ -49,6 +49,7 @@
/*
#define LOG
+#define DEBUG
*/
#define XINE_ENABLE_EXPERIMENTAL_FEATURES 1
@@ -65,6 +66,8 @@
#include <xine/xineutils.h>
#include <xine/compat.h>
+#define LINE_MAX_LENGTH (1024 * 32) /* 32 KiB */
+
#if 0
static char *plugin_name;
@@ -96,7 +99,7 @@ static void remove_segv_handler(void){
#endif
#endif /* 0 */
-#define CACHE_CATALOG_VERSION 2
+#define CACHE_CATALOG_VERSION 3
static const int plugin_iface_versions[] = {
INPUT_PLUGIN_IFACE_VERSION,
@@ -250,26 +253,26 @@ static void _decoder_priority_cb(void *data, xine_cfg_entry_t *cfg) {
map_decoders((xine_t *)data);
}
-static plugin_info_t *_get_cached_info (xine_t *this,
+static plugin_node_t *_get_cached_node (xine_t *this,
char *filename, off_t filesize, time_t filemtime,
- plugin_info_t *previous_info) {
+ plugin_node_t *previous_node) {
xine_sarray_t *list = this->plugin_catalog->cache_list;
int list_id, list_size;
list_size = xine_sarray_size (list);
for (list_id = 0; list_id < list_size; list_id++) {
plugin_node_t *node = xine_sarray_get (list, list_id);
- if( !previous_info &&
+ if( !previous_node &&
node->file->filesize == filesize &&
node->file->filemtime == filemtime &&
!strcmp( node->file->filename, filename )) {
- return node->info;
+ return node;
}
/* skip previously returned items */
- if( node->info == previous_info )
- previous_info = NULL;
+ if( node == previous_node )
+ previous_node = NULL;
}
return NULL;
@@ -299,6 +302,7 @@ static plugin_file_t *_insert_file (xine_t *this,
static void _insert_node (xine_t *this,
xine_sarray_t *list,
plugin_file_t *file,
+ plugin_node_t *node_cache,
plugin_info_t *info,
int api_version){
@@ -338,6 +342,7 @@ static void _insert_node (xine_t *this,
entry->file = file;
entry->ref = 0;
entry->priority = 0; /* default priority */
+ entry->config_entry_list = (node_cache) ? node_cache->config_entry_list : NULL;
switch (info->type & PLUGIN_TYPE_MASK){
@@ -480,7 +485,8 @@ static plugin_catalog_t *_new_catalog(void){
return catalog;
}
-static void _register_plugins_internal(xine_t *this, plugin_file_t *file, plugin_info_t *info) {
+static void _register_plugins_internal(xine_t *this, plugin_file_t *file,
+ plugin_node_t *node_cache, plugin_info_t *info) {
_x_assert(this);
_x_assert(info);
@@ -506,7 +512,7 @@ static void _register_plugins_internal(xine_t *this, plugin_file_t *file, plugin
int plugin_type = info->type & PLUGIN_TYPE_MASK;
if ((plugin_type > 0) && (plugin_type <= PLUGIN_TYPE_MAX)) {
- _insert_node (this, this->plugin_catalog->plugin_lists[plugin_type - 1], file, info,
+ _insert_node (this, this->plugin_catalog->plugin_lists[plugin_type - 1], file, node_cache, info,
plugin_iface_versions[plugin_type - 1]);
if ((plugin_type == PLUGIN_AUDIO_DECODER) ||
@@ -530,15 +536,17 @@ static void _register_plugins_internal(xine_t *this, plugin_file_t *file, plugin
/* get next info */
if( file && !file->lib_handle ) {
lprintf("get cached info\n");
- info = _get_cached_info (this, file->filename, file->filesize, file->filemtime, info);
+ node_cache = _get_cached_node (this, file->filename, file->filesize, file->filemtime, node_cache);
+ info = (node_cache) ? node_cache->info : NULL;
} else {
+
info++;
}
}
}
void xine_register_plugins(xine_t *self, plugin_info_t *info) {
- _register_plugins_internal(self, NULL, info);
+ _register_plugins_internal(self, NULL, NULL, info);
}
/*
@@ -569,6 +577,7 @@ static void collect_plugins(xine_t *this, char *path){
size_t new_str_size, d_len;
void *lib = NULL;
plugin_info_t *info = NULL;
+ plugin_node_t *node = NULL;
struct stat statbuffer;
@@ -611,7 +620,8 @@ static void collect_plugins(xine_t *this, char *path){
lib = NULL;
/* get the first plugin_info_t */
- info = _get_cached_info (this, str, statbuffer.st_size, statbuffer.st_mtime, NULL);
+ node = _get_cached_node (this, str, statbuffer.st_size, statbuffer.st_mtime, NULL);
+ info = (node) ? node->info : NULL;
#ifdef LOG
if( info )
printf("load_plugins: using cached %s\n", str);
@@ -632,7 +642,7 @@ static void collect_plugins(xine_t *this, char *path){
file = _insert_file(this, this->plugin_catalog->file_list, str, &statbuffer, lib);
- _register_plugins_internal(this, file, info);
+ _register_plugins_internal(this, file, node, info);
}
else {
const char *error = dlerror();
@@ -689,6 +699,25 @@ static inline int _plugin_info_equal(const plugin_info_t *a,
return 1;
}
+static void _attach_entry_to_node (plugin_node_t *node, char *key) {
+
+ if (!node->config_entry_list) {
+ node->config_entry_list = xine_list_new();
+ }
+
+ xine_list_push_back(node->config_entry_list, key);
+}
+
+/*
+ * This callback is called by the config entry system when a plugin register a
+ * new config entry.
+ */
+static void _new_entry_cb (void *user_data, xine_cfg_entry_t *entry) {
+ plugin_node_t *node = (plugin_node_t *)user_data;
+
+ _attach_entry_to_node(node, strdup(entry->key));
+}
+
static int _load_plugin_class(xine_t *this,
plugin_node_t *node,
void *data) {
@@ -716,9 +745,17 @@ static int _load_plugin_class(xine_t *this,
if ((info = dlsym(node->file->lib_handle, "xine_plugin_info"))) {
/* TODO: use sigsegv handler */
- while (info->type != PLUGIN_NONE){
- if (_plugin_info_equal(info, target)){
- if ((node->plugin_class = info->init(this, data))) {
+ while (info->type != PLUGIN_NONE) {
+ if (_plugin_info_equal(info, target)) {
+ config_values_t *config = this->config;
+
+ /* the callback is called for each entry registered by this plugin */
+ lprintf("plugin init %s\n", node->info->id);
+ config->set_new_entry_callback(config, _new_entry_cb, node);
+ node->plugin_class = info->init(this, data);
+ config->unset_new_entry_callback(config);
+
+ if (node->plugin_class) {
inc_file_ref(node->file);
return 1;
} else {
@@ -797,8 +834,12 @@ static void _load_required_plugins(xine_t *this, xine_sarray_t *list) {
while (list_id < list_size) {
plugin_node_t *node = xine_sarray_get(list, list_id);
- if( (node->info->type & PLUGIN_MUST_PRELOAD) && !node->plugin_class ) {
-
+ /*
+ * preload plugins if not cached
+ */
+ if( (node->info->type & PLUGIN_MUST_PRELOAD) && !node->plugin_class &&
+ node->file->lib_handle ) {
+
lprintf("preload plugin %s from %s\n", node->info->id, node->file->filename);
if (! _load_plugin_class (this, node, NULL)) {
@@ -827,7 +868,7 @@ static void load_required_plugins(xine_t *this) {
/*
* save plugin list information to file (cached catalog)
*/
-static void save_plugin_list(FILE *fp, xine_sarray_t *list) {
+static void save_plugin_list(xine_t *this, FILE *fp, xine_sarray_t *list) {
const plugin_node_t *node;
const plugin_file_t *file;
@@ -837,7 +878,6 @@ static void save_plugin_list(FILE *fp, xine_sarray_t *list) {
const vo_info_t *vo_info;
const ao_info_t *ao_info;
const post_info_t *post_info;
-
int i;
int list_id = 0;
int list_size;
@@ -854,9 +894,9 @@ static void save_plugin_list(FILE *fp, xine_sarray_t *list) {
fprintf(fp, "api=%d\n", node->info->API );
fprintf(fp, "id=%s\n", node->info->id );
fprintf(fp, "version=%lu\n", (unsigned long) node->info->version );
-
+
switch (node->info->type & PLUGIN_TYPE_MASK){
-
+
case PLUGIN_VIDEO_OUT:
vo_info = node->info->special_info;
fprintf(fp, "visual_type=%d\n", vo_info->visual_type );
@@ -884,7 +924,7 @@ static void save_plugin_list(FILE *fp, xine_sarray_t *list) {
demuxer_info = node->info->special_info;
fprintf(fp, "demuxer_priority=%d\n", demuxer_info->priority);
break;
-
+
case PLUGIN_INPUT:
input_info = node->info->special_info;
fprintf(fp, "input_priority=%d\n", input_info->priority);
@@ -892,10 +932,27 @@ static void save_plugin_list(FILE *fp, xine_sarray_t *list) {
case PLUGIN_POST:
post_info = node->info->special_info;
- fprintf(fp, "post_type=%lu\n", (unsigned long)post_info->type);
- break;
- }
-
+ fprintf(fp, "post_type=%lu\n", (unsigned long)post_info->type);
+ break;
+ }
+
+ /* config entries */
+ if (node->config_entry_list) {
+ xine_list_iterator_t ite = xine_list_front(node->config_entry_list);
+ while (ite) {
+ char *key = xine_list_get_value(node->config_entry_list, ite);
+
+ /* now serialize the config key */
+ char *key_value = this->config->get_serialized_entry(this->config, key);
+
+ lprintf(" config key: %s, serialization: %d bytes\n", key, strlen(key_value));
+ fprintf(fp, "config_key=%s\n", key_value);
+
+ free (key_value);
+ ite = xine_list_next(node->config_entry_list, ite);
+ }
+ }
+
fprintf(fp, "\n");
list_id++;
}
@@ -904,7 +961,7 @@ static void save_plugin_list(FILE *fp, xine_sarray_t *list) {
/*
* load plugin list information from file (cached catalog)
*/
-static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
+static void load_plugin_list(xine_t *this, FILE *fp, xine_sarray_t *plugins) {
plugin_node_t *node;
plugin_file_t *file;
@@ -917,20 +974,29 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
int i;
uint64_t llu;
unsigned long lu;
- char line[1024];
+ char *line;
char *value;
+ size_t line_len;
int version_ok = 0;
+ line = malloc(LINE_MAX_LENGTH);
+ if (!line)
+ return;
+
node = NULL;
file = NULL;
- while (fgets (line, 1023, fp)) {
+ while (fgets (line, LINE_MAX_LENGTH, fp)) {
if (line[0] == '#')
continue;
-
- if( (value = strchr(line, '\r')) || (value = strchr(line, '\n')) )
- *value = (char) 0; /* eliminate any cr/lf */
+ line_len = strlen(line);
+ if (line_len < 3)
+ continue;
+
+ value = &line[line_len - 1];
+ if( (*value == '\r') || (*value == '\n') )
+ *value-- = (char) 0; /* eliminate any cr/lf */
- if( (value = strchr(line, '\r')) || (value = strchr(line, '\n')) )
+ if( (*value == '\r') || (*value == '\n') )
*value = (char) 0; /* eliminate any cr/lf */
if (line[0] == '[' && version_ok) {
@@ -1005,11 +1071,11 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
xine_xmalloc(sizeof(decoder_info_t));
break;
- case PLUGIN_POST:
- node->info->special_info = post_info =
- xine_xmalloc(sizeof(post_info_t));
- break;
- }
+ case PLUGIN_POST:
+ node->info->special_info = post_info =
+ xine_xmalloc(sizeof(post_info_t));
+ break;
+ }
} else if( !strcmp("api",line) ) {
sscanf(value," %d",&i);
@@ -1050,8 +1116,18 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
sscanf(value," %d",&i);
input_info->priority = i;
} else if( !strcmp("post_type",line) && post_info ) {
- sscanf(value," %lu",&lu);
- post_info->type = lu;
+ sscanf(value," %lu",&lu);
+ post_info->type = lu;
+ } else if( !strcmp("config_key",line) ) {
+ char* cfg_key;
+
+ cfg_key = this->config->register_serialized_entry(this->config, value);
+ if (cfg_key) {
+ /* this node is a cached node */
+ _attach_entry_to_node(node, cfg_key);
+ } else {
+ lprintf("failed to deserialize config entry key\n");
+ }
}
}
}
@@ -1060,6 +1136,8 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
if( node ) {
xine_sarray_add (plugins, node);
}
+
+ free (line);
}
/**
@@ -1132,7 +1210,7 @@ static void save_catalog (xine_t *this) {
fprintf(fp, "cache_catalog_version=%d\n\n", CACHE_CATALOG_VERSION);
for (i = 0; i < PLUGIN_TYPE_MAX; i++) {
- save_plugin_list (fp, this->plugin_catalog->plugin_lists[i]);
+ save_plugin_list (this, fp, this->plugin_catalog->plugin_lists[i]);
}
fclose(fp);
}
@@ -1149,7 +1227,7 @@ static void load_cached_catalog (xine_t *this) {
/* It can't return NULL without creating directories */
if( (fp = fopen(cachefile,"r")) != NULL ) {
- load_plugin_list (fp, this->plugin_catalog->cache_list);
+ load_plugin_list (this, fp, this->plugin_catalog->cache_list);
fclose(fp);
}
free(cachefile);
@@ -1175,7 +1253,7 @@ void _x_scan_plugins (xine_t *this) {
homedir = strdup(xine_get_homedir());
this->plugin_catalog = _new_catalog();
- load_cached_catalog (this);
+ XINE_PROFILE(load_cached_catalog (this));
if ((pluginpath = getenv("XINE_PLUGIN_PATH")) != NULL) {
pluginpath = strdup(pluginpath);
@@ -1197,7 +1275,7 @@ void _x_scan_plugins (xine_t *this) {
case XINE_PATH_SEPARATOR_CHAR:
case '\0':
plugindir[j] = '\0';
- collect_plugins(this, plugindir);
+ XINE_PROFILE(collect_plugins(this, plugindir));
j = 0;
break;
case '~':
@@ -1214,9 +1292,9 @@ void _x_scan_plugins (xine_t *this) {
free(pluginpath);
free(homedir);
- save_catalog (this);
-
load_required_plugins (this);
+
+ XINE_PROFILE(save_catalog (this));
map_decoders (this);
}
@@ -2604,7 +2682,7 @@ char *xine_get_demux_for_mime_type (xine_t *self, const char *mime_type) {
}
-static void dispose_plugin_list (xine_sarray_t *list) {
+static void dispose_plugin_list (xine_sarray_t *list, int is_cache) {
plugin_node_t *node;
decoder_info_t *decoder_info;
@@ -2641,6 +2719,19 @@ static void dispose_plugin_list (xine_sarray_t *list) {
/* free info structure and string copies */
free (node->info->id);
free (node->info);
+
+ /* don't free the entry list if the node is cache */
+ if (!is_cache) {
+ if (node->config_entry_list) {
+ xine_list_iterator_t ite = xine_list_front (node->config_entry_list);
+ while (ite) {
+ char *key = xine_list_get_value (node->config_entry_list, ite);
+ free (key);
+ ite = xine_list_next (node->config_entry_list, ite);
+ }
+ xine_list_delete(node->config_entry_list);
+ }
+ }
free (node);
}
xine_sarray_delete(list);
@@ -2673,10 +2764,10 @@ void _x_dispose_plugins (xine_t *this) {
int i;
for (i = 0; i < PLUGIN_TYPE_MAX; i++) {
- dispose_plugin_list (this->plugin_catalog->plugin_lists[i]);
+ dispose_plugin_list (this->plugin_catalog->plugin_lists[i], 0);
}
- dispose_plugin_list (this->plugin_catalog->cache_list);
+ dispose_plugin_list (this->plugin_catalog->cache_list, 1);
dispose_plugin_file_list (this->plugin_catalog->file_list);
for (i = 0; this->plugin_catalog->prio_desc[i]; i++)
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index fa79ea875..c6dc8a2ce 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -52,6 +52,7 @@
#define LOG_VERBOSE
/*
#define LOG
+#define DEBUG
*/
#define XINE_ENABLE_EXPERIMENTAL_FEATURES
@@ -1699,7 +1700,7 @@ void xine_init (xine_t *this) {
/*
* plugins
*/
- _x_scan_plugins(this);
+ XINE_PROFILE(_x_scan_plugins(this));
#ifdef HAVE_SETLOCALE
if (!setlocale(LC_CTYPE, ""))
diff --git a/src/xine-utils/Makefile.am b/src/xine-utils/Makefile.am
index 30040e318..d3b4c2b1c 100644
--- a/src/xine-utils/Makefile.am
+++ b/src/xine-utils/Makefile.am
@@ -16,6 +16,7 @@ endif
endif
libxineutils_la_SOURCES = $(pppc_files) \
+ base64.c \
cpu_accel.c \
color.c \
copy.c \
diff --git a/src/input/base64.c b/src/xine-utils/base64.c
index 3f5ba2867..102f15256 100644
--- a/src/input/base64.c
+++ b/src/xine-utils/base64.c
@@ -83,12 +83,16 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <ctype.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
-#include "base64.h"
+#include <xine/base64.h>
/* NOTE: This is not true RFC822 anymore. The use of the characters
@@ -103,7 +107,7 @@
* Returns: destination as BASE64
*/
-unsigned char *rfc822_binary (void *src,unsigned long srcl,unsigned long *len)
+unsigned char *xine_rfc822_binary (void *src,unsigned long srcl,unsigned long *len)
{
unsigned char *ret,*d;
unsigned char *s = (unsigned char *) src;
@@ -129,3 +133,66 @@ unsigned char *rfc822_binary (void *src,unsigned long srcl,unsigned long *len)
return ret; /* return the resulting string */
}
+
+char *xine_base64_encode (const void *src, unsigned long srcl, unsigned long *len)
+{
+ char *ret, *d;
+ unsigned char *s = (unsigned char *) src;
+ char *v = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._";
+ unsigned long i = ((srcl + 2) / 3) * 4;
+ *len = i;
+ d = ret = (char *) malloc ((size_t) ++i);
+ for (i = 0; srcl; s += 3) { /* process tuplets */
+ *d++ = v[s[0] >> 2]; /* byte 1: high 6 bits (1) */
+ /* byte 2: low 2 bits (1), high 4 bits (2) */
+ *d++ = v[((s[0] << 4) + (--srcl ? (s[1] >> 4) : 0)) & 0x3f];
+ /* byte 3: low 4 bits (2), high 2 bits (3) */
+ *d++ = srcl ? v[((s[1] << 2) + (--srcl ? (s[2] >> 6) : 0)) & 0x3f] : '-';
+ /* byte 4: low 6 bits (3) */
+ *d++ = srcl ? v[s[2] & 0x3f] : '-';
+ if (srcl) srcl--; /* count third character if processed */
+ }
+ *d = '\0'; /* tie off string */
+
+ return ret; /* return the resulting string */
+}
+
+void *xine_base64_decode (const char *src, unsigned long srcl, unsigned long *len)
+{
+ void *ret;
+ unsigned char *d;
+ unsigned long i = ((srcl + 3) / 4) * 3;
+ *len = i;
+ d = ret = (void *) malloc ((size_t)i);
+ for (i = 0; srcl; src += 4) { /* process tuplets */
+ unsigned char tuplet[4];
+ int j;
+
+ for (j = 0; j < 4; j += 1) {
+ if (srcl) {
+ if ((src[j] >= 'A') && (src[j] <= 'Z')) {
+ tuplet[j] = src[j] - 'A';
+ } else if ((src[j] >= 'a') && (src[j] <= 'z')) {
+ tuplet[j] = src[j] - 'a' + 26;
+ } else if ((src[j] >= '0') && (src[j] <= '9')) {
+ tuplet[j] = src[j] - '0' + 52;
+ } else if (src[j] == '.') {
+ tuplet[j] = 62;
+ } else if (src[j] == '_') {
+ tuplet[j] = 63;
+ } else {
+ tuplet[j] = 64;
+ }
+ srcl--;
+ } else {
+ (*len)--;
+ }
+ }
+
+ *d++ = (tuplet[0] << 2) + ((tuplet[1] & 0x3f) >> 4);
+ *d++ = (tuplet[1] << 4) + ((tuplet[2] & 0x3f) >> 2);
+ *d++ = (tuplet[2] << 6) + (tuplet[3] & 0x3f);
+ }
+
+ return ret; /* return the resulting string */
+}