blob: e453a500c9facff323e15a2ad982eeb3dde731c5 [file] [log] [blame]
Andrew Geissler6ce62a22020-11-30 19:58:47 -06001From f587861bbe12ad0b10370f835592746aafedbf56 Mon Sep 17 00:00:00 2001
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002From: Mingke Wang <mingke.wang@freescale.com>
3Date: Thu, 19 Mar 2015 14:17:10 +0800
Andrew Geissler6ce62a22020-11-30 19:58:47 -06004Subject: [PATCH 2/4] ssaparse: enhance SSA text lines parsing.
Patrick Williamsc124f4f2015-09-15 14:41:29 -05005
6some parser will pass in the original ssa text line which starts with "Dialog:"
7and there's are maybe multiple Dialog lines in one input buffer.
8
9Upstream-Status: Submitted [https://bugzilla.gnome.org/show_bug.cgi?id=747496]
10
11Signed-off-by: Mingke Wang <mingke.wang@freescale.com>
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080012---
Andrew Geissler6ce62a22020-11-30 19:58:47 -060013 gst/subparse/gstssaparse.c | 150 +++++++++++++++++++++++++++++++++----
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080014 1 file changed, 134 insertions(+), 16 deletions(-)
15 mode change 100644 => 100755 gst/subparse/gstssaparse.c
16
Patrick Williamsc124f4f2015-09-15 14:41:29 -050017diff --git a/gst/subparse/gstssaparse.c b/gst/subparse/gstssaparse.c
18old mode 100644
19new mode 100755
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080020index c849c08..4b9636c
Patrick Williamsc124f4f2015-09-15 14:41:29 -050021--- a/gst/subparse/gstssaparse.c
22+++ b/gst/subparse/gstssaparse.c
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080023@@ -262,6 +262,7 @@ gst_ssa_parse_remove_override_codes (GstSsaParse * parse, gchar * txt)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050024 * gst_ssa_parse_push_line:
25 * @parse: caller element
26 * @txt: text to push
27+ * @size: text size need to be parse
28 * @start: timestamp for the buffer
29 * @duration: duration for the buffer
30 *
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080031@@ -271,27 +272,133 @@ gst_ssa_parse_remove_override_codes (GstSsaParse * parse, gchar * txt)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050032 * Returns: result of the push of the created buffer
33 */
34 static GstFlowReturn
35-gst_ssa_parse_push_line (GstSsaParse * parse, gchar * txt,
36+gst_ssa_parse_push_line (GstSsaParse * parse, gchar * txt, gint size,
37 GstClockTime start, GstClockTime duration)
38 {
39 GstFlowReturn ret;
40 GstBuffer *buf;
41- gchar *t, *escaped;
42+ gchar *t, *text, *p, *escaped, *p_start, *p_end;
43 gint num, i, len;
44+ GstClockTime start_time = G_MAXUINT64, end_time = 0;
45
46- num = atoi (txt);
47- GST_LOG_OBJECT (parse, "Parsing line #%d at %" GST_TIME_FORMAT,
48- num, GST_TIME_ARGS (start));
49-
50- /* skip all non-text fields before the actual text */
51+ p = text = g_malloc(size + 1);
52+ *p = '\0';
53 t = txt;
54- for (i = 0; i < 8; ++i) {
55- t = strchr (t, ',');
56+
57+ /* there are may have multiple dialogue lines at a time */
58+ while (*t) {
59+ /* ignore leading white space characters */
60+ while (isspace(*t))
61+ t++;
62+
63+ /* ignore Format: and Style: lines */
64+ if (strncmp(t, "Format:", 7) == 0 || strncmp(t, "Style:", 6) == 0) {
65+ while (*t != '\0' && *t != '\n') {
66+ t++;
67+ }
68+ }
69+
70+ if (*t == '\0')
71+ break;
72+
73+ /* continue with next line */
74+ if (*t == '\n') {
75+ t++;
76+ continue;
77+ }
78+
79+ if(strncmp(t, "Dialogue:", 9) != 0) {
80+ /* not started with "Dialogue:", it must be a line trimmed by demuxer */
81+ num = atoi (t);
82+ GST_LOG_OBJECT (parse, "Parsing line #%d at %" GST_TIME_FORMAT,
83+ num, GST_TIME_ARGS (start));
84+
85+ /* skip all non-text fields before the actual text */
86+ for (i = 0; i < 8; ++i) {
87+ t = strchr (t, ',');
88+ if (t == NULL)
89+ break;
90+ ++t;
91+ }
92+ } else {
93+ /* started with "Dialogue:", update timestamp and duration */
94+ /* time format are like Dialog:Mark,0:00:01.02,0:00:03.04,xx,xxx,... */
95+ guint hour, min, sec, msec, len;
96+ GstClockTime tmp;
97+ gchar t_str[12] = {0};
98+
99+ /* find the first ',' */
100+ p_start = strchr (t, ',');
101+ if (p_start)
102+ p_end = strchr (++p_start, ',');
103+
104+ if (p_start && p_end) {
105+ /* copy text between first ',' and second ',' */
106+ strncpy(t_str, p_start, p_end - p_start);
107+ if (sscanf (t_str, "%u:%u:%u.%u", &hour, &min, &sec, &msec) == 4) {
108+ tmp = ((hour*3600) + (min*60) + sec) * GST_SECOND + msec*GST_MSECOND;
109+ GST_DEBUG_OBJECT (parse, "Get start time:%02d:%02d:%02d:%03d\n",
110+ hour, min, sec, msec);
111+ if (start_time > tmp)
112+ start_time = tmp;
113+ } else {
114+ GST_WARNING_OBJECT (parse,
115+ "failed to parse ssa start timestamp string :%s", t_str);
116+ }
117+
118+ p_start = p_end;
119+ p_end = strchr (++p_start, ',');
120+ if (p_end) {
121+ /* copy text between second ',' and third ',' */
122+ strncpy(t_str, p_start, p_end - p_start);
123+ if (sscanf (t_str, "%u:%u:%u.%u", &hour, &min, &sec, &msec) == 4) {
124+ tmp = ((hour*3600) + (min*60) + sec)*GST_SECOND + msec*GST_MSECOND;
125+ GST_DEBUG_OBJECT(parse, "Get end time:%02d:%02d:%02d:%03d\n",
126+ hour, min, sec, msec);
127+ if (end_time < tmp)
128+ end_time = tmp;
129+ } else {
130+ GST_WARNING_OBJECT (parse,
131+ "failed to parse ssa end timestamp string :%s", t_str);
132+ }
133+ }
134+ }
135+
136+ /* now skip all non-text fields before the actual text */
137+ for (i = 0; i <= 8; ++i) {
138+ t = strchr (t, ',');
139+ if (t == NULL)
140+ break;
141+ ++t;
142+ }
143+ }
144+
145+ /* line end before expected number of ',', not a Dialogue line */
146 if (t == NULL)
147- return GST_FLOW_ERROR;
148- ++t;
149+ break;
150+
151+ /* if not the first line, and the last character of previous line is '\0',
152+ * then replace it with '\N' */
153+ if (p != text && *p == '\0') {
154+ *p++ = '\\';
155+ *p++ = 'N';
156+ }
157+
158+ /* copy all actual text of this line */
159+ while ((*t != '\0') && (*t != '\n'))
160+ *p++ = *t++;
161+
162+ /* add a terminator at the end */
163+ *p = '\0';
164+ }
165+
166+ /* not valid text found in this buffer return OK to let caller unref buffer */
167+ if (strlen(text) <= 0) {
168+ GST_WARNING_OBJECT (parse, "Not valid text found in this buffer\n");
169+ return GST_FLOW_ERROR;
170 }
171
172+ t = text;
173 GST_LOG_OBJECT (parse, "Text : %s", t);
174
175 if (gst_ssa_parse_remove_override_codes (parse, t)) {
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800176@@ -309,13 +416,22 @@ gst_ssa_parse_push_line (GstSsaParse * parse, gchar * txt,
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500177 gst_buffer_fill (buf, 0, escaped, len + 1);
178 gst_buffer_set_size (buf, len);
179 g_free (escaped);
180+ g_free(t);
181+
182+ if (start_time != G_MAXUINT64)
183+ GST_BUFFER_TIMESTAMP (buf) = start_time;
184+ else
185+ GST_BUFFER_TIMESTAMP (buf) = start;
186
187- GST_BUFFER_TIMESTAMP (buf) = start;
188- GST_BUFFER_DURATION (buf) = duration;
189+ if (end_time > start_time)
190+ GST_BUFFER_DURATION (buf) = end_time - start_time;
191+ else
192+ GST_BUFFER_DURATION (buf) = duration;
193
194 GST_LOG_OBJECT (parse, "Pushing buffer with timestamp %" GST_TIME_FORMAT
195- " and duration %" GST_TIME_FORMAT, GST_TIME_ARGS (start),
196- GST_TIME_ARGS (duration));
197+ " and duration %" GST_TIME_FORMAT,
198+ GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
199+ GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
200
201 ret = gst_pad_push (parse->srcpad, buf);
202
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800203@@ -335,6 +451,7 @@ gst_ssa_parse_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * buf)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500204 GstClockTime ts;
205 gchar *txt;
206 GstMapInfo map;
207+ gint size;
208
209 if (G_UNLIKELY (!parse->framed))
210 goto not_framed;
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800211@@ -352,13 +469,14 @@ gst_ssa_parse_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * buf)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500212 /* make double-sure it's 0-terminated and all */
213 gst_buffer_map (buf, &map, GST_MAP_READ);
214 txt = g_strndup ((gchar *) map.data, map.size);
215+ size = map.size;
216 gst_buffer_unmap (buf, &map);
217
218 if (txt == NULL)
219 goto empty_text;
220
221 ts = GST_BUFFER_TIMESTAMP (buf);
222- ret = gst_ssa_parse_push_line (parse, txt, ts, GST_BUFFER_DURATION (buf));
223+ ret = gst_ssa_parse_push_line (parse, txt, size, ts, GST_BUFFER_DURATION (buf));
224
225 if (ret != GST_FLOW_OK && GST_CLOCK_TIME_IS_VALID (ts)) {
226 GstSegment segment;
Andrew Geissler6ce62a22020-11-30 19:58:47 -0600227--
2282.28.0
229