summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDarren Salt <linux@youmustbejoking.demon.co.uk>2007-12-30 18:37:29 +0000
committerDarren Salt <linux@youmustbejoking.demon.co.uk>2007-12-30 18:37:29 +0000
commitcb2f69533fd5771c386d1b994b2179e76c4ded54 (patch)
tree98f4f9bff7afd6e9f0ce2c50b01d1e5ad55ec539 /src
parent6dbb05a4cba3cdc811308762058d722f11464683 (diff)
parentaa3d3aacdb991ad989933d71734e300535c7d350 (diff)
downloadxine-lib-cb2f69533fd5771c386d1b994b2179e76c4ded54.tar.gz
xine-lib-cb2f69533fd5771c386d1b994b2179e76c4ded54.tar.bz2
Merge from 1.1 (except po/*; translators needed for this).
--HG-- rename : src/video_out/vidix/drivers/mga_vid.c => contrib/vidix/drivers/mga_vid.c rename : src/video_out/vidix/drivers/nvidia_vid.c => contrib/vidix/drivers/nvidia_vid.c rename : src/video_out/vidix/drivers/savage_vid.c => contrib/vidix/drivers/savage_vid.c rename : src/xine-engine/video_out.h => include/xine/video_out.h rename : src/xine-utils/xmllexer.h => include/xine/xmllexer.h rename : po/libxine1.pot => po/libxine2.pot rename : src/libsputext/xine_sputext_decoder.c => src/spu_dec/sputext_decoder.c rename : src/libsputext/demux_sputext.c => src/spu_dec/sputext_demuxer.c
Diffstat (limited to 'src')
-rw-r--r--src/demuxers/demux_aiff.c15
-rw-r--r--src/input/input_cdda.c2
-rw-r--r--src/input/input_gnome_vfs.c2
-rw-r--r--src/input/input_net.c10
-rw-r--r--src/input/input_pvr.c111
-rw-r--r--src/post/goom/ifs.c2
-rw-r--r--src/spu_dec/sputext_decoder.c551
-rw-r--r--src/spu_dec/sputext_demuxer.c25
-rw-r--r--src/video_out/video_out_directfb.c14
-rw-r--r--src/video_out/video_out_fb.c14
-rw-r--r--src/video_out/video_out_sdl.c8
-rw-r--r--src/video_out/video_out_syncfb.c12
-rw-r--r--src/video_out/video_out_vidix.c12
-rw-r--r--src/video_out/video_out_xcbshm.c8
-rw-r--r--src/video_out/video_out_xcbxv.c12
-rw-r--r--src/video_out/video_out_xshm.c8
-rw-r--r--src/video_out/video_out_xv.c12
-rw-r--r--src/video_out/video_out_xvmc.c12
-rw-r--r--src/video_out/video_out_xxmc.c12
-rw-r--r--src/xine-utils/xmllexer.c14
-rw-r--r--src/xine-utils/xmlparser.c57
21 files changed, 621 insertions, 292 deletions
diff --git a/src/demuxers/demux_aiff.c b/src/demuxers/demux_aiff.c
index d3b19701a..51bc624e3 100644
--- a/src/demuxers/demux_aiff.c
+++ b/src/demuxers/demux_aiff.c
@@ -87,7 +87,6 @@ static int open_aiff_file(demux_aiff_t *this) {
unsigned char preamble[PREAMBLE_SIZE];
unsigned int chunk_type;
unsigned int chunk_size;
- unsigned char buffer[100];
if (_x_demux_read_header(this->input, signature, AIFF_SIGNATURE_SIZE) != AIFF_SIGNATURE_SIZE)
return 0;
@@ -118,13 +117,15 @@ static int open_aiff_file(demux_aiff_t *this) {
chunk_type = _X_BE_32(&preamble[0]);
chunk_size = _X_BE_32(&preamble[4]);
- if (chunk_size > sizeof(buffer) / sizeof(buffer[0])) {
- /* the chunk is too large to fit in the buffer -> this cannot be an aiff chunk */
- this->status = DEMUX_FINISHED;
- return 0;
- }
-
if (chunk_type == COMM_TAG) {
+ unsigned char buffer[100];
+
+ if (chunk_size > sizeof(buffer) / sizeof(buffer[0])) {
+ /* the chunk is too large to fit in the buffer -> this cannot be an aiff chunk */
+ this->status = DEMUX_FINISHED;
+ return 0;
+ }
+
if (this->input->read(this->input, buffer, chunk_size) !=
chunk_size) {
this->status = DEMUX_FINISHED;
diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c
index c08e1ca0b..3cad27bbe 100644
--- a/src/input/input_cdda.c
+++ b/src/input/input_cdda.c
@@ -1630,7 +1630,7 @@ static int _cdda_cddb_retrieve(cdda_input_plugin_t *this) {
this->cddb.fd = _cdda_cddb_socket_open(this);
if(this->cddb.fd >= 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- _("input_cdda: successfuly connected to cddb server '%s:%d'.\n"),
+ _("input_cdda: successfully connected to cddb server '%s:%d'.\n"),
this->cddb.server, this->cddb.port);
}
else {
diff --git a/src/input/input_gnome_vfs.c b/src/input/input_gnome_vfs.c
index 968945023..7fb2d8b00 100644
--- a/src/input/input_gnome_vfs.c
+++ b/src/input/input_gnome_vfs.c
@@ -200,7 +200,7 @@ gnomevfs_plugin_get_length (input_plugin_t *this_gen)
static uint32_t
gnomevfs_plugin_get_blocksize (input_plugin_t *this_gen)
{
- return 32 * 1024;
+ return 8 * 1024;
}
static const char*
diff --git a/src/input/input_net.c b/src/input/input_net.c
index 1d7288f41..8a4874203 100644
--- a/src/input/input_net.c
+++ b/src/input/input_net.c
@@ -412,6 +412,8 @@ static int net_plugin_open (input_plugin_t *this_gen ) {
char *filename;
char *pptr;
int port = 7658;
+ int toread = MAX_PREVIEW_SIZE;
+ int trycount = 0;
filename = this->host_port;
pptr=strrchr(filename, ':');
@@ -430,11 +432,15 @@ static int net_plugin_open (input_plugin_t *this_gen ) {
/*
* fill preview buffer
*/
+ while ((toread > 0) && (trycount < 10)) {
#ifndef WIN32
- this->preview_size = read (this->fh, this->preview, MAX_PREVIEW_SIZE);
+ this->preview_size += read (this->fh, this->preview + this->preview_size, toread);
#else
- this->preview_size = recv (this->fh, this->preview, MAX_PREVIEW_SIZE, 0);
+ this->preview_size += recv (this->fh, this->preview + this->preview_size, toread, 0);
#endif
+ trycount++;
+ toread = MAX_PREVIEW_SIZE - this->preview_size;
+ }
this->curpos = 0;
diff --git a/src/input/input_pvr.c b/src/input/input_pvr.c
index d68b3fe34..50ba4720e 100644
--- a/src/input/input_pvr.c
+++ b/src/input/input_pvr.c
@@ -979,69 +979,74 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
/* make sure we are not paused */
_x_set_speed(this->stream, XINE_SPEED_NORMAL);
- if( v4l2_data->session_id != this->session ) {
- /* if session changes -> closes the old one */
- pthread_mutex_lock(&this->lock);
- pvr_finish_recording(this);
- time(&this->start_time);
- this->show_time = this->start_time;
- this->session = v4l2_data->session_id;
- this->new_session = 1;
- this->pvr_play_paused = 0;
- this->scr_tunning = 0;
- pvrscr_speed_tunning(this->scr, 1.0 );
- pvr_break_rec_page(this);
- pthread_mutex_unlock(&this->lock);
- _x_demux_flush_engine (this->stream);
- } else {
- /* no session change, break the page and store a new show_time */
- pthread_mutex_lock(&this->lock);
- pvr_break_rec_page(this);
- this->show_page = this->rec_page;
- pthread_mutex_unlock(&this->lock);
- time(&this->show_time);
+ if ( v4l2_data->session_id != -1) {
+ if( v4l2_data->session_id != this->session ) {
+ /* if session changes -> closes the old one */
+ pthread_mutex_lock(&this->lock);
+ pvr_finish_recording(this);
+ time(&this->start_time);
+ this->show_time = this->start_time;
+ this->session = v4l2_data->session_id;
+ this->new_session = 1;
+ this->pvr_play_paused = 0;
+ this->scr_tunning = 0;
+ pvrscr_speed_tunning(this->scr, 1.0 );
+ pvr_break_rec_page(this);
+ pthread_mutex_unlock(&this->lock);
+ _x_demux_flush_engine (this->stream);
+ } else {
+ /* no session change, break the page and store a new show_time */
+ pthread_mutex_lock(&this->lock);
+ pvr_break_rec_page(this);
+ this->show_page = this->rec_page;
+ pthread_mutex_unlock(&this->lock);
+ time(&this->show_time);
+ }
}
-
- if( (v4l2_data->input != -1 && v4l2_data->input != this->input) ||
- (v4l2_data->channel != -1 && v4l2_data->channel != this->channel) ||
- (v4l2_data->frequency != -1 && v4l2_data->frequency != this->frequency) ) {
- struct v4l2_frequency vf;
+ pthread_mutex_lock(&this->dev_lock);
+
+ /* change input */
+ if (v4l2_data->input != -1 && v4l2_data->input != this->input) {
+ lprintf("change input to:%d\n", v4l2_data->input);
this->input = v4l2_data->input;
+
+ /* as of ivtv 0.10.6: must close and reopen to set input */
+ close(this->dev_fd);
+ this->dev_fd = open (this->class->devname, O_RDWR);
+ if (this->dev_fd == -1) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "input_pvr: error opening device %s\n", this->class->devname );
+ } else {
+ if( ioctl(this->dev_fd, VIDIOC_S_INPUT, &this->input) )
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "input_pvr: error setting v4l2 input\n");
+ }
+ }
+
+ /* change channel */
+ if (v4l2_data->channel != -1 && v4l2_data->channel != this->channel) {
+ lprintf("change channel to:%d\n", v4l2_data->channel);
this->channel = v4l2_data->channel;
- this->frequency = v4l2_data->frequency;
+ }
- lprintf("switching to input:%d chan:%d freq:%.2f\n",
- v4l2_data->input,
- v4l2_data->channel,
- (float)v4l2_data->frequency * 62.5);
-
- pthread_mutex_lock(&this->dev_lock);
- if( ioctl(this->dev_fd, VIDIOC_S_INPUT, &this->input) )
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "input_pvr: error setting v4l2 input\n");
-
+ /* change frequency */
+ if (v4l2_data->frequency != -1 && v4l2_data->frequency != this->frequency) {
+ lprintf("changing frequency to:%.2f\n", (float)v4l2_data->frequency * 62.5);
+ struct v4l2_frequency vf;
+ this->frequency = v4l2_data->frequency;
vf.frequency = this->frequency;
vf.tuner = 0;
if( ioctl(this->dev_fd, VIDIOC_S_FREQUENCY, &vf) )
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "input_pvr: error setting v4l2 frequency\n");
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "input_pvr: error setting v4l2 frequency\n");
+ }
- /* workaround an ivtv bug where stream gets bad mpeg2 artifacts
- * after changing inputs. reopening the device fixes it.
- */
- close(this->dev_fd);
- this->dev_fd = open (this->class->devname, O_RDWR);
- if (this->dev_fd == -1) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "input_pvr: error opening device %s\n", this->class->devname );
- return;
- }
- pthread_mutex_unlock(&this->dev_lock);
+ pthread_mutex_unlock(&this->dev_lock);
- /* FIXME: also flush the device */
- /* _x_demux_flush_engine(this->stream); */
- }
+ /* FIXME: also flush the device */
+ /* _x_demux_flush_engine(this->stream); */
+
break;
diff --git a/src/post/goom/ifs.c b/src/post/goom/ifs.c
index af84b777b..4c7ec75d1 100644
--- a/src/post/goom/ifs.c
+++ b/src/post/goom/ifs.c
@@ -64,7 +64,7 @@ IFSPoint;
#define ifs_opts xlockmore_opts
#define DEFAULTS "*delay: 20000 \n" \
-"*ncolors: 100 \n"
+"*ncolours: 100 \n"
#define SMOOTH_COLORS
diff --git a/src/spu_dec/sputext_decoder.c b/src/spu_dec/sputext_decoder.c
index 0c156d2e9..093fca1e7 100644
--- a/src/spu_dec/sputext_decoder.c
+++ b/src/spu_dec/sputext_decoder.c
@@ -41,6 +41,26 @@
#define SUB_MAX_TEXT 5 /* lines */
#define SUB_BUFSIZE 256 /* chars per line */
+/* alignment in SSA codes */
+#define ALIGN_LEFT 1
+#define ALIGN_CENTER 2
+#define ALIGN_RIGHT 3
+#define ALIGN_BOTTOM 0
+#define ALIGN_TOP 4
+#define ALIGN_MIDDLE 8
+#define GET_X_ALIGNMENT(a) ((a) & 3)
+#define GET_Y_ALIGNMENT(a) ((a) - ((a) & 3))
+
+/* subtitles projection */
+/* for subrip file with SSA tags, those values are always correct.*/
+/* But for SSA files, those values are the default ones. we have */
+/* to use PlayResX and PlayResY defined in [Script Info] section. */
+/* not implemented yet... */
+#define SPU_PROJECTION_X 384
+#define SPU_PROJECTION_Y 288
+
+
+
#define rgb2yuv(R,G,B) ((((((66*R+129*G+25*B+128)>>8)+16)<<8)|(((112*R-94*G-18*B+128)>>8)+128))<<8|(((-38*R-74*G+112*B+128)>>8)+128))
static const uint32_t sub_palette[22]={
@@ -106,6 +126,15 @@ typedef struct sputext_class_s {
} sputext_class_t;
+/* Convert subtiles coordinates in window coordinates. */
+/* (a, b) --> (x + a * dx, y + b * dy) */
+typedef struct video2wnd_s {
+ int x;
+ int y;
+ double dx;
+ double dy;
+} video2wnd_t;
+
typedef struct sputext_decoder_s {
spu_decoder_t spu_decoder;
@@ -141,7 +170,9 @@ typedef struct sputext_decoder_s {
int64_t last_subtitle_end; /* no new subtitle before this vpts */
int unscaled; /* use unscaled OSD */
+ int last_y; /* location of the previous subtitle */
int last_lines; /* number of lines of the previous subtitle */
+ video2wnd_t video2wnd;
} sputext_decoder_t;
static inline char *get_font (sputext_class_t *class)
@@ -156,8 +187,6 @@ static inline char *get_font (sputext_class_t *class)
static void update_font_size (sputext_decoder_t *this, int force_update) {
static int sizes[SUBTITLE_SIZE_NUM] = { 16, 20, 24, 32, 48, 64 };
- int y;
-
if ((this->subtitle_size != this->class->subtitle_size) ||
(this->vertical_offset != this->class->vertical_offset) ||
force_update) {
@@ -170,21 +199,17 @@ static void update_font_size (sputext_decoder_t *this, int force_update) {
this->line_height = this->font_size + 10;
- y = this->height - (SUB_MAX_TEXT * this->line_height) - 5;
-
- if(((y - this->class->vertical_offset) >= 0) && ((y - this->class->vertical_offset) <= this->height))
- y -= this->class->vertical_offset;
-
+ /* Create a full-window OSD */
if( this->osd )
this->renderer->free_object (this->osd);
- lprintf("new osd object, width %d, height %d*%d\n", this->width, SUB_MAX_TEXT, this->line_height);
this->osd = this->renderer->new_object (this->renderer,
this->width,
- SUB_MAX_TEXT * this->line_height);
+ this->height);
this->renderer->set_font (this->osd, get_font (this->class), this->font_size);
- this->renderer->set_position (this->osd, 0, y);
+
+ this->renderer->set_position (this->osd, 0, 0);
}
}
@@ -208,7 +233,7 @@ static void update_output_size (sputext_decoder_t *this) {
VO_PROP_WINDOW_HEIGHT) ||
!this->img_duration || !this->osd ) {
- int width = 0, height = 0; /* dummy */
+ int width = 0, height = 0;
this->stream->video_out->status(this->stream->video_out, NULL,
&width, &height, &this->img_duration );
@@ -220,8 +245,36 @@ static void update_output_size (sputext_decoder_t *this) {
VO_PROP_WINDOW_HEIGHT);
if(!this->osd || (this->width && this->height)) {
+
+ /* in unscaled mode, we have to convert subtitle position in window coordinates. */
+ /* we have a scale factor because video may be zommed */
+ /* and a displacement factor because video may have blacks lines. */
+ int output_width, output_height, output_xoffset, output_yoffset;
+
+ output_width = this->stream->video_out->get_property(this->stream->video_out,
+ VO_PROP_OUTPUT_WIDTH);
+ output_height = this->stream->video_out->get_property(this->stream->video_out,
+ VO_PROP_OUTPUT_HEIGHT);
+ output_xoffset = this->stream->video_out->get_property(this->stream->video_out,
+ VO_PROP_OUTPUT_XOFFSET);
+ output_yoffset = this->stream->video_out->get_property(this->stream->video_out,
+ VO_PROP_OUTPUT_YOFFSET);
+
+ /* driver don't seen to be capable to give us those values */
+ /* fallback to a default full-window values */
+ if (output_width <= 0 || output_height <= 0) {
+ output_width = this->width;
+ output_height = this->height;
+ output_xoffset = 0;
+ output_yoffset = 0;
+ }
+
+ this->video2wnd.x = output_xoffset;
+ this->video2wnd.y = output_yoffset;
+ this->video2wnd.dx = (double)output_width / SPU_PROJECTION_X;
+ this->video2wnd.dy = (double)output_height / SPU_PROJECTION_Y;
+
this->renderer = this->stream->osd_renderer;
-
update_font_size (this, 1);
}
}
@@ -238,6 +291,12 @@ static void update_output_size (sputext_decoder_t *this) {
if(!this->osd || ( this->width && this->height)) {
this->renderer = this->stream->osd_renderer;
+ /* in scaled mode, we have to convert subtitle position in film coordinates. */
+ this->video2wnd.x = 0;
+ this->video2wnd.y = 0;
+ this->video2wnd.dx = (double)this->width / SPU_PROJECTION_X;
+ this->video2wnd.dy = (double)this->height / SPU_PROJECTION_Y;
+
update_font_size (this, 1);
}
}
@@ -271,7 +330,8 @@ static int parse_utf8_size(const void *buf)
static int ogm_render_line_internal(sputext_decoder_t *this, int x, int y, const char *text, int render)
{
- int i = 0, w, dummy;
+ int i = 0, w, value;
+ char* end;
char letter[5]={0, 0, 0, 0, 0};
const char *encoding = this->buf_encoding ? this->buf_encoding
: this->class->src_encoding;
@@ -279,55 +339,82 @@ static int ogm_render_line_internal(sputext_decoder_t *this, int x, int y, const
size_t length = strlen (text);
while (i <= length) {
- switch (text[i]) {
- case '<':
+
+ if (text[i] == '<') {
if (!strncmp("<b>", text+i, 3)) {
/* enable Bold color */
if (render)
this->current_osd_text = OSD_TEXT2;
i=i+3;
- break;
+ continue;
} else if (!strncmp("</b>", text+i, 4)) {
/* disable BOLD */
if (render)
this->current_osd_text = OSD_TEXT1;
i=i+4;
- break;
+ continue;
} else if (!strncmp("<i>", text+i, 3)) {
/* enable italics color */
if (render)
this->current_osd_text = OSD_TEXT3;
i=i+3;
- break;
+ continue;
} else if (!strncmp("</i>", text+i, 4)) {
/* disable italics */
if (render)
this->current_osd_text = OSD_TEXT1;
i=i+4;
- break;
+ continue;
} else if (!strncmp("<font>", text+i, 6)) {
/*Do somethink to disable typing
fixme - no teststreams*/
i=i+6;
- break;
+ continue;
} else if (!strncmp("</font>", text+i, 7)) {
/*Do somethink to enable typing
fixme - no teststreams*/
i=i+7;
- break;
- }
- default:
- shift = isutf8 ? parse_utf8_size (&text[i]) : 1;
- memcpy(letter,&text[i],shift);
- letter[shift]=0;
-
- if (render)
- this->renderer->render_text(this->osd, x, y, letter, this->current_osd_text);
- this->renderer->get_text_size(this->osd, letter, &w, &dummy);
- x=x+w;
- i+=shift;
+ continue;
+ }
+ }
+ if (text[i] == '{') {
+
+ if (!strncmp("{\\", text+i, 2)) {
+
+ if (sscanf(text+i, "{\\b%d}", &value) == 1) {
+ if (render) {
+ if (value)
+ this->current_osd_text = OSD_TEXT2;
+ else
+ this->current_osd_text = OSD_TEXT1;
+ }
+ } else if (sscanf(text+i, "{\\i%d}", &value) == 1) {
+ if (render) {
+ if (value)
+ this->current_osd_text = OSD_TEXT3;
+ else
+ this->current_osd_text = OSD_TEXT1;
+ }
+ }
+ end = strstr(text+i+2, "}");
+ if (end) {
+ i=end-text+1;
+ continue;
+ }
+ }
}
+
+ shift = isutf8 ? parse_utf8_size (&text[i]) : 1;
+ memcpy(letter,&text[i],shift);
+ letter[shift]=0;
+
+ if (render)
+ this->renderer->render_text(this->osd, x, y, letter, this->current_osd_text);
+ this->renderer->get_text_size(this->osd, letter, &w, &value);
+ x=x+w;
+ i+=shift;
}
+
return x;
}
@@ -339,16 +426,103 @@ static inline void ogm_render_line(sputext_decoder_t *this, int x, int y, char*
ogm_render_line_internal (this, x, y, text, 1);
}
+/* read SSA tags at begening of text. Suported tags are : */
+/* \a : alignment in SSA code (see #defines) */
+/* \an : alignment in 'numpad code' */
+/* \pos : absolute position of subtitles. Alignment define origin. */
+static void read_ssa_tag(sputext_decoder_t *this, const char* text,
+ int* alignment, int* sub_x, int* sub_y, int* max_width) {
+
+ int in_tag = 0;
+
+ (*alignment) = 2;
+ (*sub_x) = -1;
+ (*sub_y) = -1;
+
+ while (*text) {
+
+ /* wait for tag begin, allow space and tab */
+ if (in_tag == 0) {
+ if (*text == '{') in_tag = 1;
+ else if ((*text != ' ') && (*text != '\t')) break;
+
+ /* parse SSA command */
+ } else {
+ if (*text == '\\') {
+ if (sscanf(text, "\\pos(%d,%d)", sub_x, sub_y) == 2) {
+ text += 8; /* just for speed up, 8 is the minimal with */
+ }
+
+ if (sscanf(text, "\\a%d", alignment) == 1) {
+ text += 2;
+ }
+
+ if (sscanf(text, "\\an%d", alignment) == 1) {
+ text += 3;
+ if ((*alignment) > 6) (*alignment) = (*alignment) - 2;
+ else if ((*alignment) > 3) (*alignment) = (*alignment) + 5;
+ }
+ }
+
+ if (*text == '}') in_tag = 0;
+ }
+
+ text++;
+ }
+
+
+ /* check alignment validity */
+ if ((*alignment) < 1 || (*alignment) > 11) {
+ (*alignment) = 2;
+ }
+
+ /* convert to window coordinates */
+ if ((*sub_x) >= 0 && (*sub_y) >= 0) {
+ (*sub_x) = this->video2wnd.x + this->video2wnd.dx * (*sub_x);
+ (*sub_y) = this->video2wnd.y + this->video2wnd.dy * (*sub_y);
+ }
+
+ /* check validity, compute max width */
+ if ( (*sub_x) < 0 || (*sub_x) >= this->width ||
+ (*sub_y) < 0 || (*sub_y) >= this->height ) {
+ (*sub_x) = -1;
+ (*sub_y) = -1;
+ (*max_width) = this->width;
+ } else {
+ switch (GET_X_ALIGNMENT(*alignment)) {
+ case ALIGN_LEFT:
+ (*max_width) = this->width - (*sub_x);
+ break;
+ case ALIGN_CENTER:
+ (*max_width) = this->width;
+ break;
+ case ALIGN_RIGHT:
+ (*max_width) = (*sub_x);
+ break;
+ }
+ }
+
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "libsputext: position : (%d, %d), max width : %d, alignment : %d\n",
+ (*sub_x), (*sub_y), (*max_width), (*alignment));
+}
+
static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t sub_end ) {
int line, y;
int font_size;
char *font;
+ int sub_x, sub_y, max_width;
+ int alignment;
+ int rebuild_all;
+
_x_assert(this->renderer != NULL);
if ( ! this->renderer )
return;
+ read_ssa_tag(this, this->text[0], &alignment, &sub_x, &sub_y, &max_width);
+
update_font_size(this, 0);
font = get_font (this->class);
@@ -364,178 +538,181 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su
else
this->renderer->set_encoding(this->osd, this->class->src_encoding);
- for (line = 0; line < this->lines; line++) /* first, check lenghts and word-wrap if needed */
- {
- int w;
- w = ogm_get_width( this, this->text[line]);
- if( w > this->width ) { /* line is too long */
- int chunks=(int)(w/this->width)+(w%this->width?1:0);
- if( this->lines+chunks <= SUB_MAX_TEXT && chunks>1 ) { /* try adding newlines while keeping existing ones */
- int a;
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,"Partial subtitle line splitting in %i chunks\n",chunks);
- for(a=this->lines-1;a>=0;a--) {
- if(a>line) /* lines after the too-long one */
- memcpy(this->text[a+chunks-1],this->text[a],SUB_BUFSIZE);
- else if(a==line) { /* line to be splitted */
- int b,len=strlen(this->text[line]);
- char *p=this->text[line];
- for(b=0;b<chunks;b++) {
- char *c;
- if(b==chunks-1) { /* if we are reading the last chunk, copy it completly */
- strncpy(this->text[line+b],p,SUB_BUFSIZE);
- this->text[line+b][SUB_BUFSIZE - 1] = '\0';
- } else {
- for(c=p+(int)(len/chunks)+(len%chunks?1:0);*c!=' ' && c>p && c!='\0';c--);
- if(*c==' ') {
- *c='\0';
- if(b) { /* we are reading something that has to be moved to another line */
- strncpy(this->text[line+b],p,SUB_BUFSIZE);
- this->text[line+b][SUB_BUFSIZE - 1] = '\0';
- }
- p=c+1;
- }
- }
- }
- }
- }
- this->lines+=chunks-1;
- } else { /* regenerate all the lines to find something that better fits */
- char buf[SUB_BUFSIZE*SUB_MAX_TEXT];
- int a,w,chunks;
- buf[0]='\0';
- for(a=0;a<this->lines;a++) {
- if(a) {
- int len=strlen(buf);
- buf[len]=' ';
- buf[len+1]='\0';
- }
- strcat(buf,this->text[a]);
+
+ rebuild_all = 0;
+ for (line = 0; line < this->lines; line++) {
+ int line_width = ogm_get_width(this, this->text[line]);
+
+ /* line too long */
+ if (line_width > max_width) {
+ char *current_cut, *best_cut;
+ int a;
+
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "libsputext: Line too long: %d > %d, split at max size.\n",
+ line_width, max_width);
+
+ /* can't fit with keeping existing lines */
+ if (this->lines + 1 > SUB_MAX_TEXT) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "libsputext: Can't fit with keeping existing line, we have to rebuild all the subtitle\n");
+ rebuild_all = 1;
+ break;
+ }
+
+ /* find the longest sequence witch fit */
+ line_width = 0;
+ current_cut = this->text[line];
+ best_cut = NULL;
+ while (line_width < max_width) {
+ while (*current_cut && *current_cut != ' ') current_cut++;
+ if (*current_cut == ' ') {
+ *current_cut = 0;
+ line_width = ogm_get_width(this, this->text[line]);
+ *current_cut = ' ';
+ if (line_width < max_width) best_cut = current_cut;
+ current_cut++;
+ } else {
+ break; /* end of line */
}
- w = ogm_get_width( this, buf);
- chunks=(int)(w/this->width)+(w%this->width?1:0);
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Complete subtitle line splitting in %i chunks\n",chunks);
- if(chunks<=SUB_MAX_TEXT) {/* if the length is over than SUB_MAX_TEXT*this->width nothing can be done */
- int b,len=strlen(buf);
- char *p=buf;
- for(b=0;b<chunks;b++) {
- char *c;
- if(b==chunks-1) { /* if we are reading the last chunk, copy it completly */
- strncpy(this->text[b],p,SUB_BUFSIZE);
- this->text[b][SUB_BUFSIZE - 1] = '\0';
- } else {
- for(c=p+(int)(len/chunks)+(len%chunks?1:0);*c!=' ' && c>p && c!='\0';c--);
- if(*c==' ') {
- *c='\0';
- strncpy(this->text[b],p,SUB_BUFSIZE);
- this->text[b][SUB_BUFSIZE - 1] = '\0';
- p=c+1;
- }
- }
- }
- this->lines=chunks;
- } else
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Subtitle too long to be splited\n");
- line=this->lines;
}
+
+ if (best_cut == NULL) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "libsputext: Can't wrap line: a word is too long, abort.\n");
+ break;
+ }
+
+ /* move other lines */
+ for (a = this->lines - 1; a > line; a--)
+ memcpy(this->text[a + 1], this->text[a], SUB_BUFSIZE);
+
+ /* split current one */
+ strncpy(this->text[line + 1], best_cut + 1, SUB_BUFSIZE);
+ *best_cut = 0;
+
+ this->lines = this->lines + 1;
}
}
- font_size = this->font_size;
- if (this->buf_encoding)
- this->renderer->set_encoding(this->osd, this->buf_encoding);
- else
- this->renderer->set_encoding(this->osd, this->class->src_encoding);
+ /* regenerate all the lines to find something that better fits */
+ if (rebuild_all) {
+ int line, line_width;
+ char *stream, *current_cut, *best_cut;
+ char buf[SUB_BUFSIZE * SUB_MAX_TEXT];
+
+ buf[0] = 0;
+ for(line = 0; line < this->lines; line++) {
+ int len = strlen(buf);
+ if (len) {
+ buf[len] = ' ';
+ len++;
+ }
+ strncpy(buf + len, this->text[line], SUB_BUFSIZE);
+ *(buf + len + SUB_BUFSIZE) = 0;
+ }
- for (line = 0; line < this->lines; line++) /* first, check lenghts and word-wrap if needed */
- {
- int w;
- w = ogm_get_width( this, this->text[line]);
- if( w > this->width ) { /* line is too long */
- int chunks=(int)(w/this->width)+(w%this->width?1:0);
- if( this->lines+chunks <= SUB_MAX_TEXT && chunks>1 ) { /* try adding newlines while keeping existing ones */
- int a;
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,"Partial subtitle line splitting in %i chunks\n",chunks);
- for(a=this->lines-1;a>=0;a--) {
- if(a>line) /* lines after the too-long one */
- memcpy(this->text[a+chunks-1],this->text[a],SUB_BUFSIZE);
- else if(a==line) { /* line to be splitted */
- int b,len=strlen(this->text[line]);
- char *p=this->text[line];
- for(b=0;b<chunks;b++) {
- char *c;
- if(b==chunks-1) { /* if we are reading the last chunk, copy it completly */
- strncpy(this->text[line+b],p,SUB_BUFSIZE);
- this->text[line+b][SUB_BUFSIZE - 1] = '\0';
- } else {
- for(c=p+(int)(len/chunks)+(len%chunks?1:0);*c!=' ' && c>p && c!='\0';c--);
- if(*c==' ') {
- *c='\0';
- if(b) { /* we are reading something that has to be moved to another line */
- strncpy(this->text[line+b],p,SUB_BUFSIZE);
- this->text[line+b][SUB_BUFSIZE - 1] = '\0';
- }
- p=c+1;
- }
- }
- }
- }
- }
- this->lines+=chunks-1;
- } else { /* regenerate all the lines to find something that better fits */
- char buf[SUB_BUFSIZE*SUB_MAX_TEXT];
- int a,w,chunks;
- buf[0]='\0';
- for(a=0;a<this->lines;a++) {
- if(a) {
- int len=strlen(buf);
- buf[len]=' ';
- buf[len+1]='\0';
+ stream = buf;
+ this->lines = 0;
+
+ do {
+
+ if (this->lines + 1 < SUB_MAX_TEXT) {
+
+ /* find the longest sequence witch fit */
+ line_width = 0;
+ current_cut = stream;
+ best_cut = NULL;
+ while (line_width < max_width) {
+ while (*current_cut && *current_cut != ' ') current_cut++;
+ if (*current_cut == ' ') {
+ *current_cut = 0;
+ line_width = ogm_get_width(this, stream);
+ *current_cut = ' ';
+ if (line_width < max_width) best_cut = current_cut;
+ current_cut++;
+ } else {
+ line_width = ogm_get_width(this, stream);
+ if (line_width < max_width) best_cut = current_cut;
+ break; /* end of line */
}
- strcat(buf,this->text[a]);
}
- w = ogm_get_width( this, buf);
- chunks=(int)(w/this->width)+(w%this->width?1:0);
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Complete subtitle line splitting in %i chunks\n",chunks);
- if(chunks<=SUB_MAX_TEXT) {/* if the length is over than SUB_MAX_TEXT*this->width nothing can be done */
- int b,len=strlen(buf);
- char *p=buf;
- for(b=0;b<chunks;b++) {
- char *c;
- if(b==chunks-1) { /* if we are reading the last chunk, copy it completly */
- strncpy(this->text[b],p,SUB_BUFSIZE);
- this->text[b][SUB_BUFSIZE - 1] = '\0';
- } else {
- for(c=p+(int)(len/chunks)+(len%chunks?1:0);*c!=' ' && c>p && c!='\0';c--);
- if(*c==' ') {
- *c='\0';
- strncpy(this->text[b],p,SUB_BUFSIZE);
- this->text[b][SUB_BUFSIZE - 1] = '\0';
- p=c+1;
- }
- }
- }
- this->lines=chunks;
- } else
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Subtitle too long to be splited\n");
- line=this->lines;
}
- }
+
+ /* line maybe too long, but we have reached last subtitle line */
+ else {
+ best_cut = current_cut = stream + strlen(stream);
+ }
+
+ /* copy current line */
+ if (best_cut != NULL) *best_cut = 0;
+ strncpy(this->text[this->lines], stream, SUB_BUFSIZE);
+ this->lines = this->lines + 1;
+
+ stream = best_cut + 1;
+
+ } while (best_cut != current_cut);
+
}
- if (this->last_lines)
- this->renderer->filled_rect (this->osd, 0, this->line_height * (SUB_MAX_TEXT - this->last_lines),
- this->width - 1, this->line_height * SUB_MAX_TEXT - 1, 0);
- this->last_lines = this->lines;
- y = (SUB_MAX_TEXT - this->lines) * this->line_height;
+
+ /* Erase subtitle : use last_y and last_lines saved last turn. */
+ if (this->last_lines) {
+ this->renderer->filled_rect (this->osd, 0, this->last_y,
+ this->width - 1, this->last_y + this->last_lines * this->line_height,
+ 0);
+ }
+
+ switch (GET_Y_ALIGNMENT(alignment)) {
+ case ALIGN_TOP:
+ if (sub_y >= 0) y = sub_y;
+ else y = 5;
+ break;
+
+ case ALIGN_MIDDLE:
+ if (sub_y >= 0) y = sub_y - (this->lines * this->line_height) / 2;
+ else y = (this->height - this->lines * this->line_height) / 2;
+ break;
+
+ case ALIGN_BOTTOM:
+ default:
+ if (sub_y >= 0) y = sub_y - this->lines * this->line_height;
+ else y = this->height - this->lines * this->line_height - this->class->vertical_offset;
+ break;
+ }
+ if (y < 0 || y >= this->height)
+ y = this->height - this->line_height * this->lines;
+
+ this->last_lines = this->lines;
+ this->last_y = y;
+
for (line = 0; line < this->lines; line++) {
int w, x;
while(1) {
w = ogm_get_width( this, this->text[line]);
- x = (this->width - w) / 2;
-
- if( w > this->width && font_size > 16 ) {
+
+ switch (GET_X_ALIGNMENT(alignment)) {
+ case ALIGN_LEFT:
+ if (sub_x >= 0) x = sub_x;
+ else x = 5;
+ break;
+
+ case ALIGN_RIGHT:
+ if (sub_x >= 0) x = sub_x - w;
+ else x = max_width - w - 5;
+ break;
+
+ case ALIGN_CENTER:
+ default:
+ if (sub_x >= 0) x = sub_x - w / 2;
+ else x = (max_width - w) / 2;
+ break;
+ }
+
+
+ if( w > max_width && font_size > 16 ) {
font_size -= 4;
this->renderer->set_font (this->osd, get_font (this->class), font_size);
} else {
diff --git a/src/spu_dec/sputext_demuxer.c b/src/spu_dec/sputext_demuxer.c
index 49ecbb172..d7d1361b1 100644
--- a/src/spu_dec/sputext_demuxer.c
+++ b/src/spu_dec/sputext_demuxer.c
@@ -382,31 +382,6 @@ static subtitle_t *sub_read_line_subrip(demux_sputext_t *this,subtitle_t *curren
} else
temp_line[temp_index++]=*p;
break;
- case '{':
-#if 0 /* italic not implemented in renderer, ignore them for now */
- if(!strncmp(p,"{\\i1}",5) && temp_index+3<SUB_BUFSIZE) {
- temp_line[temp_index++]='<';
- temp_line[temp_index++]='i';
- temp_line[temp_index++]='>';
-#else
- if(!strncmp(p,"{\\i1}",5)) {
-#endif
- p+=4;
- }
-#if 0 /* italic not implemented in renderer, ignore them for now */
- else if(!strncmp(p,"{\\i0}",5) && temp_index+4<SUB_BUFSIZE) {
- temp_line[temp_index++]='<';
- temp_line[temp_index++]='/';
- temp_line[temp_index++]='i';
- temp_line[temp_index++]='>';
-#else
- else if(!strncmp(p,"{\\i0}",5)) {
-#endif
- p+=4;
- }
- else
- temp_line[temp_index++]=*p;
- break;
case '\r': /* just ignore '\r's */
break;
case '\n':
diff --git a/src/video_out/video_out_directfb.c b/src/video_out/video_out_directfb.c
index 943eec681..0781384c1 100644
--- a/src/video_out/video_out_directfb.c
+++ b/src/video_out/video_out_directfb.c
@@ -922,7 +922,19 @@ static int directfb_get_property (vo_driver_t *this_gen, int property) {
case VO_PROP_WINDOW_HEIGHT:
return this->sc.gui_height;
-
+
+ case VO_PROP_OUTPUT_WIDTH:
+ return this->cur_frame->sc.output_width;
+
+ case VO_PROP_OUTPUT_HEIGHT:
+ return this->cur_frame->sc.output_height;
+
+ case VO_PROP_OUTPUT_XOFFSET:
+ return this->cur_frame->sc.output_xoffset;
+
+ case VO_PROP_OUTPUT_YOFFSET:
+ return this->cur_frame->sc.output_yoffset;
+
case VO_PROP_MAX_NUM_FRAMES:
return (this->type & DLTF_VIDEO) ? 8 : 15;
diff --git a/src/video_out/video_out_fb.c b/src/video_out/video_out_fb.c
index 1e95e5a71..d45989e14 100644
--- a/src/video_out/video_out_fb.c
+++ b/src/video_out/video_out_fb.c
@@ -600,7 +600,19 @@ static int fb_get_property(vo_driver_t *this_gen, int property)
case VO_PROP_WINDOW_HEIGHT:
return this->sc.gui_height;
-
+
+ case VO_PROP_OUTPUT_WIDTH:
+ return this->cur_frame->sc.output_width;
+
+ case VO_PROP_OUTPUT_HEIGHT:
+ return this->cur_frame->sc.output_height;
+
+ case VO_PROP_OUTPUT_XOFFSET:
+ return this->cur_frame->sc.output_xoffset;
+
+ case VO_PROP_OUTPUT_YOFFSET:
+ return this->cur_frame->sc.output_yoffset;
+
default:
xprintf(this->xine, XINE_VERBOSITY_DEBUG,
"video_out_fb: tried to get unsupported property %d\n", property);
diff --git a/src/video_out/video_out_sdl.c b/src/video_out/video_out_sdl.c
index 5866f822f..de9736845 100644
--- a/src/video_out/video_out_sdl.c
+++ b/src/video_out/video_out_sdl.c
@@ -360,6 +360,14 @@ static int sdl_get_property (vo_driver_t *this_gen, int property) {
return this->sc.gui_width;
case VO_PROP_WINDOW_HEIGHT:
return this->sc.gui_height;
+ case VO_PROP_OUTPUT_WIDTH:
+ return this->sc.output_width;
+ case VO_PROP_OUTPUT_HEIGHT:
+ return this->sc.output_height;
+ case VO_PROP_OUTPUT_XOFFSET:
+ return this->sc.output_xoffset;
+ case VO_PROP_OUTPUT_YOFFSET:
+ return this->sc.output_yoffset;
case VO_PROP_ASPECT_RATIO:
return this->sc.user_ratio;
}
diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c
index e6c3ffdf6..49c0d371a 100644
--- a/src/video_out/video_out_syncfb.c
+++ b/src/video_out/video_out_syncfb.c
@@ -670,6 +670,18 @@ static int syncfb_get_property(vo_driver_t* this_gen, int property)
case VO_PROP_WINDOW_HEIGHT:
this->props[property].value = this->sc.gui_height;
break;
+ case VO_PROP_OUTPUT_WIDTH:
+ this->props[property].value = this->sc.output_width;
+ break;
+ case VO_PROP_OUTPUT_HEIGHT:
+ this->props[property].value = this->sc.output_height;
+ break;
+ case VO_PROP_OUTPUT_XOFFSET:
+ this->props[property].value = this->sc.output_xoffset;
+ break;
+ case VO_PROP_OUTPUT_YOFFSET:
+ this->props[property].value = this->sc.output_yoffset;
+ break;
}
return this->props[property].value;
diff --git a/src/video_out/video_out_vidix.c b/src/video_out/video_out_vidix.c
index 251dac87e..d0a45a58c 100644
--- a/src/video_out/video_out_vidix.c
+++ b/src/video_out/video_out_vidix.c
@@ -700,6 +700,18 @@ static int vidix_get_property (vo_driver_t *this_gen, int property) {
case VO_PROP_WINDOW_HEIGHT:
this->props[property].value = this->sc.gui_height;
break;
+ case VO_PROP_OUTPUT_WIDTH:
+ this->props[property].value = this->sc.output_width;
+ break;
+ case VO_PROP_OUTPUT_HEIGHT:
+ this->props[property].value = this->sc.output_height;
+ break;
+ case VO_PROP_OUTPUT_XOFFSET:
+ this->props[property].value = this->sc.output_xoffset;
+ break;
+ case VO_PROP_OUTPUT_YOFFSET:
+ this->props[property].value = this->sc.output_yoffset;
+ break;
}
lprintf ("video_out_vidix: property #%d = %d\n", property,
diff --git a/src/video_out/video_out_xcbshm.c b/src/video_out/video_out_xcbshm.c
index 9e9df7a71..376099e8f 100644
--- a/src/video_out/video_out_xcbshm.c
+++ b/src/video_out/video_out_xcbshm.c
@@ -730,6 +730,14 @@ static int xshm_get_property (vo_driver_t *this_gen, int property) {
return this->sc.gui_width;
case VO_PROP_WINDOW_HEIGHT:
return this->sc.gui_height;
+ case VO_PROP_OUTPUT_WIDTH:
+ return this->cur_frame->sc.output_width;
+ case VO_PROP_OUTPUT_HEIGHT:
+ return this->cur_frame->sc.output_height;
+ case VO_PROP_OUTPUT_XOFFSET:
+ return this->cur_frame->sc.output_xoffset;
+ case VO_PROP_OUTPUT_YOFFSET:
+ return this->cur_frame->sc.output_yoffset;
default:
xprintf(this->xine, XINE_VERBOSITY_DEBUG,
LOG_MODULE ": tried to get unsupported property %d\n", property);
diff --git a/src/video_out/video_out_xcbxv.c b/src/video_out/video_out_xcbxv.c
index f3650a6dd..19a387732 100644
--- a/src/video_out/video_out_xcbxv.c
+++ b/src/video_out/video_out_xcbxv.c
@@ -636,6 +636,18 @@ static int xv_get_property (vo_driver_t *this_gen, int property) {
case VO_PROP_WINDOW_HEIGHT:
this->props[property].value = this->sc.gui_height;
break;
+ case VO_PROP_OUTPUT_WIDTH:
+ this->props[property].value = this->sc.output_width;
+ break;
+ case VO_PROP_OUTPUT_HEIGHT:
+ this->props[property].value = this->sc.output_height;
+ break;
+ case VO_PROP_OUTPUT_XOFFSET:
+ this->props[property].value = this->sc.output_xoffset;
+ break;
+ case VO_PROP_OUTPUT_YOFFSET:
+ this->props[property].value = this->sc.output_yoffset;
+ break;
}
lprintf(LOG_MODULE ": property #%d = %d\n", property, this->props[property].value);
diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c
index 52468781a..cce57f27a 100644
--- a/src/video_out/video_out_xshm.c
+++ b/src/video_out/video_out_xshm.c
@@ -819,6 +819,14 @@ static int xshm_get_property (vo_driver_t *this_gen, int property) {
return this->sc.gui_width;
case VO_PROP_WINDOW_HEIGHT:
return this->sc.gui_height;
+ case VO_PROP_OUTPUT_WIDTH:
+ return this->cur_frame->sc.output_width;
+ case VO_PROP_OUTPUT_HEIGHT:
+ return this->cur_frame->sc.output_height;
+ case VO_PROP_OUTPUT_XOFFSET:
+ return this->cur_frame->sc.output_xoffset;
+ case VO_PROP_OUTPUT_YOFFSET:
+ return this->cur_frame->sc.output_yoffset;
default:
xprintf(this->xine, XINE_VERBOSITY_DEBUG,
LOG_MODULE ": tried to get unsupported property %d\n", property);
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index b99f8eae2..208e8600f 100644
--- a/src/video_out/video_out_xv.c
+++ b/src/video_out/video_out_xv.c
@@ -737,6 +737,18 @@ static int xv_get_property (vo_driver_t *this_gen, int property) {
case VO_PROP_WINDOW_HEIGHT:
this->props[property].value = this->sc.gui_height;
break;
+ case VO_PROP_OUTPUT_WIDTH:
+ this->props[property].value = this->sc.output_width;
+ break;
+ case VO_PROP_OUTPUT_HEIGHT:
+ this->props[property].value = this->sc.output_height;
+ break;
+ case VO_PROP_OUTPUT_XOFFSET:
+ this->props[property].value = this->sc.output_xoffset;
+ break;
+ case VO_PROP_OUTPUT_YOFFSET:
+ this->props[property].value = this->sc.output_yoffset;
+ break;
}
lprintf(LOG_MODULE ": property #%d = %d\n", property, this->props[property].value);
diff --git a/src/video_out/video_out_xvmc.c b/src/video_out/video_out_xvmc.c
index 8d7b5737d..6aa8f430d 100644
--- a/src/video_out/video_out_xvmc.c
+++ b/src/video_out/video_out_xvmc.c
@@ -991,6 +991,18 @@ static int xvmc_get_property (vo_driver_t *this_gen, int property) {
case VO_PROP_WINDOW_HEIGHT:
this->props[property].value = this->sc.gui_height;
break;
+ case VO_PROP_OUTPUT_WIDTH:
+ this->props[property].value = this->sc.output_width;
+ break;
+ case VO_PROP_OUTPUT_HEIGHT:
+ this->props[property].value = this->sc.output_height;
+ break;
+ case VO_PROP_OUTPUT_XOFFSET:
+ this->props[property].value = this->sc.output_xoffset;
+ break;
+ case VO_PROP_OUTPUT_YOFFSET:
+ this->props[property].value = this->sc.output_yoffset;
+ break;
}
return this->props[property].value;
diff --git a/src/video_out/video_out_xxmc.c b/src/video_out/video_out_xxmc.c
index 6e99d765c..98ce99f1f 100644
--- a/src/video_out/video_out_xxmc.c
+++ b/src/video_out/video_out_xxmc.c
@@ -1796,6 +1796,18 @@ static int xxmc_get_property (vo_driver_t *this_gen, int property) {
case VO_PROP_WINDOW_HEIGHT:
this->props[property].value = this->sc.gui_height;
break;
+ case VO_PROP_OUTPUT_WIDTH:
+ this->props[property].value = this->sc.output_width;
+ break;
+ case VO_PROP_OUTPUT_HEIGHT:
+ this->props[property].value = this->sc.output_height;
+ break;
+ case VO_PROP_OUTPUT_XOFFSET:
+ this->props[property].value = this->sc.output_xoffset;
+ break;
+ case VO_PROP_OUTPUT_YOFFSET:
+ this->props[property].value = this->sc.output_yoffset;
+ break;
}
lprintf("%s: property #%d = %d\n", LOG_MODULE, property, this->props[property].value);
diff --git a/src/xine-utils/xmllexer.c b/src/xine-utils/xmllexer.c
index e276beef0..df483e9db 100644
--- a/src/xine-utils/xmllexer.c
+++ b/src/xine-utils/xmllexer.c
@@ -144,7 +144,9 @@ typedef enum {
STATE_IDENT /* must be last */
} lexer_state_t;
-int lexer_get_token(char * tok, int tok_size) {
+int lexer_get_token(char ** _tok, int * _tok_size) {
+ char *tok = *_tok;
+ int tok_size = *_tok_size;
int tok_pos = 0;
lexer_state_t state = STATE_IDLE;
char c;
@@ -513,7 +515,15 @@ int lexer_get_token(char * tok, int tok_size) {
/* pb */
if (tok_pos >= tok_size) {
- lprintf("token buffer is too little\n");
+ *_tok_size *= 2;
+ *_tok = realloc (*_tok, *_tok_size);
+ lprintf("token buffer is too small\n");
+ lprintf("increasing buffer size to %d bytes\n", *_tok_size);
+ if (*_tok) {
+ return lexer_get_token (_tok, _tok_size);
+ } else {
+ return T_ERROR;
+ }
} else {
if (lexbuf_pos >= lexbuf_size) {
/* Terminate the current token */
diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c
index 1213072f3..feeb5de65 100644
--- a/src/xine-utils/xmlparser.c
+++ b/src/xine-utils/xmlparser.c
@@ -219,11 +219,14 @@ 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 (xml_node_t *current_node, char *root_names[], int rec, int flags)
+static int xml_parser_get_node_internal (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)
{
- char tok[TOKEN_SIZE];
- char property_name[TOKEN_SIZE];
- char node_name[TOKEN_SIZE];
+ char *tok = *token_buffer;
+ char *property_name = *pname_buffer;
+ char *node_name = *nname_buffer;
parser_state_t state = STATE_IDLE;
int res = 0;
int parse_res;
@@ -236,9 +239,10 @@ static int xml_parser_get_node_internal (xml_node_t *current_node, char *root_na
if (rec < MAX_RECURSION) {
- memset (tok, 0, TOKEN_SIZE);
+ memset (tok, 0, *token_buffer_size);
- while ((bypass_get_token) || (res = lexer_get_token(tok, TOKEN_SIZE)) != T_ERROR) {
+ while ((bypass_get_token) || (res = lexer_get_token(token_buffer, token_buffer_size)) != T_ERROR) {
+ tok = *token_buffer;
bypass_get_token = 0;
lprintf("info: %d - %d : '%s'\n", state, res, tok);
@@ -298,10 +302,15 @@ static int xml_parser_get_node_internal (xml_node_t *current_node, char *root_na
strtoupper(tok);
}
if (state == STATE_Q_NODE) {
- snprintf (node_name, TOKEN_SIZE, "?%s", tok);
+ asprintf (&node_name, "?%s", tok);
+ free (*nname_buffer);
+ *nname_buffer = node_name;
+ *nname_buffer_size = strlen (node_name) + 1;
state = STATE_Q_ATTRIBUTE;
} else {
- strcpy(node_name, tok);
+ free (*nname_buffer);
+ *nname_buffer = node_name = strdup (tok);
+ *nname_buffer_size = strlen (node_name) + 1;
state = STATE_ATTRIBUTE;
}
lprintf("info: current node name \"%s\"\n", node_name);
@@ -329,8 +338,12 @@ static int xml_parser_get_node_internal (xml_node_t *current_node, char *root_na
/* set node propertys */
subtree->props = properties;
lprintf("info: rec %d new subtree %s\n", rec, node_name);
- root_names[rec + 1] = node_name;
- parse_res = xml_parser_get_node_internal(subtree, root_names, rec + 1, flags);
+ root_names[rec + 1] = strdup (node_name);
+ parse_res = xml_parser_get_node_internal (token_buffer, token_buffer_size,
+ pname_buffer, pname_buffer_size,
+ nname_buffer, nname_buffer_size,
+ subtree, root_names, rec + 1, flags);
+ free (root_names[rec + 1]);
if (parse_res == -1 || parse_res > 0) {
return parse_res;
}
@@ -376,6 +389,12 @@ static int xml_parser_get_node_internal (xml_node_t *current_node, char *root_na
if (xml_parser_mode == XML_PARSER_CASE_INSENSITIVE) {
strtoupper(tok);
}
+ /* make sure the buffer for the property name is big enough */
+ if (*token_buffer_size > *pname_buffer_size) {
+ *pname_buffer_size = *token_buffer_size;
+ *pname_buffer = realloc (*pname_buffer, *pname_buffer_size);
+ property_name = *pname_buffer;
+ }
strcpy(property_name, tok);
state = Q_STATE(ATTRIBUTE, ATTRIBUTE_EQUALS);
lprintf("info: current property name \"%s\"\n", property_name);
@@ -622,9 +641,25 @@ static int xml_parser_get_node_internal (xml_node_t *current_node, char *root_na
static int xml_parser_get_node (xml_node_t *current_node, int flags)
{
+ int res = 0;
+ int token_buffer_size = TOKEN_SIZE;
+ int pname_buffer_size = TOKEN_SIZE;
+ int nname_buffer_size = TOKEN_SIZE;
+ char *token_buffer = xine_xmalloc (token_buffer_size);
+ char *pname_buffer = xine_xmalloc (pname_buffer_size);
+ char *nname_buffer = xine_xmalloc (nname_buffer_size);
char *root_names[MAX_RECURSION + 1];
root_names[0] = "";
- return xml_parser_get_node_internal (current_node, root_names, 0, flags);
+ res = xml_parser_get_node_internal (&token_buffer, &token_buffer_size,
+ &pname_buffer, &pname_buffer_size,
+ &nname_buffer, &nname_buffer_size,
+ current_node, root_names, 0, flags);
+
+ free (token_buffer);
+ free (pname_buffer);
+ free (nname_buffer);
+
+ return res;
}
int xml_parser_build_tree_with_options(xml_node_t **root_node, int flags) {