Merge branch 'upstream/1.16' into tizen_gst_1.16.2
[platform/upstream/gst-plugins-base.git] / gst / subparse / gstsubparse.c
index 4254158..6d806de 100644 (file)
 
 GST_DEBUG_CATEGORY (sub_parse_debug);
 
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+#define SUBPARSE_SEEK_GET_LOCK(elem)    (&elem->seek_lock)
+#define SUBPARSE_SEEK_LOCK(elem)        g_mutex_lock(SUBPARSE_SEEK_GET_LOCK(elem))
+#define SUBPARSE_SEEK_TRYLOCK(elem)     g_mutex_trylock(SUBPARSE_SEEK_GET_LOCK(elem))
+#define SUBPARSE_SEEK_UNLOCK(elem)      g_mutex_unlock(SUBPARSE_SEEK_GET_LOCK(elem))
+#endif
+
 #define DEFAULT_ENCODING   NULL
 #define ATTRIBUTE_REGEX "\\s?[a-zA-Z0-9\\. \t\\(\\)]*"
 static const gchar *allowed_srt_tags[] = { "i", "b", "u", NULL };
 static const gchar *allowed_vtt_tags[] =
     { "i", "b", "c", "u", "v", "ruby", "rt", NULL };
 
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+#define DEFAULT_CURRENT_LANGUAGE   NULL
+#endif
 enum
 {
   PROP_0,
   PROP_ENCODING,
-  PROP_VIDEOFPS
+  PROP_VIDEOFPS,
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+  PROP_EXTSUB_CURRENT_LANGUAGE
+#endif
 };
 
 static void
@@ -120,6 +133,12 @@ gst_sub_parse_dispose (GObject * object)
     subparse->textbuf = NULL;
   }
 
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+  g_free (subparse->state.current_language);
+  subparse->state.current_language = NULL;
+
+  g_mutex_clear (&subparse->seek_lock);
+#endif
   GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
 }
 
@@ -158,6 +177,13 @@ gst_sub_parse_class_init (GstSubParseClass * klass)
           "and the subtitle format requires it subtitles may be out of sync.",
           0, 1, G_MAXINT, 1, 24000, 1001,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+  g_object_class_install_property (object_class, PROP_EXTSUB_CURRENT_LANGUAGE,
+      g_param_spec_string ("current-language", "Current language",
+            "Current language of the subtitle in external subtitle case.",
+            DEFAULT_CURRENT_LANGUAGE,
+            G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+#endif
 }
 
 static void
@@ -188,6 +214,13 @@ gst_sub_parse_init (GstSubParse * subparse)
 
   subparse->fps_n = 24000;
   subparse->fps_d = 1001;
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+  subparse->state.language_list = NULL;
+  subparse->state.current_language = NULL;
+  subparse->state.langlist_msg_posted = FALSE;
+
+  g_mutex_init (&subparse->seek_lock);
+#endif
 }
 
 /*
@@ -270,6 +303,9 @@ gst_sub_parse_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
         goto beach;
       }
 
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+      SUBPARSE_SEEK_LOCK (self);
+#endif
       /* Convert that seek to a seeking in bytes at position 0,
          FIXME: could use an index */
       ret = gst_pad_push_event (self->sinkpad,
@@ -291,6 +327,10 @@ gst_sub_parse_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
         GST_WARNING_OBJECT (self, "seek to 0 bytes failed");
       }
 
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+      SUBPARSE_SEEK_UNLOCK (self);
+#endif
+
       gst_event_unref (event);
       break;
     }
