+2007-03-10 Tim-Philipp Müller <tim at centricular dot net>
+
+ Patch by: Kamil Pawlowski <kamilpe gmail com>
+
+ * gst/subparse/Makefile.am:
+ * gst/subparse/gstsubparse.c:
+ (gst_sub_parse_data_format_autodetect),
+ (gst_sub_parse_format_autodetect), (gst_sub_parse_sink_event),
+ (gst_subparse_type_find):
+ * gst/subparse/gstsubparse.h:
+ * gst/subparse/mpl2parse.c: (mpl2_parse_line), (parse_mpl2):
+ * gst/subparse/mpl2parse.h:
+ Add support for MPL2 subtitle format (#413799).
+
2007-03-09 Tim-Philipp Müller <tim at centricular dot net>
* configure.ac:
-Subproject commit ea828a478fe11561881a6eaf1f7bf2b0b77c8c85
+Subproject commit dec151d15512e4cca2dcdd36d9c6c4a2185760ec
samiparse.c \
samiparse.h \
tmplayerparse.c \
- tmplayerparse.h
+ tmplayerparse.h \
+ mpl2parse.c \
+ mpl2parse.h
libgstsubparse_la_CFLAGS = $(GST_CFLAGS)
libgstsubparse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
gstssaparse.h \
gstsubparse.h \
samiparse.h \
- tmplayerparse.h
+ tmplayerparse.h \
+ mpl2parse.h
#include "gstssaparse.h"
#include "samiparse.h"
#include "tmplayerparse.h"
+#include "mpl2parse.h"
GST_DEBUG_CATEGORY (sub_parse_debug);
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("application/x-subtitle; application/x-subtitle-sami; "
- "application/x-subtitle-tmplayer")
+ "application/x-subtitle-tmplayer; application/x-subtitle-mpl2")
);
#else
static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
GST_LOG ("TMPlayer (time based) format detected");
return GST_SUB_PARSE_FORMAT_TMPLAYER;
}
-
+ if (sscanf (match_str, "[%u][%u]", &n1, &n2) == 2) {
+ GST_LOG ("MPL2 (time based) format detected");
+ return GST_SUB_PARSE_FORMAT_MPL2;
+ }
GST_DEBUG ("no subtitle format detected");
return GST_SUB_PARSE_FORMAT_UNKNOWN;
}
case GST_SUB_PARSE_FORMAT_TMPLAYER:
self->parse_line = parse_tmplayer;
return gst_caps_new_simple ("text/plain", NULL);
+ case GST_SUB_PARSE_FORMAT_MPL2:
+ self->parse_line = parse_mpl2;
+ return gst_caps_new_simple ("text/x-pango-markup", NULL);
case GST_SUB_PARSE_FORMAT_UNKNOWN:
default:
GST_DEBUG ("no subtitle format detected");
case GST_EVENT_EOS:{
/* 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) {
+ if (self->parser_type == GST_SUB_PARSE_FORMAT_SUBRIP ||
+ self->parser_type == GST_SUB_PARSE_FORMAT_MPL2) {
GstBuffer *buf = gst_buffer_new_and_alloc (1 + 1);
GST_DEBUG ("EOS. Pushing remaining text (if any)");
/* FIXME 0.11: these caps are ugly, use app/x-subtitle + type field or so;
* also, give different subtitle formats really different types */
+static GstStaticCaps mpl2_caps =
+GST_STATIC_CAPS ("application/x-subtitle-mpl2");
static GstStaticCaps tmp_caps =
GST_STATIC_CAPS ("application/x-subtitle-tmplayer");
static GstStaticCaps smi_caps = GST_STATIC_CAPS ("application/x-subtitle-sami");
#define SUB_CAPS (gst_static_caps_get (&sub_caps))
#define SAMI_CAPS (gst_static_caps_get (&smi_caps))
#define TMP_CAPS (gst_static_caps_get (&tmp_caps))
+#define MPL2_CAPS (gst_static_caps_get (&mpl2_caps))
static void
gst_subparse_type_find (GstTypeFind * tf, gpointer private)
GST_DEBUG ("TMPlayer (time based) format detected");
caps = TMP_CAPS;
break;
+ /* FIXME: our MPL2 typefinding is not really good enough to warrant
+ * returning a high probability (however, since we registered our
+ * typefinder here with a rank of MARGINAL we should pretty much only
+ * be called if most other typefinders have already run */
+ case GST_SUB_PARSE_FORMAT_MPL2:
+ GST_DEBUG ("MPL2 (time based) format detected");
+ caps = MPL2_CAPS;
+ break;
default:
case GST_SUB_PARSE_FORMAT_UNKNOWN:
GST_DEBUG ("no subtitle format detected");
GST_SUB_PARSE_FORMAT_SUBRIP = 2,
GST_SUB_PARSE_FORMAT_MPSUB = 3,
GST_SUB_PARSE_FORMAT_SAMI = 4,
- GST_SUB_PARSE_FORMAT_TMPLAYER = 5
+ GST_SUB_PARSE_FORMAT_TMPLAYER = 5,
+ GST_SUB_PARSE_FORMAT_MPL2 = 6
} GstSubParseFormat;
typedef struct {
--- /dev/null
+/* GStreamer mpl2 format subtitle parser
+ * Copyright (C) 2006 Kamil Pawlowski <kamilpe gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mpl2parse.h"
+
+#include <string.h>
+
+/* From http://lists.mplayerhq.hu/pipermail/mplayer-users/2003-February/030222.html
+ *
+ * [123][456] Sample subtitle
+ * [1234][5678] Line 1|Line 2
+ * [12345][67890] /Italic|Normal
+ * [12345][67890] /Italic|/Italic
+ * [12345][67890] Normal|/Italic
+ *
+ * (The space between the last ']' bracket and the text appears to be optional)
+ */
+
+static gchar *
+mpl2_parse_line (ParserState * state, const gchar * line, guint line_num)
+{
+ GString *markup;
+ gint dc_start, dc_stop;
+
+ /* parse subtitle file line */
+ if (sscanf (line, "[%u][%u]", &dc_start, &dc_stop) != 2) {
+ GST_WARNING ("failed to extract timestamps for line '%s'", line);
+ return NULL;
+ }
+
+ GST_LOG ("line format %u %u", dc_start, dc_stop);
+ state->start_time = GST_SECOND / 10 * dc_start;
+ state->duration = (GST_SECOND / 10 * dc_stop) - state->start_time;
+
+ /* skip brackets with timestamps */
+ line = strchr (line, ']') + 1;
+ line = strchr (line, ']') + 1;
+
+ markup = g_string_new (NULL);
+
+ while (1) {
+ const gchar *format_string;
+ const gchar *sep;
+ gchar *line_chunk_escaped;
+
+ /* skip leading white spaces */
+ while (*line == ' ' || *line == '\t')
+ ++line;
+
+ /* a '/' at the beginning indicates italics */
+ if (*line == '/') {
+ format_string = "<i>%s</i>";
+ ++line;
+ } else {
+ format_string = "%s";
+ }
+
+ if ((sep = strchr (line, '|')))
+ line_chunk_escaped = g_markup_escape_text (line, sep - line);
+ else
+ line_chunk_escaped = g_markup_escape_text (line, -1);
+
+ GST_LOG ("escaped line: %s", line_chunk_escaped);
+ g_string_append_printf (markup, format_string, line_chunk_escaped);
+
+ g_free (line_chunk_escaped);
+
+ if (sep == NULL)
+ break;
+
+ /* move after the '|' and append another line */
+ g_string_append (markup, "\n");
+ line = sep + 1;
+ }
+
+ return g_strstrip (g_string_free (markup, FALSE));
+}
+
+gchar *
+parse_mpl2 (ParserState * state, const gchar * line)
+{
+ gchar *ret;
+
+ ret = mpl2_parse_line (state, line, state->state);
+ ++state->state;
+ return ret;
+}
--- /dev/null
+/* GStreamer mpl2 format subtitle parser
+ * Copyright (C) 2006 Kamil Pawlowski <kamilpe gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MPL2_PARSE_H_
+#define _MPL2_PARSE_H_
+
+#include "gstsubparse.h"
+
+G_BEGIN_DECLS
+
+gchar * parse_mpl2 (ParserState * state, const gchar * line);
+
+G_END_DECLS
+
+#endif /* _MPL2_PARSE_H_ */
+