gst/subparse/gstsubparse.*: Remove spurious 1000 subtrahend when calculating the...
authorTim-Philipp Müller <tim@centricular.net>
Mon, 8 Jan 2007 12:30:03 +0000 (12:30 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Mon, 8 Jan 2007 12:30:03 +0000 (12:30 +0000)
Original commit message from CVS:
* gst/subparse/gstsubparse.c: (parse_mdvdsub):
* gst/subparse/gstsubparse.h:
Remove spurious 1000 subtrahend when calculating the timestamp from
the frame number and the frame rate . Also, use the frames/second
value specified in the first line of the file, if one is specified
there. Should fix #357503.
* tests/check/elements/subparse.c: (do_test),
(test_tmplayer_do_test), (test_microdvd_do_test), (GST_START_TEST),
(subparse_suite):
Add some basic unit tests for the microdvd subtitle format.

ChangeLog
common
gst/subparse/gstsubparse.c
gst/subparse/gstsubparse.h
tests/check/elements/subparse.c

index 8b5899f..605e5b0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2007-01-08  Tim-Philipp Müller  <tim at centricular dot net>
+
+       * gst/subparse/gstsubparse.c: (parse_mdvdsub):
+       * gst/subparse/gstsubparse.h:
+         Remove spurious 1000 subtrahend when calculating the timestamp from
+         the frame number and the frame rate . Also, use the frames/second
+         value specified in the first line of the file, if one is specified
+         there. Should fix #357503.
+
+       * tests/check/elements/subparse.c: (do_test),
+       (test_tmplayer_do_test), (test_microdvd_do_test), (GST_START_TEST),
+       (subparse_suite):
+         Add some basic unit tests for the microdvd subtitle format.
+
 2007-01-07  Julien MOUTTE  <julien@moutte.net>
 
        * sys/xvimage/xvimagesink.c: (gst_xvimage_buffer_destroy),
diff --git a/common b/common
index 64f924f..8ba5dff 160000 (submodule)
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit 64f924f6f2ff6275b06facb4c2adbc7c05f70641
+Subproject commit 8ba5dffb5ee7e7daea1030f6b34bfef10f9801a3
index 713b96c..779e728 100644 (file)
@@ -396,10 +396,6 @@ parse_mdvdsub (ParserState * state, const gchar * line)
   guint start_frame, end_frame;
   gint64 clip_start = 0, clip_stop = 0;
   gboolean in_seg = FALSE;
-
-  /* FIXME: hardcoded for now, but detecting the correct value is
-   * not going to be easy, I suspect... */
-  const double frames_per_sec = 24000 / 1001.;
   GString *markup;
   gchar *ret;
 
@@ -414,8 +410,32 @@ parse_mdvdsub (ParserState * state, const gchar * line)
     return NULL;
   }
 
-  state->start_time = (start_frame - 1000) / frames_per_sec * GST_SECOND;
-  state->duration = (end_frame - start_frame) / frames_per_sec * GST_SECOND;
+  /* skip the {%u}{%u} part */
+  line = strchr (line, '}') + 1;
+  line = strchr (line, '}') + 1;
+
+  /* see if there's a first line with a framerate */
+  if (state->fps == 0.0 && start_frame == 1 && end_frame == 1) {
+    gchar *rest, *end = NULL;
+
+    rest = g_strdup (line);
+    g_strdelimit (rest, ",", '.');
+    state->fps = g_ascii_strtod (rest, &end);
+    if (end == rest)
+      state->fps = 0.0;
+    GST_INFO ("framerate from file: %f ('%s')", state->fps, rest);
+    g_free (rest);
+    return NULL;
+  }
+
+  if (state->fps == 0.0) {
+    /* FIXME: hardcoded for now, is there a better way/assumption? */
+    state->fps = 24000.0 / 1001.0;
+    GST_INFO ("no framerate specified, assuming %f", state->fps);
+  }
+
+  state->start_time = start_frame / state->fps * GST_SECOND;
+  state->duration = (end_frame - start_frame) / state->fps * GST_SECOND;
 
   /* Check our segment start/stop */
   in_seg = gst_segment_clip (state->segment, GST_FORMAT_TIME,
@@ -430,10 +450,6 @@ parse_mdvdsub (ParserState * state, const gchar * line)
     return NULL;
   }
 