@@ -330,6 +370,15 @@ gst_sub_parse_set_property (GObject * object, guint prop_id,
       }
       break;
     }
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+    case PROP_EXTSUB_CURRENT_LANGUAGE:
+      g_free(subparse->state.current_language);
+      subparse->state.current_language = g_value_dup_string (value);
+      GST_LOG_OBJECT (subparse, "subtitle current language set to %s",
+                      GST_STR_NULL (subparse->state.current_language));
+      sami_context_change_language(&subparse->state);
+      break;
+#endif
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -351,6 +400,11 @@ gst_sub_parse_get_property (GObject * object, guint prop_id,
     case PROP_VIDEOFPS:
       gst_value_set_fraction (value, subparse->fps_n, subparse->fps_d);
       break;
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+    case PROP_EXTSUB_CURRENT_LANGUAGE:
+      g_value_set_string (value, subparse->state.current_language);
+      break;
+#endif
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -494,13 +548,26 @@ convert_encoding (GstSubParse * self, const gchar * str, gsize len,
         encoding, err->message);
     g_clear_error (&err);
 
-    /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
-    ret = gst_convert_to_utf8 (str, len, "ISO-8859-15", consumed, NULL);
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+    if (!strcmp (self->encoding, "EUC-KR")) {
+      GST_LOG_OBJECT (self, "use CP949 as fallback");
+      g_free (self->encoding);
+      self->encoding = g_strdup ("CP949");
+      encoding = self->encoding;
+      ret = gst_convert_to_utf8 (str, len, encoding, consumed, &err);
+    } else {
+#endif
+      /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
+      GST_LOG_OBJECT (self, "use ISO-8859-15 as fallback");
+      ret = gst_convert_to_utf8 (str, len, "ISO-8859-15", consumed, NULL);
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+    }
+#endif
   }
 
   GST_LOG_OBJECT (self,
-      "successfully converted %" G_GSIZE_FORMAT " characters from %s to UTF-8"
-      "%s", len, encoding, (err) ? " , using ISO-8859-15 as fallback" : "");
+      "successfully converted %" G_GSIZE_FORMAT " characters from %s to UTF-8",
+      len, encoding);
 
   return ret;
 }
@@ -1375,6 +1442,15 @@ parser_state_init (ParserState * state)
   state->max_duration = 0;      /* no limit */
   state->state = 0;
   state->segment = NULL;
+
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+  state->language_list = NULL;
+
+  g_free(state->current_language);
+  state->current_language = NULL;
+
+  state->langlist_msg_posted = FALSE;
+#endif
 }
 
 static void
@@ -1721,6 +1797,9 @@ handle_buffer (GstSubParse * self, GstBuffer * buf)
   GstCaps *caps = NULL;
   gchar *line, *subtitle;
   gboolean need_tags = FALSE;
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+  GstMessage *m = NULL;
+#endif
 
   if (self->first_buffer) {
     GstMapInfo map;
@@ -1778,7 +1857,16 @@ handle_buffer (GstSubParse * self, GstBuffer * buf)
         line + offset);
     subtitle = self->parse_line (&self->state, line + offset);
     g_free (line);
-
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+    if (!self->state.langlist_msg_posted && self->state.language_list) {
+      m = gst_message_new_element (GST_OBJECT_CAST (self), gst_structure_new("Ext_Sub_Language_List",
+                                 "lang_list", G_TYPE_POINTER, self->state.language_list, NULL));
+
+      gst_element_post_message (GST_ELEMENT_CAST (self), m);
+      self->state.langlist_msg_posted = TRUE;
+      GST_DEBUG_OBJECT (self, "curr lang as : %s ", GST_STR_NULL(self->state.current_language));
+    }
+#endif
     if (subtitle) {
       guint subtitle_len = strlen (subtitle);
 
@@ -1881,6 +1969,21 @@ gst_sub_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
     case GST_EVENT_SEGMENT:
     {
       const GstSegment *s;
+
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+      if (self->first_buffer) {
+        if (!SUBPARSE_SEEK_TRYLOCK (self)) {
+          /* new seeking request is in process */
+          GST_WARNING_OBJECT (self, "ignore the old newsegment event");
+          ret = TRUE;
+          gst_event_unref (event);
+          break;
+        }
+      } else {
+        SUBPARSE_SEEK_LOCK (self);
+      }
+#endif
+
       gst_event_parse_segment (event, &s);
       if (s->format == GST_FORMAT_TIME)
         gst_event_copy_segment (event, &self->segment);
@@ -1901,6 +2004,11 @@ gst_sub_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
        * trigger sending of the saved requested seek segment
        * or the one taken here from upstream */
       self->need_segment = TRUE;
+
+#ifdef TIZEN_FEATURE_SUBPARSE_MODIFICATION
+      SUBPARSE_SEEK_UNLOCK (self);
+#endif
+         
       break;
     }
     case GST_EVENT_FLUSH_START: