mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
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:
parent
ee90cf1969
commit
005c1c8636
3 changed files with 62 additions and 7 deletions
12
ChangeLog
12
ChangeLog
|
@ -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>
|
2008-05-03 Tim-Philipp Müller <tim.muller at collabora co uk>
|
||||||
|
|
||||||
* gst/subparse/gstsubparse.c: (feed_textbuf):
|
* gst/subparse/gstsubparse.c: (feed_textbuf):
|
||||||
|
|
|
@ -1093,6 +1093,10 @@ handle_buffer (GstSubParse * self, GstBuffer * buf)
|
||||||
ret = gst_pad_push (self->srcpad, 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);
|
g_free (subtitle);
|
||||||
subtitle = NULL;
|
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
|
/* Make sure the last subrip chunk is pushed out even
|
||||||
* if the file does not have an empty line at the end */
|
* if the file does not have an empty line at the end */
|
||||||
if (self->parser_type == GST_SUB_PARSE_FORMAT_SUBRIP ||
|
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) {
|
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_DEBUG ("EOS. Pushing remaining text (if any)");
|
||||||
GST_BUFFER_DATA (buf)[0] = '\n';
|
GST_BUFFER_DATA (buf)[0] = '\n';
|
||||||
GST_BUFFER_DATA (buf)[1] = '\0'; /* play it safe */
|
GST_BUFFER_DATA (buf)[1] = '\n';
|
||||||
GST_BUFFER_SIZE (buf) = 1;
|
GST_BUFFER_DATA (buf)[2] = '\0'; /* play it safe */
|
||||||
|
GST_BUFFER_SIZE (buf) = 2;
|
||||||
GST_BUFFER_OFFSET (buf) = self->offset;
|
GST_BUFFER_OFFSET (buf) = self->offset;
|
||||||
gst_sub_parse_chain (pad, buf);
|
gst_sub_parse_chain (pad, buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* GStreamer tmplayer format subtitle parser
|
/* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -55,8 +55,29 @@
|
||||||
* 00:00:53,1=
|
* 00:00:53,1=
|
||||||
* 00:00:54,1=a lush and fertile planet.
|
* 00:00:54,1=a lush and fertile planet.
|
||||||
* 00:00:56,1=
|
* 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 *
|
static gchar *
|
||||||
tmplayer_parse_line (ParserState * state, const gchar * line, guint line_num)
|
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);
|
GST_LOG ("single line format %u %u %u %u %c", h, m, s, l, divc);
|
||||||
ts = GST_SECOND * ((((h * 60) + m) * 60) + s);
|
ts = GST_SECOND * ((((h * 60) + m) * 60) + s);
|
||||||
text_start = strchr (line + 6, divc);
|
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 {
|
} else {
|
||||||
GST_WARNING ("failed to parse line: '%s'", line);
|
GST_WARNING ("failed to parse line: '%s'", line);
|
||||||
return NULL;
|
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' ||
|
if (text_start == NULL || text_start[1] == '\0' ||
|
||||||
(l == 1 && state->buf->len > 0)) {
|
(l == 1 && state->buf->len > 0)) {
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (state->start_time) &&
|
if (GST_CLOCK_TIME_IS_VALID (state->start_time) &&
|
||||||
state->start_time < ts && line_num > 0) {
|
state->start_time < ts && line_num > 0) {
|
||||||
ret = g_strndup (state->buf->str, state->buf->len);
|
ret = tmplayer_process_buffer (state);
|
||||||
g_strdelimit (ret, "|", '\n');
|
|
||||||
g_string_truncate (state->buf, 0);
|
|
||||||
state->duration = ts - state->start_time;
|
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) {
|
} else if (line_num > 0) {
|
||||||
GST_WARNING ("end of subtitle unit but no valid start time?!");
|
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;
|
state->start_time = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_LOG ("returning: '%s'", GST_STR_NULL (ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue