gst/subparse/: Fix parsing of tmplayer subtitle variant where every single line contains text and there isn't an empt...

Original commit message from CVS:
* gst/subparse/gstsubparse.c: (handle_buffer),
(gst_sub_parse_sink_event):
* gst/subparse/tmplayerparse.c: (tmplayer_process_buffer),
(tmplayer_parse_line):
Fix parsing of tmplayer subtitle variant where every single line contains
text and there isn't an empty line after each line to determine the
duration (#530962). Improve EOS handling for tmplayer subtitles a bit by
making sure that we push out the last line of text without a duration if
there's still text left in the buffer at the end.
This commit is contained in:
Tim-Philipp Müller 2008-05-03 15:45:23 +00:00
parent ee90cf1969
commit 005c1c8636
3 changed files with 62 additions and 7 deletions

View file

@ -1,3 +1,15 @@
2008-05-03 Tim-Philipp Müller <tim.muller at collabora co uk>
* gst/subparse/gstsubparse.c: (handle_buffer),
(gst_sub_parse_sink_event):
* gst/subparse/tmplayerparse.c: (tmplayer_process_buffer),
(tmplayer_parse_line):
Fix parsing of tmplayer subtitle variant where every single line contains
text and there isn't an empty line after each line to determine the
duration (#530962). Improve EOS handling for tmplayer subtitles a bit by
making sure that we push out the last line of text without a duration if
there's still text left in the buffer at the end.
2008-05-03 Tim-Philipp Müller <tim.muller at collabora co uk>
* gst/subparse/gstsubparse.c: (feed_textbuf):

View file

@ -1093,6 +1093,10 @@ handle_buffer (GstSubParse * self, GstBuffer * buf)
ret = gst_pad_push (self->srcpad, buf);
}
/* move this forward (the tmplayer parser needs this) */
if (self->state.duration != GST_CLOCK_TIME_NONE)
self->state.start_time += self->state.duration;
g_free (subtitle);
subtitle = NULL;
@ -1143,13 +1147,15 @@ gst_sub_parse_sink_event (GstPad * pad, GstEvent * event)
/* Make sure the last subrip chunk is pushed out even
* if the file does not have an empty line at the end */
if (self->parser_type == GST_SUB_PARSE_FORMAT_SUBRIP ||
self->parser_type == GST_SUB_PARSE_FORMAT_TMPLAYER ||
self->parser_type == GST_SUB_PARSE_FORMAT_MPL2) {
GstBuffer *buf = gst_buffer_new_and_alloc (1 + 1);
GstBuffer *buf = gst_buffer_new_and_alloc (2 + 1);
GST_DEBUG ("EOS. Pushing remaining text (if any)");
GST_BUFFER_DATA (buf)[0] = '\n';
GST_BUFFER_DATA (buf)[1] = '\0'; /* play it safe */
GST_BUFFER_SIZE (buf) = 1;
GST_BUFFER_DATA (buf)[1] = '\n';
GST_BUFFER_DATA (buf)[2] = '\0'; /* play it safe */
GST_BUFFER_SIZE (buf) = 2;
GST_BUFFER_OFFSET (buf) = self->offset;
gst_sub_parse_chain (pad, buf);
}

View file

@ -1,5 +1,5 @@
/* GStreamer tmplayer format subtitle parser
* Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
* Copyright (C) 2006-2008 Tim-Philipp Müller <tim centricular net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -55,8 +55,29 @@
* 00:00:53,1=
* 00:00:54,1=a lush and fertile planet.
* 00:00:56,1=
*
* --------------------------------------------------------------------------
*
* And another variety (which is 'time-base 0:00:00:' but without empty lines):
*
* 00:00:01:This is the Earth at a time|when the dinosaurs roamed...
* 00:00:03:a lush and fertile planet.
* 00:00:06:More text here
* 00:00:12:Yet another line
*
*/
static gchar *
tmplayer_process_buffer (ParserState * state)
{
gchar *ret;
ret = g_strndup (state->buf->str, state->buf->len);
g_strdelimit (ret, "|", '\n');
g_string_truncate (state->buf, 0);
return ret;
}
static gchar *
tmplayer_parse_line (ParserState * state, const gchar * line, guint line_num)
{
@ -78,19 +99,34 @@ tmplayer_parse_line (ParserState * state, const gchar * line, guint line_num)
GST_LOG ("single line format %u %u %u %u %c", h, m, s, l, divc);
ts = GST_SECOND * ((((h * 60) + m) * 60) + s);
text_start = strchr (line + 6, divc);
} else if (line[0] == '\0' && state->buf->len > 0 &&
GST_CLOCK_TIME_IS_VALID (state->start_time)) {
/* if we get an empty line (could be the end of the file, but doesn't have
* to be), just push whatever is still in the buffer without a duration */
GST_LOG ("empty line, and there's still text in the buffer");
ret = tmplayer_process_buffer (state);
state->duration = GST_CLOCK_TIME_NONE;
return ret;
} else {
GST_WARNING ("failed to parse line: '%s'", line);
return NULL;
}
/* if this is a line without text, or the first line in a multiline file,
* process and return the data in the buffer, which is the previous line(s) */
if (text_start == NULL || text_start[1] == '\0' ||
(l == 1 && state->buf->len > 0)) {
if (GST_CLOCK_TIME_IS_VALID (state->start_time) &&
state->start_time < ts && line_num > 0) {
ret = g_strndup (state->buf->str, state->buf->len);
g_strdelimit (ret, "|", '\n');
g_string_truncate (state->buf, 0);
ret = tmplayer_process_buffer (state);
state->duration = ts - state->start_time;
/* ..and append current line's text (if there is any) for the next round.
* We don't have to store ts as pending_start_time, since we deduce the
* durations from the start times anyway, so as long as the parser just
* forwards state->start_time by duration after it pushes the line we
* are about to return it will all be good. */
g_string_append (state->buf, text_start + 1);
} else if (line_num > 0) {
GST_WARNING ("end of subtitle unit but no valid start time?!");
}
@ -101,6 +137,7 @@ tmplayer_parse_line (ParserState * state, const gchar * line, guint line_num)
state->start_time = ts;
}
GST_LOG ("returning: '%s'", GST_STR_NULL (ret));
return ret;
}