gst_plugins_base/gst/subparse/tmplayerparse.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
     1 /* GStreamer tmplayer format subtitle parser
     1 /* GStreamer tmplayer format subtitle parser
     2  * Copyright (C) 2006-2008 Tim-Philipp Müller <tim centricular net>
     2  * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
     3  *
     3  *
     4  * This library is free software; you can redistribute it and/or
     4  * This library is free software; you can redistribute it and/or
     5  * modify it under the terms of the GNU Library General Public
     5  * modify it under the terms of the GNU Library General Public
     6  * License as published by the Free Software Foundation; either
     6  * License as published by the Free Software Foundation; either
     7  * version 2 of the License, or (at your option) any later version.
     7  * version 2 of the License, or (at your option) any later version.
    53  * 00:00:50,1=This is the Earth at a time
    53  * 00:00:50,1=This is the Earth at a time
    54  * 00:00:50,2=when the dinosaurs roamed...
    54  * 00:00:50,2=when the dinosaurs roamed...
    55  * 00:00:53,1=
    55  * 00:00:53,1=
    56  * 00:00:54,1=a lush and fertile planet.
    56  * 00:00:54,1=a lush and fertile planet.
    57  * 00:00:56,1=
    57  * 00:00:56,1=
    58  *
       
    59  * --------------------------------------------------------------------------
       
    60  *
       
    61  * And another variety (which is 'time-base 0:00:00:' but without empty lines):
       
    62  *
       
    63  * 00:00:01:This is the Earth at a time|when the dinosaurs roamed...
       
    64  * 00:00:03:a lush and fertile planet.
       
    65  * 00:00:06:More text here
       
    66  * 00:00:12:Yet another line
       
    67  *
       
    68  */
    58  */
    69 
       
    70 static gchar *
       
    71 tmplayer_process_buffer (ParserState * state)
       
    72 {
       
    73   gchar *ret;
       
    74 
       
    75   ret = g_strndup (state->buf->str, state->buf->len);
       
    76   g_strdelimit (ret, "|", '\n');
       
    77   g_string_truncate (state->buf, 0);
       
    78   return ret;
       
    79 }
       
    80 
    59 
    81 static gchar *
    60 static gchar *
    82 tmplayer_parse_line (ParserState * state, const gchar * line, guint line_num)
    61 tmplayer_parse_line (ParserState * state, const gchar * line, guint line_num)
    83 {
    62 {
    84   GstClockTime ts = GST_CLOCK_TIME_NONE;
    63   GstClockTime ts = GST_CLOCK_TIME_NONE;
    97   } else if (sscanf (line, "%u:%02u:%02u%c", &h, &m, &s, &divc) == 4 &&
    76   } else if (sscanf (line, "%u:%02u:%02u%c", &h, &m, &s, &divc) == 4 &&
    98       (divc == '=' || divc == ':')) {
    77       (divc == '=' || divc == ':')) {
    99     GST_LOG ("single line format %u %u %u %u %c", h, m, s, l, divc);
    78     GST_LOG ("single line format %u %u %u %u %c", h, m, s, l, divc);
   100     ts = GST_SECOND * ((((h * 60) + m) * 60) + s);
    79     ts = GST_SECOND * ((((h * 60) + m) * 60) + s);
   101     text_start = strchr (line + 6, divc);
    80     text_start = strchr (line + 6, divc);
   102   } else if (line[0] == '\0' && state->buf->len > 0 &&
       
   103       GST_CLOCK_TIME_IS_VALID (state->start_time)) {
       
   104     /* if we get an empty line (could be the end of the file, but doesn't have
       
   105      * to be), just push whatever is still in the buffer without a duration */
       
   106     GST_LOG ("empty line, and there's still text in the buffer");
       
   107     ret = tmplayer_process_buffer (state);
       
   108     state->duration = GST_CLOCK_TIME_NONE;
       
   109     return ret;
       
   110   } else {
    81   } else {
   111     GST_WARNING ("failed to parse line: '%s'", line);
    82     GST_WARNING ("failed to parse line: '%s'", line);
   112     return NULL;
    83     return NULL;
   113   }
    84   }
   114 
    85 
   115   /* if this is a line without text, or the first line in a multiline file,
       
   116    * process and return the data in the buffer, which is the previous line(s) */
       
   117   if (text_start == NULL || text_start[1] == '\0' ||
    86   if (text_start == NULL || text_start[1] == '\0' ||
   118       (l == 1 && state->buf->len > 0)) {
    87       (l == 1 && state->buf->len > 0)) {
   119 
       
   120     if (GST_CLOCK_TIME_IS_VALID (state->start_time) &&
    88     if (GST_CLOCK_TIME_IS_VALID (state->start_time) &&
   121         state->start_time < ts && line_num > 0) {
    89         state->start_time < ts && line_num > 0) {
   122       ret = tmplayer_process_buffer (state);
    90       ret = g_strndup (state->buf->str, state->buf->len);
       
    91       g_strdelimit (ret, "|", '\n');
       
    92       g_string_truncate (state->buf, 0);
   123       state->duration = ts - state->start_time;
    93       state->duration = ts - state->start_time;
   124       /* ..and append current line's text (if there is any) for the next round.
       
   125        * We don't have to store ts as pending_start_time, since we deduce the
       
   126        * durations from the start times anyway, so as long as the parser just
       
   127        * forwards state->start_time by duration after it pushes the line we
       
   128        * are about to return it will all be good. */
       
   129       g_string_append (state->buf, text_start + 1);
       
   130     } else if (line_num > 0) {
    94     } else if (line_num > 0) {
   131       GST_WARNING ("end of subtitle unit but no valid start time?!");
    95       GST_WARNING ("end of subtitle unit but no valid start time?!");
   132     }
    96     }
   133   } else {
    97   } else {
   134     if (l > 1)
    98     if (l > 1)
   135       g_string_append_c (state->buf, '\n');
    99       g_string_append_c (state->buf, '\n');
   136     g_string_append (state->buf, text_start + 1);
   100     g_string_append (state->buf, text_start + 1);
   137     state->start_time = ts;
   101     state->start_time = ts;
   138   }
   102   }
   139 
   103 
   140   GST_LOG ("returning: '%s'", GST_STR_NULL (ret));
       
   141   return ret;
   104   return ret;
   142 }
   105 }
   143 #ifdef __SYMBIAN32__
   106 #ifdef __SYMBIAN32__
   144 EXPORT_C
   107 EXPORT_C
   145 #endif
   108 #endif