diff options
author | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2009-11-05 15:06:18 +0000 |
---|---|---|
committer | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2009-11-05 15:06:18 +0000 |
commit | ca2c9c30b5a0f0fcab1ffb52bd065e335ffd4afe (patch) | |
tree | e43b190684d36f5ec7c4c089aec4dc42f48714f0 /src | |
parent | cf86264961e27b47d57981bddb98364947ba7018 (diff) | |
parent | 2af40655557ffc8197e3e59b9428168c2454a68b (diff) | |
download | xine-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
Diffstat (limited to 'src')
-rw-r--r-- | src/combined/ffmpeg/ff_video_decoder.c | 3 | ||||
-rw-r--r-- | src/demuxers/demux_asf.c | 9 | ||||
-rw-r--r-- | src/demuxers/demux_flac.c | 3 | ||||
-rw-r--r-- | src/demuxers/demux_real.c | 3 | ||||
-rw-r--r-- | src/input/input_dvb.c | 2 | ||||
-rw-r--r-- | src/input/libdvdnav/dvd_reader.c | 2 | ||||
-rw-r--r-- | src/spu_dec/cmml_decoder.c | 8 | ||||
-rw-r--r-- | src/spu_dec/spuhdmv_decoder.c | 324 | ||||
-rw-r--r-- | src/xine-engine/scratch.c | 2 | ||||
-rw-r--r-- | src/xine-utils/monitor.c | 46 | ||||
-rw-r--r-- | src/xine-utils/xmllexer.c | 165 | ||||
-rw-r--r-- | src/xine-utils/xmlparser.c | 53 |
12 files changed, 368 insertions, 252 deletions
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) { |