diff options
Diffstat (limited to 'meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base/0002-ssaparse-enhance-SSA-text-lines-parsing.patch')
-rw-r--r-- | meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base/0002-ssaparse-enhance-SSA-text-lines-parsing.patch | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base/0002-ssaparse-enhance-SSA-text-lines-parsing.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base/0002-ssaparse-enhance-SSA-text-lines-parsing.patch new file mode 100644 index 0000000000..e453a500c9 --- /dev/null +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base/0002-ssaparse-enhance-SSA-text-lines-parsing.patch | |||
@@ -0,0 +1,229 @@ | |||
1 | From f587861bbe12ad0b10370f835592746aafedbf56 Mon Sep 17 00:00:00 2001 | ||
2 | From: Mingke Wang <mingke.wang@freescale.com> | ||
3 | Date: Thu, 19 Mar 2015 14:17:10 +0800 | ||
4 | Subject: [PATCH 2/4] ssaparse: enhance SSA text lines parsing. | ||
5 | |||
6 | some parser will pass in the original ssa text line which starts with "Dialog:" | ||
7 | and there's are maybe multiple Dialog lines in one input buffer. | ||
8 | |||
9 | Upstream-Status: Submitted [https://bugzilla.gnome.org/show_bug.cgi?id=747496] | ||
10 | |||
11 | Signed-off-by: Mingke Wang <mingke.wang@freescale.com> | ||
12 | --- | ||
13 | gst/subparse/gstssaparse.c | 150 +++++++++++++++++++++++++++++++++---- | ||
14 | 1 file changed, 134 insertions(+), 16 deletions(-) | ||
15 | mode change 100644 => 100755 gst/subparse/gstssaparse.c | ||
16 | |||
17 | diff --git a/gst/subparse/gstssaparse.c b/gst/subparse/gstssaparse.c | ||
18 | old mode 100644 | ||
19 | new mode 100755 | ||
20 | index c849c08..4b9636c | ||
21 | --- a/gst/subparse/gstssaparse.c | ||
22 | +++ b/gst/subparse/gstssaparse.c | ||
23 | @@ -262,6 +262,7 @@ gst_ssa_parse_remove_override_codes (GstSsaParse * parse, gchar * txt) | ||
24 | * 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 | * | ||
31 | @@ -271,27 +272,133 @@ gst_ssa_parse_remove_override_codes (GstSsaParse * parse, gchar * txt) | ||
32 | * 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)) { | ||
176 | @@ -309,13 +416,22 @@ gst_ssa_parse_push_line (GstSsaParse * parse, gchar * txt, | ||
177 | 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 | |||
203 | @@ -335,6 +451,7 @@ gst_ssa_parse_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * buf) | ||
204 | GstClockTime ts; | ||
205 | gchar *txt; | ||
206 | GstMapInfo map; | ||
207 | + gint size; | ||
208 | |||
209 | if (G_UNLIKELY (!parse->framed)) | ||
210 | goto not_framed; | ||
211 | @@ -352,13 +469,14 @@ gst_ssa_parse_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * buf) | ||
212 | /* 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; | ||
227 | -- | ||
228 | 2.28.0 | ||
229 | |||