summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Salt <linux@youmustbejoking.demon.co.uk>2009-11-05 15:06:18 +0000
committerDarren Salt <linux@youmustbejoking.demon.co.uk>2009-11-05 15:06:18 +0000
commitca2c9c30b5a0f0fcab1ffb52bd065e335ffd4afe (patch)
treee43b190684d36f5ec7c4c089aec4dc42f48714f0
parentcf86264961e27b47d57981bddb98364947ba7018 (diff)
parent2af40655557ffc8197e3e59b9428168c2454a68b (diff)
downloadxine-lib-ca2c9c30b5a0f0fcab1ffb52bd065e335ffd4afe.tar.gz
xine-lib-ca2c9c30b5a0f0fcab1ffb52bd065e335ffd4afe.tar.bz2
Merge from 1.1 (with adaptations).
--HG-- rename : src/xine-engine/scratch.h => include/xine/scratch.h rename : src/xine-utils/xmllexer.h => include/xine/xmllexer.h rename : src/xine-utils/xmlparser.h => include/xine/xmlparser.h rename : src/libspucmml/xine_cmml_decoder.c => src/spu_dec/cmml_decoder.c rename : src/libspuhdmv/xine_hdmv_decoder.c => src/spu_dec/spuhdmv_decoder.c
-rw-r--r--ChangeLog3
-rw-r--r--doc/man/en/Makefile.am2
-rw-r--r--doc/man/en/xine-config.11
-rw-r--r--doc/man/en/xine-list.1.in9
-rw-r--r--doc/man/en/xine.52
-rw-r--r--include/xine/scratch.h5
-rw-r--r--include/xine/xmllexer.h25
-rw-r--r--include/xine/xmlparser.h21
-rw-r--r--src/combined/ffmpeg/ff_video_decoder.c3
-rw-r--r--src/demuxers/demux_asf.c9
-rw-r--r--src/demuxers/demux_flac.c3
-rw-r--r--src/demuxers/demux_real.c3
-rw-r--r--src/input/input_dvb.c2
-rw-r--r--src/input/libdvdnav/dvd_reader.c2
-rw-r--r--src/spu_dec/cmml_decoder.c8
-rw-r--r--src/spu_dec/spuhdmv_decoder.c324
-rw-r--r--src/xine-engine/scratch.c2
-rw-r--r--src/xine-utils/monitor.c46
-rw-r--r--src/xine-utils/xmllexer.c165
-rw-r--r--src/xine-utils/xmlparser.c53
20 files changed, 418 insertions, 270 deletions
diff --git a/ChangeLog b/ChangeLog
index 8dac0b84b..111793569 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -92,6 +92,9 @@ xine-lib (1.1.17) 2009-??-??
* Work around MOD files with reported length == 0.
* Reworked Matroska demuxer. Now reads files created by mkvmerge 2.7.0.
* Support BluRay/HDMV streams & subtitles.
+ * The XML parser & lexer code now has re-entrancy.
+ * Fixed a bug which prevented "dvb://" (no channel specified) working with
+ the default configuration.
xine-lib (1.1.16.3) 2009-04-03
* Security fixes:
diff --git a/doc/man/en/Makefile.am b/doc/man/en/Makefile.am
index 9fe87cc11..c8d616c35 100644
--- a/doc/man/en/Makefile.am
+++ b/doc/man/en/Makefile.am
@@ -10,4 +10,4 @@ DISTCLEANFILES = $(DYNAMICMANS)
EXTRA_DIST = $(STATICMANS) xine-list.1.in
xine-list-@XINE_SERIES@.1: xine-list.1.in
- (echo '.ds xl xine\-list\-@XINE_SERIES@'; cat $<) >$@
+ $(SED) -e 's/@XL@/xine\-list\-@XINE_SERIES@/' $< >$@
diff --git a/doc/man/en/xine-config.1 b/doc/man/en/xine-config.1
index 034cd405c..af56fd844 100644
--- a/doc/man/en/xine-config.1
+++ b/doc/man/en/xine-config.1
@@ -20,7 +20,6 @@ the compiler and linker flags that should be used to compile
and link programs that use \fIlibxine\fP. It can also be used to determine
the directories where \fIlibxine\fP expects plugins.
.SH OPTIONS
-.l
\fIxine\-config\fP accepts the following options, passing them on (possibly
modified) to \fIpkg\-config libxine\fP:
.TP 8
diff --git a/doc/man/en/xine-list.1.in b/doc/man/en/xine-list.1.in
index e159852c8..558b44df0 100644
--- a/doc/man/en/xine-list.1.in
+++ b/doc/man/en/xine-list.1.in
@@ -1,18 +1,17 @@
.TH XINE 1 2001-08-28 "The xine project"
.SH NAME
-\*(xl - get supported filetype information from xine-lib
+@XL@ - get supported filetype information from xine-lib
.SH SYNOPSIS
-.B \*(xl
+.B @XL@
[\fPoptions...\fI]
.SH DESCRIPTION
.PP
-\fI\*(xl\fP is a tool that is used to list the MIME type and filename
+\fI@XL@\fP is a tool that is used to list the MIME type and filename
extension information known and supported by the installed \fIxine-lib\fP.
It is of use in filling in MIME information in front ends' desktop files.
.
.SH OPTIONS
-.l
-\fIxine\-list\fP accepts the following options:
+\fI@XL@\fP accepts the following options:
.TP 8
.B \-m
.B \-\-mime\-types
diff --git a/doc/man/en/xine.5 b/doc/man/en/xine.5
index a278e9acf..ab5c2833b 100644
--- a/doc/man/en/xine.5
+++ b/doc/man/en/xine.5
@@ -98,7 +98,7 @@ above are available with stock libxine.
provided\fP - from a shell, you can normally use \fB"$PWD/file"\fP or
\fB"$(pwd)/file"\fP or \fB"\`pwd\`/file"\fP if the file is in the current
directory. (Which one depends on your shell; all three work in bash. Also,
-certain characters need to be encoded.)
+normal URL encoding rules apply; `%', in particular, must be encoded as `%25'.)
As of xine-lib 1.1.3, the DVD title number may be 0 (select navigation) and
the chapter number may be 0 (full title).
diff --git a/include/xine/scratch.h b/include/xine/scratch.h
index 1029276e3..c45af198f 100644
--- a/include/xine/scratch.h
+++ b/include/xine/scratch.h
@@ -32,10 +32,7 @@ typedef struct scratch_buffer_s scratch_buffer_t;
struct scratch_buffer_s {
- void
-#if __GNUC__ >= 3
- __attribute__((__format__(__printf__, 2, 0)))
-#endif
+ void XINE_FORMAT_PRINTF(2, 0)
(*scratch_printf) (scratch_buffer_t *this, const char *format, va_list ap);
char **(*get_content) (scratch_buffer_t *this);
diff --git a/include/xine/xmllexer.h b/include/xine/xmllexer.h
index e93cb69ff..70fa86ee0 100644
--- a/include/xine/xmllexer.h
+++ b/include/xine/xmllexer.h
@@ -23,6 +23,10 @@
#ifndef XML_LEXER_H
#define XML_LEXER_H
+#ifndef XINE_DEPRECATED
+#define XINE_DEPRECATED
+#endif
+
#ifndef XINE_PROTECTED
#define XINE_PROTECTED
#endif
@@ -51,10 +55,25 @@
#define T_CDATA_STOP 19 /* ]]> */
+/* public structure */
+struct lexer
+{
+ const char * lexbuf;
+ int lexbuf_size;
+ int lexbuf_pos;
+ int lex_mode;
+ int in_comment;
+ char *lex_malloc;
+};
+
+
/* public functions */
-void lexer_init(const char * buf, int size) XINE_PROTECTED;
-int lexer_get_token_d(char ** tok, int * tok_size, int fixed) XINE_PROTECTED;
-int lexer_get_token(char * tok, int tok_size) XINE_PROTECTED;
+void lexer_init(const char * buf, int size) XINE_DEPRECATED XINE_PROTECTED;
+struct lexer *lexer_init_r(const char * buf, int size) XINE_PROTECTED;
+void lexer_finalize_r(struct lexer * lexer) XINE_PROTECTED;
+int lexer_get_token_d_r(struct lexer * lexer, char ** tok, int * tok_size, int fixed) XINE_PROTECTED;
+int lexer_get_token_d(char ** tok, int * tok_size, int fixed) XINE_DEPRECATED XINE_PROTECTED;
+int lexer_get_token(char * tok, int tok_size) XINE_DEPRECATED XINE_PROTECTED;
char *lexer_decode_entities (const char *tok) XINE_PROTECTED;
#endif
diff --git a/include/xine/xmlparser.h b/include/xine/xmlparser.h
index c89cb6dd3..8fed3199c 100644
--- a/include/xine/xmlparser.h
+++ b/include/xine/xmlparser.h
@@ -22,6 +22,10 @@
#ifndef XML_PARSER_H
#define XML_PARSER_H
+#ifndef XINE_DEPRECATED
+#define XINE_DEPRECATED
+#endif
+
#ifndef XINE_PROTECTED
#define XINE_PROTECTED
#endif
@@ -65,10 +69,21 @@ typedef struct xml_node_s {
struct xml_node_s *next;
} xml_node_t;
-void xml_parser_init(const char * buf, int size, int mode) XINE_PROTECTED;
+/* xml parser */
+typedef struct xml_parser_s {
+ struct lexer *lexer;
+ int mode;
+} xml_parser_t;
+
+void xml_parser_init(const char * buf, int size, int mode) XINE_DEPRECATED XINE_PROTECTED;
+xml_parser_t *xml_parser_init_r(const char * buf, int size, int mode) XINE_PROTECTED;
+void xml_parser_finalize_r(xml_parser_t *xml_parser) XINE_PROTECTED;
+
+int xml_parser_build_tree(xml_node_t **root_node) XINE_DEPRECATED XINE_PROTECTED;
+int xml_parser_build_tree_r(xml_parser_t *xml_parser, xml_node_t **root_node) XINE_PROTECTED;
-int xml_parser_build_tree(xml_node_t **root_node) XINE_PROTECTED;
-int xml_parser_build_tree_with_options(xml_node_t **root_node, int flags) XINE_PROTECTED;
+int xml_parser_build_tree_with_options(xml_node_t **root_node, int flags) XINE_DEPRECATED XINE_PROTECTED;
+int xml_parser_build_tree_with_options_r(xml_parser_t *xml_parser, xml_node_t **root_node, int flags) XINE_PROTECTED;
void xml_parser_free_tree(xml_node_t *root_node) XINE_PROTECTED;
diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c
index f412274a0..c69433fbf 100644
--- a/src/combined/ffmpeg/ff_video_decoder.c
+++ b/src/combined/ffmpeg/ff_video_decoder.c
@@ -1180,7 +1180,8 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
if (this->size == 0) {
/* take over pts when we are about to buffer a frame */
this->av_frame->reordered_opaque = ff_tag_pts(this, this->pts);
- this->context->reordered_opaque = ff_tag_pts(this, this->pts);
+ if (this->context) /* shouldn't be NULL */
+ this->context->reordered_opaque = ff_tag_pts(this, this->pts);
this->pts = 0;
}
diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c
index 9d0447ce5..757e7ffd8 100644
--- a/src/demuxers/demux_asf.c
+++ b/src/demuxers/demux_asf.c
@@ -1540,6 +1540,7 @@ static int demux_asf_parse_asx_references( demux_asf_t *this) {
int buf_used = 0;
int len;
xml_node_t *xml_tree, *asx_entry, *asx_ref;
+ xml_parser_t *xml_parser;
int result;
@@ -1562,9 +1563,13 @@ static int demux_asf_parse_asx_references( demux_asf_t *this) {
if(buf_used)
buf[buf_used] = '\0';
- xml_parser_init(buf, buf_used, XML_PARSER_CASE_INSENSITIVE);
- if((result = xml_parser_build_tree(&xml_tree)) != XML_PARSER_OK)
+ xml_parser = xml_parser_init_r(buf, buf_used, XML_PARSER_CASE_INSENSITIVE);
+ if((result = xml_parser_build_tree_r(xml_parser, &xml_tree)) != XML_PARSER_OK) {
+ xml_parser_finalize_r(xml_parser);
goto failure;
+ }
+
+ xml_parser_finalize_r(xml_parser);
if(!strcasecmp(xml_tree->name, "ASX")) {
/* Attributes: VERSION, PREVIEWMODE, BANNERBAR
diff --git a/src/demuxers/demux_flac.c b/src/demuxers/demux_flac.c
index 9a01c9adf..8acddb3c6 100644
--- a/src/demuxers/demux_flac.c
+++ b/src/demuxers/demux_flac.c
@@ -33,6 +33,9 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
#define LOG_MODULE "demux_flac"
#define LOG_VERBOSE
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c
index d416ebeca..eecaef915 100644
--- a/src/demuxers/demux_real.c
+++ b/src/demuxers/demux_real.c
@@ -42,6 +42,9 @@
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
#define LOG_MODULE "demux_real"
#define LOG_VERBOSE
diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c
index 065a57b47..164ac2bc9 100644
--- a/src/input/input_dvb.c
+++ b/src/input/input_dvb.c
@@ -2863,6 +2863,8 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
if (lastchannel.num_value) {
if (xine_config_lookup_entry(this->class->xine, "media.dvb.last_channel", &lastchannel)){
this->channel = lastchannel.num_value -1;
+ if (this->channel < 0 || this->channel >= num_channels)
+ this->channel = 0; /* out of range? default */
}else{
xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("input_dvb: invalid channel specification, defaulting to channel 0\n"));
this->channel = 0;
diff --git a/src/input/libdvdnav/dvd_reader.c b/src/input/libdvdnav/dvd_reader.c
index 4144b9133..e8e035b10 100644
--- a/src/input/libdvdnav/dvd_reader.c
+++ b/src/input/libdvdnav/dvd_reader.c
@@ -30,7 +30,9 @@
#include <string.h>
#include <unistd.h>
#include <limits.h>
+#ifdef HAVE_DIRENT_H
#include <dirent.h>
+#endif
#ifndef HAVE_GETTIMEOFDAY
# ifdef WIN32
diff --git a/src/spu_dec/cmml_decoder.c b/src/spu_dec/cmml_decoder.c
index 7f800cf20..02ef18540 100644
--- a/src/spu_dec/cmml_decoder.c
+++ b/src/spu_dec/cmml_decoder.c
@@ -239,6 +239,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
spucmml_decoder_t *this = (spucmml_decoder_t *) this_gen;
+ xml_parser_t *xml_parser;
xml_node_t *packet_xml_root;
char * anchor_text = NULL;
@@ -248,12 +249,15 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
/* parse the CMML */
- xml_parser_init (str, strlen (str), XML_PARSER_CASE_INSENSITIVE);
- if (xml_parser_build_tree(&packet_xml_root) != XML_PARSER_OK) {
+ xml_parser = xml_parser_init_r (str, strlen (str), XML_PARSER_CASE_INSENSITIVE);
+ if (xml_parser_build_tree_r(xml_parser, &packet_xml_root) != XML_PARSER_OK) {
lprintf ("warning: invalid XML packet detected in CMML track\n");
+ xml_parser_finalize_r(xml_parser);
return;
}
+ xml_parser_finalize_r(xml_parser);
+
if (strcasecmp(packet_xml_root->name, "head") == 0) {
/* found a <head>...</head> packet: need to parse the title */
diff --git a/src/spu_dec/spuhdmv_decoder.c b/src/spu_dec/spuhdmv_decoder.c
index f23d34c50..bcd52ee3f 100644
--- a/src/spu_dec/spuhdmv_decoder.c
+++ b/src/spu_dec/spuhdmv_decoder.c
@@ -39,7 +39,7 @@
#define TRACE(x...) printf(x)
/*#define TRACE(x...) */
-#define ERROR(x...) fprintf(stderr, x)
+#define ERROR(x...) fprintf(stderr, "spuhdmv: " x)
/*#define ERROR(x...) lprintf(x) */
/*
@@ -51,6 +51,8 @@ struct subtitle_clut_s {
uint32_t color[256];
uint8_t trans[256];
subtitle_clut_t *next;
+
+ int shown;
};
/*
@@ -66,11 +68,15 @@ struct subtitle_object_s {
uint num_rle;
size_t data_size;
+#if 0
uint8_t *raw_data; /* partial RLE data in HDMV format */
size_t raw_data_len;
size_t raw_data_size;
+#endif
subtitle_object_t *next;
+
+ int shown;
};
/*
@@ -83,6 +89,8 @@ struct window_def_s {
uint16_t width, height;
window_def_t *next;
+
+ int shown;
};
@@ -102,9 +110,79 @@ struct composition_object_s {
uint16_t crop_width, crop_height;
composition_object_t *next;
+
+ int shown;
+};
+
+typedef struct composition_descriptor_s composition_descriptor_t;
+struct composition_descriptor_s {
+ uint16_t number;
+ uint8_t state;
+};
+
+typedef struct presentation_segment_s presentation_segment_t;
+struct presentation_segment_s {
+ composition_descriptor_t comp_descr;
+
+ uint8_t palette_update_flag;
+ uint8_t palette_id_ref;
+ uint8_t object_number;
+
+ composition_object_t *comp_objs;
+
+ presentation_segment_t *next;
+
+ int64_t pts;
+ int shown;
};
/*
+ * list handling
+ */
+
+#define LIST_REPLACE(list, obj, FREE_FUNC) \
+ do { \
+ uint id = obj->id; \
+ \
+ /* insert to list */ \
+ obj->next = list; \
+ list = obj; \
+ \
+ /* remove old */ \
+ while (obj->next && obj->next->id != id) \
+ obj = obj->next; \
+ if (obj->next) { \
+ void *tmp = (void*)obj->next; \
+ obj->next = obj->next->next; \
+ FREE_FUNC(tmp); \
+ } \
+ } while (0);
+
+#define LIST_DESTROY(list, FREE_FUNC) \
+ while (list) { \
+ void *tmp = (void*)list; \
+ list = list->next; \
+ FREE_FUNC(tmp); \
+ }
+
+static void free_subtitle_object(void *ptr)
+{
+ if (ptr) {
+ free(((subtitle_object_t*)ptr)->rle);
+ free(ptr);
+ }
+}
+static void free_presentation_segment(void *ptr)
+{
+ if (ptr) {
+ presentation_segment_t *seg = (presentation_segment_t*)ptr;
+ LIST_DESTROY(seg->comp_objs, free);
+ free(ptr);
+ }
+}
+
+
+/*
* segment_buffer_t
*
* assemble and decode segments
@@ -389,14 +467,14 @@ static subtitle_object_t *segbuf_decode_object(segment_buffer_t *buf)
segbuf_decode_rle (buf, obj);
if (buf->error) {
- free(obj);
+ free_subtitle_object(obj);
return NULL;
}
} else {
ERROR(" TODO: APPEND RLE, length %d bytes\n", buf->segment_len - 4);
/* TODO */
- free(obj);
+ free_subtitle_object(obj);
return NULL;
}
@@ -435,12 +513,6 @@ static int segbuf_decode_video_descriptor(segment_buffer_t *buf)
return buf->error;
}
-typedef struct composition_descriptor_s composition_descriptor_t;
-struct composition_descriptor_s {
- uint16_t number;
- uint8_t state;
-};
-
static int segbuf_decode_composition_descriptor(segment_buffer_t *buf, composition_descriptor_t *descr)
{
descr->number = segbuf_get_u16(buf);
@@ -482,9 +554,38 @@ static composition_object_t *segbuf_decode_composition_object(segment_buffer_t *
return cobj;
}
+static presentation_segment_t *segbuf_decode_presentation_segment(segment_buffer_t *buf)
+{
+ presentation_segment_t *seg = calloc(1, sizeof(presentation_segment_t));
+ int index;
+
+ segbuf_decode_video_descriptor (buf);
+ segbuf_decode_composition_descriptor (buf, &seg->comp_descr);
+
+ seg->palette_update_flag = !!((segbuf_get_u8(buf)) & 0x80);
+ seg->palette_id_ref = segbuf_get_u8 (buf);
+ seg->object_number = segbuf_get_u8 (buf);
+
+ TRACE(" presentation_segment: object_number %d, palette %d\n",
+ seg->object_number, seg->palette_id_ref);
+
+ for (index = 0; index < seg->object_number; index++) {
+ composition_object_t *cobj = segbuf_decode_composition_object (buf);
+ cobj->next = seg->comp_objs;
+ seg->comp_objs = cobj;
+ }
+
+ if (buf->error) {
+ free_presentation_segment(seg);
+ return NULL;
+ }
+
+ return seg;
+}
+
static rle_elem_t *copy_crop_rle(subtitle_object_t *obj, composition_object_t *cobj)
{
- /* TODO: exec cropping here (w,h sized image from pos x,y) */
+ /* TODO: cropping (w,h sized image from pos x,y) */
rle_elem_t *rle = calloc (obj->num_rle, sizeof(rle_elem_t));
memcpy (rle, obj->rle, obj->num_rle * sizeof(rle_elem_t));
@@ -508,57 +609,17 @@ typedef struct spuhdmv_decoder_s {
segment_buffer_t *buf;
- subtitle_clut_t *cluts;
- subtitle_object_t *objects;
- window_def_t *windows;
+ subtitle_clut_t *cluts;
+ subtitle_object_t *objects;
+ window_def_t *windows;
+ presentation_segment_t *segments;
+
int overlay_handles[MAX_OBJECTS];
int64_t pts;
} spuhdmv_decoder_t;
-#define LIST_REPLACE_OLD(type, list, obj) \
- do { \
- /* insert to list */ \
- obj->next = list; \
- list = obj; \
-\
- /* remove old */ \
- type *i = list; \
- while (i->next && i->next->id != obj->id) \
- i = i->next; \
- if (i->next) { \
- void *tmp = (void*)i->next; \
- i->next = i->next->next; \
- free(tmp); \
- } \
- } while (0);
-
-#define LIST_REPLACE(list, obj) \
- do { \
- uint id = obj->id; \
- \
- /* insert to list */ \
- obj->next = list; \
- list = obj; \
- \
- /* remove old */ \
- while (obj->next && obj->next->id != id) \
- obj = obj->next; \
- if (obj->next) { \
- void *tmp = (void*)obj->next; \
- obj->next = obj->next->next; \
- free(tmp); \
- } \
- } while (0);
-
-#define LIST_DESTROY(list) \
- while (list) { \
- void *tmp = (void*)list; \
- list = list->next; \
- free (tmp); \
- }
-
static int decode_palette(spuhdmv_decoder_t *this)
{
/* decode */
@@ -566,7 +627,7 @@ static int decode_palette(spuhdmv_decoder_t *this)
if (!clut)
return 1;
- LIST_REPLACE (this->cluts, clut);
+ LIST_REPLACE (this->cluts, clut, free);
return 0;
}
@@ -578,7 +639,7 @@ static int decode_object(spuhdmv_decoder_t *this)
if (!obj)
return 1;
- LIST_REPLACE (this->objects, obj);
+ LIST_REPLACE (this->objects, obj, free_subtitle_object);
return 0;
}
@@ -590,13 +651,30 @@ static int decode_window_definition(spuhdmv_decoder_t *this)
if (!wnd)
return 1;
- LIST_REPLACE (this->windows, wnd);
+ LIST_REPLACE (this->windows, wnd, free);
+
+ return 0;
+}
+
+static int decode_presentation_segment(spuhdmv_decoder_t *this)
+{
+ /* decode */
+ presentation_segment_t *seg = segbuf_decode_presentation_segment(this->buf);
+ if (!seg)
+ return 1;
+
+ seg->pts = this->pts;
+
+ /* replace */
+ if (this->segments)
+ LIST_DESTROY(this->segments, free_presentation_segment);
+ this->segments = seg;
return 0;
}
static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uint palette_id_ref,
- int overlay_index, int64_t pts)
+ int overlay_index, int64_t pts, int force_update)
{
video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out);
metronom_t *metronom = this->stream->metronom;
@@ -608,21 +686,16 @@ static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uin
while (clut && clut->id != palette_id_ref)
clut = clut->next;
if (!clut) {
- ERROR(" fill_overlay: clut %d not found !\n", palette_id_ref);
+ TRACE(" show_overlay: clut %d not found !\n", palette_id_ref);
return -1;
}
- /* copy palette to xine overlay */
- overlay.rgb_clut = 0;
- memcpy(overlay.color, clut->color, sizeof(uint32_t) * 256);
- memcpy(overlay.trans, clut->trans, sizeof(uint8_t) * 256);
-
/* find RLE image */
subtitle_object_t *obj = this->objects;
while (obj && obj->id != cobj->object_id_ref)
obj = obj->next;
if (!obj) {
- ERROR(" fill_overlay: object %d not found !\n", cobj->object_id_ref);
+ TRACE(" show_overlay: object %d not found !\n", cobj->object_id_ref);
return -1;
}
@@ -631,10 +704,20 @@ static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uin
while (wnd && wnd->id != cobj->window_id_ref)
wnd = wnd->next;
if (!wnd) {
- ERROR(" fill_overlay: window %d not found !\n", cobj->window_id_ref);
+ TRACE(" show_overlay: window %d not found !\n", cobj->window_id_ref);
return -1;
}
+ /* do not show again if all elements are unchanged */
+ if (!force_update && clut->shown && obj->shown && wnd->shown && cobj->shown)
+ return 0;
+ clut->shown = obj->shown = wnd->shown = cobj->shown = 1;
+
+ /* copy palette to xine overlay */
+ overlay.rgb_clut = 0;
+ memcpy(overlay.color, clut->color, sizeof(uint32_t) * 256);
+ memcpy(overlay.trans, clut->trans, sizeof(uint8_t) * 256);
+
/* copy and crop RLE image to xine overlay */
overlay.width = obj->width;
overlay.height = obj->height;
@@ -680,41 +763,9 @@ static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uin
ovl_manager->add_event (ovl_manager, (void *)&event);
- obj->rle = NULL;
-
return 0;
}
-typedef struct presentation_segment_s presentation_segment_t;
-struct presentation_segment_s {
- composition_descriptor_t comp_descr;
-
- uint8_t palette_update_flag;
- uint8_t palette_id_ref;
- uint8_t object_number;
-
- composition_object_t *comp_objs;
-
- presentation_segment_t *next;
-
- int64_t pts;
-};
-
-static void show_overlays(spuhdmv_decoder_t *this, presentation_segment_t *pseg)
-{
- composition_object_t *cobj = pseg->comp_objs;
- int i;
-
- for (i = 0; i < pseg->object_number; i++) {
- if (!cobj) {
- ERROR("show_overlays: composition object %d missing !\n", i);
- } else {
- show_overlay(this, cobj, pseg->palette_id_ref, i, pseg->pts);
- cobj = cobj->next;
- }
- }
-}
-
static void hide_overlays(spuhdmv_decoder_t *this, int64_t pts)
{
video_overlay_event_t event = {0};
@@ -740,38 +791,46 @@ static void hide_overlays(spuhdmv_decoder_t *this, int64_t pts)
}
}
-static int decode_presentation_segment(spuhdmv_decoder_t *this)
+static void update_overlays(spuhdmv_decoder_t *this)
{
- presentation_segment_t p = {};
- segment_buffer_t *buf = this->buf;
- int index;
+ presentation_segment_t *pseg = this->segments;
- segbuf_decode_video_descriptor (this->buf);
- segbuf_decode_composition_descriptor (this->buf, &p.comp_descr);
+ while (pseg) {
- p.palette_update_flag = !!((segbuf_get_u8(buf)) & 0x80);
- p.palette_id_ref = segbuf_get_u8 (buf);
- p.object_number = segbuf_get_u8 (buf);
+ if (!pseg->comp_descr.state) {
- TRACE(" presentation_segment: object_number %d, palette %d\n",
- p.object_number, p.palette_id_ref);
+ /* HIDE */
+ if (!pseg->shown)
+ hide_overlays (this, pseg->pts);
- p.pts = this->pts; /* !! todo - use it ? */
+ } else {
- for (index = 0; index < p.object_number; index++) {
- composition_object_t *cobj = segbuf_decode_composition_object (this->buf);
- cobj->next = p.comp_objs;
- p.comp_objs = cobj;
- }
+ /* SHOW */
+ composition_object_t *cobj = pseg->comp_objs;
+ int i;
+
+ for (i = 0; i < pseg->object_number; i++) {
+ if (!cobj) {
+ ERROR("show_overlays: composition object %d missing !\n", i);
+ } else {
+ show_overlay(this, cobj, pseg->palette_id_ref, i, pseg->pts, !pseg->shown);
+ cobj = cobj->next;
+ }
+ }
+ }
- if (!p.comp_descr.state) {
- hide_overlays (this, this->pts);
- } else {
- show_overlays (this, &p);
- LIST_DESTROY (p.comp_objs);
+ pseg->shown = 1;
+
+ pseg = pseg->next;
}
+}
- return buf->error;
+static void free_objs(spuhdmv_decoder_t *this)
+{
+ LIST_DESTROY (this->cluts, free);
+ LIST_DESTROY (this->objects, free_subtitle_object);
+ LIST_DESTROY (this->windows, free);
+ LIST_DESTROY (this->segments, free_presentation_segment);
}
static void decode_segment(spuhdmv_decoder_t *this)
@@ -801,13 +860,8 @@ static void decode_segment(spuhdmv_decoder_t *this)
break;
case 0x80:
TRACE(" segment: END OF DISPLAY\n");
- {
- int64_t pts = xine_get_current_vpts(this->stream) -
- this->stream->metronom->get_option(this->stream->metronom,
- METRONOM_VPTS_OFFSET);
- TRACE(" * current pts = %ld\n", pts);
- }
-
+ /* drop all cached objects */
+ free_objs(this);
break;
default:
ERROR(" segment type 0x%x unknown, skipping\n", this->buf->segment_type);
@@ -816,11 +870,13 @@ static void decode_segment(spuhdmv_decoder_t *this)
if (this->buf->error) {
ERROR("*** DECODE ERROR ***\n");
}
+
+ update_overlays (this);
}
static void close_osd(spuhdmv_decoder_t *this)
{
- video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out);
+ video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out);
int i = 0;
while (this->overlay_handles[i] >= 0) {
@@ -865,9 +921,7 @@ static void spudec_reset (spu_decoder_t * this_gen)
if (this->buf)
segbuf_reset(this->buf);
- LIST_DESTROY (this->cluts);
- LIST_DESTROY (this->objects);
- LIST_DESTROY (this->windows);
+ free_objs(this);
close_osd(this);
}
@@ -886,9 +940,7 @@ static void spudec_dispose (spu_decoder_t *this_gen)
close_osd (this);
segbuf_dispose (this->buf);
- LIST_DESTROY (this->cluts);
- LIST_DESTROY (this->objects);
- LIST_DESTROY (this->windows);
+ free_objs(this);
free (this);
}
diff --git a/src/xine-engine/scratch.c b/src/xine-engine/scratch.c
index f01ea9c7d..02c415e96 100644
--- a/src/xine-engine/scratch.c
+++ b/src/xine-engine/scratch.c
@@ -36,7 +36,7 @@
#include <xine/xineutils.h>
#include <xine/scratch.h>
-static void __attribute__((__format__(__printf__, 2, 0)))
+static void XINE_FORMAT_PRINTF(2, 0)
scratch_printf (scratch_buffer_t *this, const char *format, va_list argp)
{
time_t t;
diff --git a/src/xine-utils/monitor.c b/src/xine-utils/monitor.c
index 59d8a63d2..906cd9278 100644
--- a/src/xine-utils/monitor.c
+++ b/src/xine-utils/monitor.c
@@ -32,41 +32,42 @@
#ifndef NDEBUG
-static long long int profiler_times[MAX_ID] ;
-static long long int profiler_start[MAX_ID] ;
-static long profiler_calls[MAX_ID] ;
-static const char *profiler_label[MAX_ID] ;
+typedef struct {
+ uint64_t p_times;
+ uint64_t p_start;
+ long p_calls;
+ const char *p_label;
+} xine_profiler_t;
+
+static xine_profiler_t profiler[MAX_ID];
void xine_profiler_init () {
- memset(profiler_times, 0, sizeof(profiler_times));
- memset(profiler_start, 0, sizeof(profiler_start));
- memset(profiler_calls, 0, sizeof(profiler_calls));
- memset(profiler_label, 0, sizeof(profiler_label));
+ memset(profiler, 0, sizeof(profiler));
}
int xine_profiler_allocate_slot (const char *label) {
int id;
- for (id = 0; id < MAX_ID && profiler_label[id] != NULL; id++)
+ for (id = 0; id < MAX_ID && profiler[id].p_label != NULL; id++)
;
if (id >= MAX_ID)
return -1;
- profiler_label[id] = label;
+ profiler[id].p_label = label;
return id;
}
#if defined(ARCH_X86_32)
-static __inline__ unsigned long long int rdtsc(void)
+static __inline__ uint64_t rdtsc(void)
{
unsigned long long int x;
__asm__ volatile ("rdtsc\n\t" : "=A" (x));
return x;
}
#elif defined(ARCH_X86_64)
-static __inline__ unsigned long long int rdtsc(void)
+static __inline__ uint64_t rdtsc(void)
{
unsigned long long int a, d;
__asm__ volatile ("rdtsc\n\t" : "=a" (a), "=d" (d));
@@ -78,7 +79,7 @@ void xine_profiler_start_count (int id) {
if ( id >= MAX_ID || id < 0 ) return;
#if defined(ARCH_X86) || defined(ARCH_X86_64)
- profiler_start[id] = rdtsc();
+ profiler[id].p_start = rdtsc();
#endif
}
@@ -86,18 +87,19 @@ void xine_profiler_stop_count (int id) {
if ( id >= MAX_ID || id < 0 ) return;
#if defined(ARCH_X86) || defined(ARCH_X86_64)
- profiler_times[id] += rdtsc() - profiler_start[id];
+ profiler[id].p_times += rdtsc() - profiler[id].p_start;
#endif
- profiler_calls[id]++;
+ profiler[id].p_calls++;
}
void xine_profiler_print_results (void) {
int i;
#if defined(ARCH_X86) || defined(ARCH_X86_64)
- static long long int cpu_speed; /* cpu cyles/usec */
+ static uint64_t cpu_speed; /* cpu cyles/usec */
+
if (!cpu_speed) {
- long long int tsc_start, tsc_end;
+ uint64_t tsc_start, tsc_end;
struct timeval tv_start, tv_end;
tsc_start = rdtsc();
@@ -119,13 +121,13 @@ void xine_profiler_print_results (void) {
"----------------------------------------------------------------------------\n",
"ID", "name", "cpu cycles", "calls", "cycles/call", "usec/call");
for (i=0; i<MAX_ID; i++) {
- if (profiler_label[i]) {
+ if (profiler[i].p_label) {
printf ("%2d: %-24.24s %12lld %9ld",
- i, profiler_label[i], profiler_times[i], profiler_calls[i]);
- if (profiler_calls[i]) {
- printf(" %12lld", profiler_times[i] / profiler_calls[i]);
+ i, profiler[i].p_label, profiler[i].p_times, profiler[i].p_calls);
+ if (profiler[i].p_calls) {
+ printf(" %12lld", profiler[i].p_times / profiler[i].p_calls);
#if defined(ARCH_X86) || defined(ARCH_X86_64)
- printf(" %9lld", profiler_times[i] / (cpu_speed * profiler_calls[i]));
+ printf(" %9lld", profiler[i].p_times / (cpu_speed * profiler[i].p_calls));
#endif
}
printf ("\n");
diff --git a/src/xine-utils/xmllexer.c b/src/xine-utils/xmllexer.c
index a535b7aca..c37510903 100644
--- a/src/xine-utils/xmllexer.c
+++ b/src/xine-utils/xmllexer.c
@@ -48,15 +48,11 @@
/* private constants*/
/* private global variables */
-static const char * lexbuf;
-static int lexbuf_size = 0;
-static int lexbuf_pos = 0;
-static int in_comment = 0;
-static char *lex_malloc = NULL;
+struct lexer * static_lexer;
enum utf { UTF32BE, UTF32LE, UTF16BE, UTF16LE };
-static void lex_convert (const char * buf, int size, enum utf utf)
+static void lex_convert (struct lexer * lexer, const char * buf, int size, enum utf utf)
{
char *utf8 = malloc (size * (utf >= UTF16BE ? 3 : 6) + 1);
char *bp = utf8;
@@ -88,8 +84,16 @@ static void lex_convert (const char * buf, int size, enum utf utf)
}
}
*bp = 0;
- lexbuf_size = bp - utf8;
- lexbuf = lex_malloc = realloc (utf8, lexbuf_size + 1);
+ lexer->lexbuf_size = bp - utf8;
+ lexer->lexbuf = lexer->lex_malloc = realloc (utf8, lexer->lexbuf_size + 1);
+}
+
+/* for ABI compatibility */
+void lexer_init(const char * buf, int size) {
+ if (static_lexer) {
+ lexer_finalize_r(static_lexer);
+ }
+ static_lexer = lexer_init_r(buf, size);
}
static enum {
@@ -98,35 +102,40 @@ static enum {
CDATA,
} lex_mode = NORMAL;
-void lexer_init(const char * buf, int size) {
+struct lexer *lexer_init_r(const char * buf, int size) {
static const char boms[] = { 0xFF, 0xFE, 0, 0, 0xFE, 0xFF },
bom_utf8[] = { 0xEF, 0xBB, 0xBF };
+ struct lexer * lexer = calloc (1, sizeof (*lexer));
- free (lex_malloc);
- lex_malloc = NULL;
-
- lexbuf = buf;
- lexbuf_size = size;
+ lexer->lexbuf = buf;
+ lexer->lexbuf_size = size;
if (size >= 4 && !memcmp (buf, boms + 2, 4))
- lex_convert (buf + 4, size - 4, UTF32BE);
+ lex_convert (lexer, buf + 4, size - 4, UTF32BE);
else if (size >= 4 && !memcmp (buf, boms, 4))
- lex_convert (buf + 4, size - 4, UTF32LE);
+ lex_convert (lexer, buf + 4, size - 4, UTF32LE);
else if (size >= 3 && !memcmp (buf, bom_utf8, 3))
{
- lexbuf += 3;
- lexbuf_size -= 3;
+ lexer->lexbuf += 3;
+ lexer->lexbuf_size -= 3;
}
else if (size >= 2 && !memcmp (buf, boms + 4, 2))
- lex_convert (buf + 2, size - 2, UTF16BE);
+ lex_convert (lexer, buf + 2, size - 2, UTF16BE);
else if (size >= 2 && !memcmp (buf, boms, 2))
- lex_convert (buf + 2, size - 2, UTF16LE);
+ lex_convert (lexer, buf + 2, size - 2, UTF16LE);
- lexbuf_pos = 0;
- lex_mode = NORMAL;
- in_comment = 0;
+ lexer->lexbuf_pos = 0;
+ lexer->lex_mode = NORMAL;
+ lexer->in_comment = 0;
lprintf("buffer length %d\n", size);
+ return lexer;
+}
+
+void lexer_finalize_r(struct lexer * lexer)
+{
+ free(lexer->lex_malloc);
+ free(lexer);
}
typedef enum {
@@ -147,19 +156,25 @@ typedef enum {
STATE_IDENT /* must be last */
} lexer_state_t;
+/* for ABI compatibility */
int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
+ return lexer_get_token_d_r(static_lexer, _tok, _tok_size, fixed);
+}
+
+int lexer_get_token_d_r(struct lexer * lexer, char ** _tok, int * _tok_size, int fixed) {
char *tok = *_tok;
int tok_size = *_tok_size;
+
int tok_pos = 0;
lexer_state_t state = STATE_IDLE;
char c;
if (tok) {
- while ((tok_pos < tok_size) && (lexbuf_pos < lexbuf_size)) {
- c = lexbuf[lexbuf_pos];
- lprintf("c=%c, state=%d, lex_mode=%d, in_comment=%d\n", c, state, lex_mode, in_comment);
+ while ((tok_pos < tok_size) && (lexer->lexbuf_pos < lexer->lexbuf_size)) {
+ c = lexer->lexbuf[lexer->lexbuf_pos];
+ lprintf("c=%c, state=%d, in_comment=%d\n", c, state, lexer->in_comment);
- switch (lex_mode) {
+ switch (lexer->lex_mode) {
case NORMAL:
switch (state) {
/* init state */
@@ -192,7 +207,7 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
break;
case '/':
- if (!in_comment)
+ if (!lexer->in_comment)
state = STATE_T_M_STOP_2;
tok[tok_pos] = c;
tok_pos++;
@@ -219,7 +234,7 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
break;
case '?':
- if (!in_comment)
+ if (!lexer->in_comment)
state = STATE_T_TI_STOP;
tok[tok_pos] = c;
tok_pos++;
@@ -231,14 +246,14 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
tok_pos++;
break;
}
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
break;
/* end of line */
case STATE_EOL:
if (c == '\n' || (c == '\r')) {
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++;
} else {
tok[tok_pos] = '\0';
@@ -250,7 +265,7 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case STATE_SEPAR:
if (c == ' ' || (c == '\t')) {
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++;
} else {
tok[tok_pos] = '\0';
@@ -263,20 +278,20 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
switch (c) {
case '/':
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++; /* FIXME */
tok[tok_pos] = '\0';
return T_M_START_2;
break;
case '!':
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++;
state = STATE_T_COMMENT;
break;
case '?':
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++; /* FIXME */
tok[tok_pos] = '\0';
return T_TI_START;
@@ -290,8 +305,8 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
/* T_M_STOP_1 */
case STATE_T_M_STOP_1:
tok[tok_pos] = '\0';
- if (!in_comment)
- lex_mode = DATA;
+ if (!lexer->in_comment)
+ lexer->lex_mode = DATA;
return T_M_STOP_1;
break;
@@ -299,11 +314,11 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case STATE_T_M_STOP_2:
if (c == '>') {
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++; /* FIXME */
tok[tok_pos] = '\0';
- if (!in_comment)
- lex_mode = DATA;
+ if (!lexer->in_comment)
+ lexer->lex_mode = DATA;
return T_M_STOP_2;
} else {
tok[tok_pos] = '\0';
@@ -320,7 +335,7 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
/* T_STRING */
case STATE_T_STRING_DOUBLE:
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
if (c == '\"') { /* " */
tok[tok_pos] = '\0'; /* FIXME */
return T_STRING;
@@ -332,33 +347,33 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case STATE_T_COMMENT:
switch (c) {
case '-':
- lexbuf_pos++;
- if (lexbuf[lexbuf_pos] == '-')
+ lexer->lexbuf_pos++;
+ if (lexer->lexbuf[lexer->lexbuf_pos] == '-')
{
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok[tok_pos++] = '-'; /* FIXME */
tok[tok_pos++] = '-';
tok[tok_pos] = '\0';
- in_comment = 1;
+ lexer->in_comment = 1;
return T_C_START;
}
break;
case 'D':
- lexbuf_pos++;
- if (strncmp(lexbuf + lexbuf_pos, "OCTYPE", 6) == 0) {
+ lexer->lexbuf_pos++;
+ if (strncmp(lexer->lexbuf + lexer->lexbuf_pos, "OCTYPE", 6) == 0) {
strncpy(tok + tok_pos, "DOCTYPE", 7); /* FIXME */
- lexbuf_pos += 6;
+ lexer->lexbuf_pos += 6;
return T_DOCTYPE_START;
} else {
return T_ERROR;
}
break;
case '[':
- lexbuf_pos++;
- if (strncmp(lexbuf + lexbuf_pos, "CDATA[", 6) == 0) {
+ lexer->lexbuf_pos++;
+ if (strncmp(lexer->lexbuf + lexer->lexbuf_pos, "CDATA[", 6) == 0) {
strncpy (tok + tok_pos, "[CDATA[", 7); /* FIXME */
- lexbuf_pos += 6;
- lex_mode = CDATA;
+ lexer->lexbuf_pos += 6;
+ lexer->lex_mode = CDATA;
return T_CDATA_START;
} else{
return T_ERROR;
@@ -374,11 +389,11 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case STATE_T_TI_STOP:
if (c == '>') {
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++; /* FIXME */
tok[tok_pos] = '\0';
- if (!in_comment)
- lex_mode = DATA;
+ if (!lexer->in_comment)
+ lexer->lex_mode = DATA;
return T_TI_STOP;
} else {
tok[tok_pos] = '\0';
@@ -392,13 +407,13 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case '-':
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
state = STATE_T_C_STOP;
break;
default:
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
state = STATE_IDENT;
}
break;
@@ -409,21 +424,21 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case '>':
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok[tok_pos] = '\0'; /* FIX ME */
if (strlen(tok) != 3) {
tok[tok_pos - 3] = '\0';
- lexbuf_pos -= 3;
+ lexer->lexbuf_pos -= 3;
return T_IDENT;
} else {
- in_comment = 0;
+ lexer->in_comment = 0;
return T_C_STOP;
}
break;
default:
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
state = STATE_IDENT;
}
break;
@@ -431,7 +446,7 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
/* T_STRING (single quotes) */
case STATE_T_STRING_SINGLE:
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
if (c == '\'') { /* " */
tok[tok_pos] = '\0'; /* FIXME */
return T_STRING;
@@ -458,19 +473,19 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case '?':
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
state = STATE_T_TI_STOP;
break;
case '-':
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
state = STATE_T_DASHDASH;
break;
default:
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
}
break;
default:
@@ -484,12 +499,12 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
{
case '<':
tok[tok_pos] = '\0';
- lex_mode = NORMAL;
+ lexer->lex_mode = NORMAL;
return T_DATA;
default:
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
}
break;
@@ -497,26 +512,26 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
switch (c)
{
case ']':
- if (strncmp(lexbuf + lexbuf_pos, "]]>", 3) == 0) {
- lexbuf_pos += 3;
- lex_mode = DATA;
+ if (strncmp(lexer->lexbuf + lexer->lexbuf_pos, "]]>", 3) == 0) {
+ lexer->lexbuf_pos += 3;
+ lexer->lex_mode = DATA;
return T_CDATA_STOP;
} else {
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
}
break;
default:
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
}
break;
}
}
lprintf ("loop done tok_pos = %d, tok_size=%d, lexbuf_pos=%d, lexbuf_size=%d\n",
- tok_pos, tok_size, lexbuf_pos, lexbuf_size);
+ tok_pos, tok_size, lexer->lexbuf_pos, lexer->lexbuf_size);
/* pb */
if (tok_pos >= tok_size) {
@@ -527,12 +542,12 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
lprintf("token buffer is too small\n");
lprintf("increasing buffer size to %d bytes\n", *_tok_size);
if (*_tok) {
- return lexer_get_token_d (_tok, _tok_size, 0);
+ return lexer_get_token_d_r (lexer, _tok, _tok_size, 0);
} else {
return T_ERROR;
}
} else {
- if (lexbuf_pos >= lexbuf_size) {
+ if (lexer->lexbuf_pos >= lexer->lexbuf_size) {
/* Terminate the current token */
tok[tok_pos] = '\0';
switch (state) {
diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c
index c5acf8739..7ae0626eb 100644
--- a/src/xine-utils/xmlparser.c
+++ b/src/xine-utils/xmlparser.c
@@ -55,7 +55,7 @@
#define MAX_RECURSION 10
/* private global variables */
-static int xml_parser_mode;
+xml_parser_t * static_xml_parser;
/* private functions */
@@ -106,10 +106,24 @@ static void free_xml_property(xml_property_t * property) {
free(property);
}
+/* for ABI compatibility */
void xml_parser_init(const char * buf, int size, int mode) {
+ if (static_xml_parser) {
+ xml_parser_finalize_r(static_xml_parser);
+ }
+ static_xml_parser = xml_parser_init_r(buf, size, mode);
+}
- lexer_init(buf, size);
- xml_parser_mode = mode;
+xml_parser_t *xml_parser_init_r(const char * buf, int size, int mode) {
+ xml_parser_t *xml_parser = malloc(sizeof(*xml_parser));
+ xml_parser->lexer = lexer_init_r(buf, size);
+ xml_parser->mode = mode;
+ return xml_parser;
+}
+
+void xml_parser_finalize_r(xml_parser_t *xml_parser) {
+ lexer_finalize_r(xml_parser->lexer);
+ free(xml_parser);
}
static void xml_parser_free_props(xml_property_t *current_property) {
@@ -223,7 +237,9 @@ static xml_node_t *xml_parser_append_text (xml_node_t *node, xml_node_t *subnode
#define Q_STATE(CURRENT,NEW) (STATE_##NEW + state - STATE_##CURRENT)
-static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffer_size,
+
+static int xml_parser_get_node_internal (xml_parser_t *xml_parser,
+ char ** token_buffer, int * token_buffer_size,
char ** pname_buffer, int * pname_buffer_size,
char ** nname_buffer, int * nname_buffer_size,
xml_node_t *current_node, char *root_names[], int rec, int flags)
@@ -245,7 +261,7 @@ static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffe
memset (tok, 0, *token_buffer_size);
- while ((bypass_get_token) || (res = lexer_get_token_d(token_buffer, token_buffer_size, 0)) != T_ERROR) {
+ while ((bypass_get_token) || (res = lexer_get_token_d_r(xml_parser->lexer, token_buffer, token_buffer_size, 0)) != T_ERROR) {
tok = *token_buffer;
bypass_get_token = 0;
lprintf("info: %d - %d : '%s'\n", state, res, tok);
@@ -302,7 +318,7 @@ static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffe
current_property = NULL;
/* save node name */
- if (xml_parser_mode == XML_PARSER_CASE_INSENSITIVE) {
+ if (xml_parser->mode == XML_PARSER_CASE_INSENSITIVE) {
strtoupper(tok);
}
if (state == STATE_Q_NODE) {
@@ -343,7 +359,7 @@ static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffe
subtree->props = properties;
lprintf("info: rec %d new subtree %s\n", rec, node_name);
root_names[rec + 1] = strdup (node_name);
- parse_res = xml_parser_get_node_internal (token_buffer, token_buffer_size,
+ parse_res = xml_parser_get_node_internal (xml_parser, token_buffer, token_buffer_size,
pname_buffer, pname_buffer_size,
nname_buffer, nname_buffer_size,
subtree, root_names, rec + 1, flags);
@@ -390,7 +406,7 @@ static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffe
case (T_IDENT):
/* save property name */
new_prop:
- if (xml_parser_mode == XML_PARSER_CASE_INSENSITIVE) {
+ if (xml_parser->mode == XML_PARSER_CASE_INSENSITIVE) {
strtoupper(tok);
}
/* make sure the buffer for the property name is big enough */
@@ -431,7 +447,7 @@ static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffe
switch (res) {
case (T_IDENT):
/* must be equal to root_name */
- if (xml_parser_mode == XML_PARSER_CASE_INSENSITIVE) {
+ if (xml_parser->mode == XML_PARSER_CASE_INSENSITIVE) {
strtoupper(tok);
}
if (strcmp(tok, root_names[rec]) == 0) {
@@ -643,7 +659,7 @@ static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffe
}
}
-static int xml_parser_get_node (xml_node_t *current_node, int flags)
+static int xml_parser_get_node (xml_parser_t *xml_parser, xml_node_t *current_node, int flags)
{
int res = 0;
int token_buffer_size = TOKEN_SIZE;
@@ -655,7 +671,8 @@ static int xml_parser_get_node (xml_node_t *current_node, int flags)
char *root_names[MAX_RECURSION + 1];
root_names[0] = "";
- res = xml_parser_get_node_internal (&token_buffer, &token_buffer_size,
+ res = xml_parser_get_node_internal (xml_parser,
+ &token_buffer, &token_buffer_size,
&pname_buffer, &pname_buffer_size,
&nname_buffer, &nname_buffer_size,
current_node, root_names, 0, flags);
@@ -667,12 +684,17 @@ static int xml_parser_get_node (xml_node_t *current_node, int flags)
return res;
}
+/* for ABI compatibility */
int xml_parser_build_tree_with_options(xml_node_t **root_node, int flags) {
+ return xml_parser_build_tree_with_options_r(static_xml_parser, root_node, flags);
+}
+
+int xml_parser_build_tree_with_options_r(xml_parser_t *xml_parser, xml_node_t **root_node, int flags) {
xml_node_t *tmp_node, *pri_node, *q_node;
int res;
tmp_node = new_xml_node();
- res = xml_parser_get_node(tmp_node, flags);
+ res = xml_parser_get_node(xml_parser, tmp_node, flags);
/* delete any top-level [CDATA] nodes */;
pri_node = tmp_node->child;
@@ -715,8 +737,13 @@ int xml_parser_build_tree_with_options(xml_node_t **root_node, int flags) {
return res;
}
+/* for ABI compatibility */
int xml_parser_build_tree(xml_node_t **root_node) {
- return xml_parser_build_tree_with_options (root_node, 0);
+ return xml_parser_build_tree_with_options_r (static_xml_parser, root_node, 0);
+}
+
+int xml_parser_build_tree_r(xml_parser_t *xml_parser, xml_node_t **root_node) {
+ return xml_parser_build_tree_with_options_r(xml_parser, root_node, 0);
}
const char *xml_parser_get_property (const xml_node_t *node, const char *name) {