-  /* skip the {%u}{%u} part */
-  line = strchr (line, '}') + 1;
-  line = strchr (line, '}') + 1;
-
   markup = g_string_new (NULL);
   while (1) {
     italic = FALSE;
index 8999d42..c9feede 100644 (file)
@@ -60,6 +60,7 @@ typedef struct {
   guint64  duration;
   GstSegment *segment;
   gpointer user_data;
+  gdouble  fps;          /* used by microdvd parser */
 } ParserState;
 
 typedef gchar* (*Parser) (ParserState *state, const gchar *line);
index 77bd4b1..3cd7d3b 100644 (file)
@@ -24,6 +24,8 @@
 
 #include <gst/check/gstcheck.h>
 
+#include <string.h>
+
 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
@@ -205,7 +207,7 @@ GST_START_TEST (test_srt)
 GST_END_TEST;
 
 static void
-test_tmplayer_do_test (SubParseInputChunk * input, guint num)
+do_test (SubParseInputChunk * input, guint num, const gchar * media_type)
 {
   guint n;
 
@@ -249,12 +251,24 @@ test_tmplayer_do_test (SubParseInputChunk * input, guint num)
     fail_unless (GST_BUFFER_CAPS (buf) != NULL);
     buffer_caps_struct = gst_caps_get_structure (GST_BUFFER_CAPS (buf), 0);
     fail_unless_equals_string (gst_structure_get_name (buffer_caps_struct),
-        "text/plain");
+        media_type);
   }
 
   teardown_subparse ();
 }
 
+static void
+test_tmplayer_do_test (SubParseInputChunk * input, guint num)
+{
+  do_test (input, num, "text/plain");
+}
+
+static void
+test_microdvd_do_test (SubParseInputChunk * input, guint num)
+{
+  do_test (input, num, "text/x-pango-markup");
+}
+
 GST_START_TEST (test_tmplayer_multiline)
 {
   static SubParseInputChunk tmplayer_multiline_input[] = {
@@ -392,6 +406,30 @@ GST_START_TEST (test_tmplayer_style4_with_bogus_lines)
 
 GST_END_TEST;
 
+GST_START_TEST (test_microdvd_with_fps)
+{
+  static SubParseInputChunk microdvd_input[] = {
+    {
+          "{1}{1}12.500\n{100}{200}- Hi, Eddie.|- Hiya, Scotty.\n",
+          8 * GST_SECOND, 16 * GST_SECOND,
+        "<span>- Hi, Eddie.</span>\n<span>- Hiya, Scotty.</span>"}, {
+          "{1250}{1350}- Cold enough for you?|- Well, I'm only faintly alive. "
+          "It's 25 below\n",
+          100 * GST_SECOND, 108 * GST_SECOND,
+        "<span>- Cold enough for you?</span>\n"
+          "<span>- Well, I&apos;m only faintly alive. It&apos;s 25 below</span>"}
+  };
+
+  test_microdvd_do_test (microdvd_input, G_N_ELEMENTS (microdvd_input));
+
+  /* and the same with ',' instead of '.' as floating point divider */
+  microdvd_input[0].in =
+      "{1}{1}12,500\n{100}{200}- Hi, Eddie.|- Hiya, Scotty.\n";
+  test_microdvd_do_test (microdvd_input, G_N_ELEMENTS (microdvd_input));
+}
+
+GST_END_TEST;
+
 /* TODO:
  *  - add/modify tests so that lines aren't dogfed to the parsers in complete
  *    lines or sets of complete lines, but rather in random chunks
@@ -413,6 +451,7 @@ subparse_suite (void)
   tcase_add_test (tc_chain, test_tmplayer_style3);
   tcase_add_test (tc_chain, test_tmplayer_style4);
   tcase_add_test (tc_chain, test_tmplayer_style4_with_bogus_lines);
+  tcase_add_test (tc_chain, test_microdvd_with_fps);
   return s;
 }