[meta-freescale] [meta-fsl-arm][PATCH v4 2/4] gstreamer1.0-plugins-base: Add ssaparse related patch

Carlos Rafael Giani dv at pseudoterminal.org
Wed Aug 5 13:36:36 PDT 2015


Is this also marked i.MX specific because it is still under discussion 
with the community? Do you have a link to the discussion in Bugzilla? If 
so, use "Upstream-Status: Submitted [<Bugzilla link>]" instead.

Am 2015-07-30 um 20:55 schrieb Yuqing Zhu:
> Enhance SSA text lines parsing.
>
> Signed-off-by: Yuqing Zhu <b54851 at freescale.com>
> ---
>   ...3-ssaparse-enhance-SSA-text-lines-parsing.patch | 225 +++++++++++++++++++++
>   .../gstreamer/gstreamer1.0-plugins-base_%.bbappend |   4 +-
>   2 files changed, 228 insertions(+), 1 deletion(-)
>   create mode 100644 recipes-multimedia/gstreamer/gstreamer1.0-plugins-base/0003-ssaparse-enhance-SSA-text-lines-parsing.patch
>
> diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base/0003-ssaparse-enhance-SSA-text-lines-parsing.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base/0003-ssaparse-enhance-SSA-text-lines-parsing.patch
> new file mode 100644
> index 0000000..7666998
> --- /dev/null
> +++ b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base/0003-ssaparse-enhance-SSA-text-lines-parsing.patch
> @@ -0,0 +1,225 @@
> +From be6163cfa3a255493f9d75bad9541cbfe1723fee Mon Sep 17 00:00:00 2001
> +From: Mingke Wang <mingke.wang at freescale.com>
> +Date: Thu, 19 Mar 2015 14:17:10 +0800
> +Subject: [PATCH 3/4] ssaparse: enhance SSA text lines parsing.
> +
> +some parser will pass in the original ssa text line which starts with "Dialog:"
> +and there's are maybe multiple Dialog lines in one input buffer.
> +
> +Upstream-Status: Inappropriate [i.MX specific]
> +
> +Signed-off-by: Mingke Wang <mingke.wang at freescale.com>
> +
> +diff --git a/gst/subparse/gstssaparse.c b/gst/subparse/gstssaparse.c
> +old mode 100644
> +new mode 100755
> +index 06ecef9..0ab5dce
> +--- a/gst/subparse/gstssaparse.c
> ++++ b/gst/subparse/gstssaparse.c
> +@@ -260,6 +260,7 @@ gst_ssa_parse_remove_override_codes (GstSsaParse * parse, gchar * txt)
> +  * gst_ssa_parse_push_line:
> +  * @parse: caller element
> +  * @txt: text to push
> ++ * @size: text size need to be parse
> +  * @start: timestamp for the buffer
> +  * @duration: duration for the buffer
> +  *
> +@@ -269,27 +270,133 @@ gst_ssa_parse_remove_override_codes (GstSsaParse * parse, gchar * txt)
> +  * Returns: result of the push of the created buffer
> +  */
> + static GstFlowReturn
> +-gst_ssa_parse_push_line (GstSsaParse * parse, gchar * txt,
> ++gst_ssa_parse_push_line (GstSsaParse * parse, gchar * txt, gint size,
> +     GstClockTime start, GstClockTime duration)
> + {
> +   GstFlowReturn ret;
> +   GstBuffer *buf;
> +-  gchar *t, *escaped;
> ++  gchar *t, *text, *p, *escaped, *p_start, *p_end;
> +   gint num, i, len;
> ++  GstClockTime start_time = G_MAXUINT64, end_time = 0;
> +
> +-  num = atoi (txt);
> +-  GST_LOG_OBJECT (parse, "Parsing line #%d at %" GST_TIME_FORMAT,
> +-      num, GST_TIME_ARGS (start));
> +-
> +-  /* skip all non-text fields before the actual text */
> ++  p = text = g_malloc(size + 1);
> ++  *p = '\0';
> +   t = txt;
> +-  for (i = 0; i < 8; ++i) {
> +-    t = strchr (t, ',');
> ++
> ++  /* there are may have multiple dialogue lines at a time */
> ++  while (*t) {
> ++    /* ignore leading white space characters */
> ++    while (isspace(*t))
> ++      t++;
> ++
> ++    /* ignore Format: and Style: lines */
> ++    if (strncmp(t, "Format:", 7) == 0 || strncmp(t, "Style:", 6) == 0) {
> ++      while (*t != '\0' && *t != '\n') {
> ++        t++;
> ++      }
> ++    }
> ++
> ++    if (*t == '\0')
> ++      break;
> ++
> ++    /* continue with next line */
> ++    if (*t == '\n') {
> ++      t++;
> ++      continue;
> ++    }
> ++
> ++    if(strncmp(t, "Dialogue:", 9) != 0) {
> ++      /* not started with "Dialogue:", it must be a line trimmed by demuxer */
> ++      num = atoi (t);
> ++      GST_LOG_OBJECT (parse, "Parsing line #%d at %" GST_TIME_FORMAT,
> ++          num, GST_TIME_ARGS (start));
> ++
> ++      /* skip all non-text fields before the actual text */
> ++      for (i = 0; i < 8; ++i) {
> ++        t = strchr (t, ',');
> ++        if (t == NULL)
> ++          break;
> ++        ++t;
> ++      }
> ++    } else {
> ++      /* started with "Dialogue:", update timestamp and duration */
> ++      /* time format are like Dialog:Mark,0:00:01.02,0:00:03.04,xx,xxx,... */
> ++      guint hour, min, sec, msec, len;
> ++      GstClockTime tmp;
> ++      gchar t_str[12] = {0};
> ++
> ++      /* find the first ',' */
> ++      p_start = strchr (t, ',');
> ++      if (p_start)
> ++        p_end = strchr (++p_start, ',');
> ++
> ++      if (p_start && p_end) {
> ++        /* copy text between first ',' and second ',' */
> ++        strncpy(t_str, p_start, p_end - p_start);
> ++        if (sscanf (t_str, "%u:%u:%u.%u", &hour, &min, &sec, &msec) == 4) {
> ++          tmp = ((hour*3600) + (min*60) + sec) * GST_SECOND + msec*GST_MSECOND;
> ++          GST_DEBUG_OBJECT (parse, "Get start time:%02d:%02d:%02d:%03d\n",
> ++              hour, min, sec, msec);
> ++          if (start_time > tmp)
> ++            start_time = tmp;
> ++        } else {
> ++          GST_WARNING_OBJECT (parse,
> ++              "failed to parse ssa start timestamp string :%s", t_str);
> ++        }
> ++
> ++        p_start = p_end;
> ++        p_end = strchr (++p_start, ',');
> ++        if (p_end) {
> ++          /* copy text between second ',' and third ',' */
> ++          strncpy(t_str, p_start, p_end - p_start);
> ++          if (sscanf (t_str, "%u:%u:%u.%u", &hour, &min, &sec, &msec) == 4) {
> ++            tmp = ((hour*3600) + (min*60) + sec)*GST_SECOND + msec*GST_MSECOND;
> ++            GST_DEBUG_OBJECT(parse, "Get end time:%02d:%02d:%02d:%03d\n",
> ++                hour, min, sec, msec);
> ++            if (end_time < tmp)
> ++              end_time = tmp;
> ++          } else {
> ++            GST_WARNING_OBJECT (parse,
> ++                "failed to parse ssa end timestamp string :%s", t_str);
> ++          }
> ++        }
> ++      }
> ++
> ++      /* now skip all non-text fields before the actual text */
> ++      for (i = 0; i <= 8; ++i) {
> ++        t = strchr (t, ',');
> ++        if (t == NULL)
> ++          break;
> ++        ++t;
> ++      }
> ++    }
> ++
> ++    /* line end before expected number of ',', not a Dialogue line */
> +     if (t == NULL)
> +-      return GST_FLOW_ERROR;
> +-    ++t;
> ++      break;
> ++
> ++    /* if not the first line, and the last character of previous line is '\0',
> ++     * then replace it with '\N' */
> ++    if (p != text && *p == '\0') {
> ++      *p++ = '\\';
> ++      *p++ = 'N';
> ++    }
> ++
> ++    /* copy all actual text of this line */
> ++    while ((*t != '\0') && (*t != '\n'))
> ++      *p++ = *t++;
> ++
> ++    /* add a terminator at the end */
> ++    *p = '\0';
> ++  }
> ++
> ++  /* not valid text found in this buffer return OK to let caller unref buffer */
> ++  if (strlen(text) <= 0) {
> ++    GST_WARNING_OBJECT (parse, "Not valid text found in this buffer\n");
> ++    return GST_FLOW_ERROR;
> +   }
> +
> ++  t = text;
> +   GST_LOG_OBJECT (parse, "Text : %s", t);
> +
> +   if (gst_ssa_parse_remove_override_codes (parse, t)) {
> +@@ -307,13 +414,22 @@ gst_ssa_parse_push_line (GstSsaParse * parse, gchar * txt,
> +   gst_buffer_fill (buf, 0, escaped, len + 1);
> +   gst_buffer_set_size (buf, len);
> +   g_free (escaped);
> ++  g_free(t);
> ++
> ++  if (start_time != G_MAXUINT64)
> ++    GST_BUFFER_TIMESTAMP (buf) = start_time;
> ++  else
> ++    GST_BUFFER_TIMESTAMP (buf) = start;
> +
> +-  GST_BUFFER_TIMESTAMP (buf) = start;
> +-  GST_BUFFER_DURATION (buf) = duration;
> ++  if (end_time > start_time)
> ++    GST_BUFFER_DURATION (buf) = end_time - start_time;
> ++  else
> ++    GST_BUFFER_DURATION (buf) = duration;
> +
> +   GST_LOG_OBJECT (parse, "Pushing buffer with timestamp %" GST_TIME_FORMAT
> +-      " and duration %" GST_TIME_FORMAT, GST_TIME_ARGS (start),
> +-      GST_TIME_ARGS (duration));
> ++      " and duration %" GST_TIME_FORMAT,
> ++      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
> ++      GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
> +
> +   ret = gst_pad_push (parse->srcpad, buf);
> +
> +@@ -333,6 +449,7 @@ gst_ssa_parse_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * buf)
> +   GstClockTime ts;
> +   gchar *txt;
> +   GstMapInfo map;
> ++  gint size;
> +
> +   if (G_UNLIKELY (!parse->framed))
> +     goto not_framed;
> +@@ -350,13 +467,14 @@ gst_ssa_parse_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * buf)
> +   /* make double-sure it's 0-terminated and all */
> +   gst_buffer_map (buf, &map, GST_MAP_READ);
> +   txt = g_strndup ((gchar *) map.data, map.size);
> ++  size = map.size;
> +   gst_buffer_unmap (buf, &map);
> +
> +   if (txt == NULL)
> +     goto empty_text;
> +
> +   ts = GST_BUFFER_TIMESTAMP (buf);
> +-  ret = gst_ssa_parse_push_line (parse, txt, ts, GST_BUFFER_DURATION (buf));
> ++  ret = gst_ssa_parse_push_line (parse, txt, size, ts, GST_BUFFER_DURATION (buf));
> +
> +   if (ret != GST_FLOW_OK && GST_CLOCK_TIME_IS_VALID (ts)) {
> +     GstSegment segment;
> +--
> +1.7.9.5
> +
> diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_%.bbappend b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_%.bbappend
> index e7e148e..977c26e 100644
> --- a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_%.bbappend
> +++ b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_%.bbappend
> @@ -2,7 +2,9 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
>   
>   SRC_URI_append_mxs = " file://gstplaybin-remove-flag-deinterlace.patch"
>   SRC_URI_append_mx5 = " file://gstplaybin-remove-flag-deinterlace.patch"
> -IMX_PATCHES = " file://gstplaybin-remove-flag-deinterlace.patch"
> +IMX_PATCHES = " file://gstplaybin-remove-flag-deinterlace.patch \
> +                file://0003-ssaparse-enhance-SSA-text-lines-parsing.patch \
> +"
>   
>   
>   SRC_URI_append_mx6 = "${IMX_PATCHES}"



More information about the meta-freescale mailing list