gst/playback/gstplaybasebin.*: Add 'subtitle-encoding' property to playbin, so applic...
authorYoung-Ho Cha <ganadist@chollian.net>
Mon, 29 May 2006 13:21:00 +0000 (13:21 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Mon, 29 May 2006 13:21:00 +0000 (13:21 +0000)
Original commit message from CVS:
Patch by: Young-Ho Cha  <ganadist at chollian net>
* gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init),
(gst_play_base_bin_init), (gst_play_base_bin_dispose),
(set_encoding_element), (decodebin_element_added_cb),
(decodebin_element_removed_cb), (setup_subtitle), (setup_source),
(gst_play_base_bin_set_property), (gst_play_base_bin_get_property):
* gst/playback/gstplaybasebin.h:
Add 'subtitle-encoding' property to playbin, so applications can
force a subtitle encoding for non-UTF8 subtitles (#342268).
* gst/subparse/gstsubparse.c: (gst_sub_parse_class_init),
(gst_sub_parse_set_property):
Rename recently-added 'encoding' property to 'subtitle-encoding'
(so it can be proxied by playbin/decodebin in a generic way
with less danger of false positives).

ChangeLog
gst/playback/gstplaybasebin.c
gst/playback/gstplaybasebin.h
gst/subparse/gstsubparse.c

index 2be910d80000c0415178448f1e56d5e75dc92ed9..93ca741957fa00eeaeeeae5972c082c8cac73e4c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2006-05-29  Tim-Philipp Müller  <tim at centricular dot net>
+
+       Patch by: Young-Ho Cha  <ganadist at chollian net>
+
+       * gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init),
+       (gst_play_base_bin_init), (gst_play_base_bin_dispose),
+       (set_encoding_element), (decodebin_element_added_cb),
+       (decodebin_element_removed_cb), (setup_subtitle), (setup_source),
+       (gst_play_base_bin_set_property), (gst_play_base_bin_get_property):
+       * gst/playback/gstplaybasebin.h:
+         Add 'subtitle-encoding' property to playbin, so applications can
+         force a subtitle encoding for non-UTF8 subtitles (#342268).
+
+       * gst/subparse/gstsubparse.c: (gst_sub_parse_class_init),
+       (gst_sub_parse_set_property):
+         Rename recently-added 'encoding' property to 'subtitle-encoding'
+         (so it can be proxied by playbin/decodebin in a generic way
+         with less danger of false positives).
+
 2006-05-29  Michael Smith  <msmith@fluendo.com>
 
        * gst/audioconvert/gstaudioconvert.c: (make_lossless_changes),
index b8d1e57544d54b0ee267bdf49cabb03477276f27..9fcbc0a1e0522d2bb1b67c934f580dbd3963cc0f 100644 (file)
@@ -71,7 +71,8 @@ enum
   ARG_SOURCE,
   ARG_VIDEO,
   ARG_AUDIO,
-  ARG_TEXT
+  ARG_TEXT,
+  ARG_SUBTITLE_ENCODING
 };
 
 static void gst_play_base_bin_class_init (GstPlayBaseBinClass * klass);
@@ -187,6 +188,12 @@ gst_play_base_bin_class_init (GstPlayBaseBinClass * klass)
       g_param_spec_int ("current-text", "Current text",
           "Currently playing text stream (-1 = none)",
           -1, G_MAXINT, -1, G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_klass, ARG_SUBTITLE_ENCODING,
+      g_param_spec_string ("subtitle-encoding", "subtitle encoding",
+          "Encoding to assume if input subtitles are not in UTF-8 encoding. "
+          "If not set, the GST_SUBTITLE_ENCODING environment variable will "
+          "be checked for an encoding to use. If that is not set either, "
+          "ISO-8859-15 will be assumed.", NULL, G_PARAM_READWRITE));
 
   GST_DEBUG_CATEGORY_INIT (gst_play_base_bin_debug, "playbasebin", 0,
       "playbasebin");
@@ -208,6 +215,8 @@ gst_play_base_bin_init (GstPlayBaseBin * play_base_bin)
   play_base_bin->source = NULL;
   play_base_bin->decoder = NULL;
   play_base_bin->subtitle = NULL;
+  play_base_bin->subencoding = NULL;
+  play_base_bin->subtitle_elements = NULL;
 
   play_base_bin->group_lock = g_mutex_new ();
   play_base_bin->group_cond = g_cond_new ();
@@ -229,7 +238,12 @@ gst_play_base_bin_dispose (GObject * object)
   play_base_bin->uri = NULL;
   g_free (play_base_bin->suburi);
   play_base_bin->suburi = NULL;
-
+  g_free (play_base_bin->subencoding);
+  play_base_bin->subencoding = NULL;
+  if (play_base_bin->subtitle_elements) {
+    g_slist_free (play_base_bin->subtitle_elements);
+    play_base_bin->subtitle_elements = NULL;
+  }
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
@@ -1147,6 +1161,48 @@ no_type:
   }
 }
 
+static void
+set_encoding_element (GstElement * element, gchar * encoding)
+{
+  GST_DEBUG_OBJECT (element, "setting encoding to %s", GST_STR_NULL (encoding));
+  g_object_set (G_OBJECT (element), "subtitle-encoding", encoding, NULL);
+}
+
+
+static void
+decodebin_element_added_cb (GstBin * decodebin, GstElement * element,
+    gpointer data)
+{
+  GstPlayBaseBin *play_base_bin = GST_PLAY_BASE_BIN (data);
+  gchar *encoding;
+
+  if (!g_object_class_find_property (G_OBJECT_GET_CLASS (element),
+          "subtitle-encoding")) {
+    return;
+  }
+
+  GST_OBJECT_LOCK (play_base_bin);
+  play_base_bin->subtitle_elements =
+      g_slist_append (play_base_bin->subtitle_elements, element);
+  encoding = g_strdup (play_base_bin->subencoding);
+  GST_OBJECT_UNLOCK (play_base_bin);
+
+  set_encoding_element (element, encoding);
+  g_free (encoding);
+}
+
+static void
+decodebin_element_removed_cb (GstBin * decodebin, GstElement * element,
+    gpointer data)
+{
+  GstPlayBaseBin *play_base_bin = GST_PLAY_BASE_BIN (data);
+
+  GST_OBJECT_LOCK (play_base_bin);
+  play_base_bin->subtitle_elements =
+      g_slist_remove (play_base_bin->subtitle_elements, element);
+  GST_OBJECT_UNLOCK (play_base_bin);
+}
+
 
 /*
  * Generate source ! subparse bins.
@@ -1155,16 +1211,20 @@ no_type:
 static GstElement *
 setup_subtitle (GstPlayBaseBin * play_base_bin, gchar * sub_uri)
 {
-  GstElement *source, *subparse, *subbin;
+  GstElement *source, *subdecodebin, *subbin;
 
   source = gst_element_make_from_uri (GST_URI_SRC, sub_uri, NULL);
   if (!source)
     return NULL;
-  subparse = gst_element_factory_make ("decodebin", "subtitle-decoder");
-
+  subdecodebin = gst_element_factory_make ("decodebin", "subtitle-decoder");
+  g_signal_connect (subdecodebin, "element-added",
+      G_CALLBACK (decodebin_element_added_cb), play_base_bin);
+  g_signal_connect (subdecodebin, "element-removed",
+      G_CALLBACK (decodebin_element_removed_cb), play_base_bin);
   subbin = gst_bin_new ("subtitle-bin");
-  gst_bin_add_many (GST_BIN (subbin), source, subparse, NULL);
-  gst_element_link (source, subparse);
+  gst_bin_add_many (GST_BIN (subbin), source, subdecodebin, NULL);
+
+  gst_element_link (source, subdecodebin);
 
   /* return the subtitle GstElement object */
   return subbin;
@@ -1437,6 +1497,11 @@ setup_source (GstPlayBaseBin * play_base_bin, gchar ** new_location)
           gst_element_factory_make ("decodebin", "decoder")))
     goto no_decodebin;
 
+  g_signal_connect (play_base_bin->decoder, "element-added",
+      G_CALLBACK (decodebin_element_added_cb), play_base_bin);
+  g_signal_connect (play_base_bin->decoder, "element-removed",
+      G_CALLBACK (decodebin_element_removed_cb), play_base_bin);
+
   gst_bin_add (GST_BIN (play_base_bin), play_base_bin->decoder);
 
   if (!gst_element_link (play_base_bin->source, play_base_bin->decoder))
@@ -1802,6 +1867,34 @@ gst_play_base_bin_set_property (GObject * object, guint prop_id,
           GST_STREAM_TYPE_TEXT, g_value_get_int (value));
       GROUP_UNLOCK (play_base_bin);
       break;
+    case ARG_SUBTITLE_ENCODING:
+    {
+      const gchar *encoding;
+      GSList *list;
+
+      encoding = g_value_get_string (value);
+      if (encoding && play_base_bin->subencoding &&
+          !strcmp (play_base_bin->subencoding, encoding)) {
+        return;
+      }
+      if (encoding == NULL && play_base_bin->subencoding == NULL)
+        return;
+
+      GST_OBJECT_LOCK (play_base_bin);
+      g_free (play_base_bin->subencoding);
+      play_base_bin->subencoding = g_strdup (encoding);
+      list = g_slist_copy (play_base_bin->subtitle_elements);
+      g_slist_foreach (list, (GFunc) gst_object_ref, NULL);
+      GST_OBJECT_UNLOCK (play_base_bin);
+
+      /* we can't hold a lock when calling g_object_set() on a child, since
+       * the notify event will trigger GstObject to send a deep-notify event
+       * which will try to take the lock ... */
+      g_slist_foreach (list, (GFunc) set_encoding_element, (gpointer) encoding);
+      g_slist_foreach (list, (GFunc) gst_object_unref, NULL);
+      g_slist_free (list);
+      break;
+    }
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1876,6 +1969,11 @@ gst_play_base_bin_get_property (GObject * object, guint prop_id, GValue * value,
               GST_STREAM_TYPE_TEXT));
       GROUP_UNLOCK (play_base_bin);
       break;
+    case ARG_SUBTITLE_ENCODING:
+      GST_OBJECT_LOCK (play_base_bin);
+      g_value_set_string (value, play_base_bin->subencoding);
+      GST_OBJECT_UNLOCK (play_base_bin);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index 80e4007e8c88bc210443045e3aca89c4297977b7..3826c98f0af5455845994aa42b16dfca847977d5 100644 (file)
@@ -79,7 +79,9 @@ struct _GstPlayBaseBin {
   gboolean       is_stream;
   GstElement    *source;
   GstElement    *decoder;
-  GstElement    *subtitle; /* additional filesrc ! subparse bin */
+  GstElement    *subtitle;              /* additional filesrc ! subparse bin */
+  GSList        *subtitle_elements;     /* subtitle elements that have 'subtitle-encoding' property */
+  gchar         *subencoding;           /* encoding to propagate to the above subtitle elements     */
   gboolean       need_rebuild;
 
   /* group management - using own lock */
index f3782e2189cfbc0dbc7f6d58dce02a917180cb8a..34222094fb35eebccd13d845ccfd373cdb8a4771 100644 (file)
@@ -163,7 +163,7 @@ gst_sub_parse_class_init (GstSubParseClass * klass)
   element_class->change_state = gst_sub_parse_change_state;
 
   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ENCODING,
-      g_param_spec_string ("encoding", "subtitle charset encoding",
+      g_param_spec_string ("subtitle-encoding", "subtitle charset encoding",
           "Encoding to assume if input subtitles are not in UTF-8 encoding. "
           "If not set, the GST_SUBTITLE_ENCODING environment variable will "
           "be checked for an encoding to use. If that is not set either, "
@@ -278,6 +278,8 @@ gst_sub_parse_set_property (GObject * object, guint prop_id,
     case PROP_ENCODING:
       g_free (subparse->encoding);
       subparse->encoding = g_value_dup_string (value);
+      GST_LOG_OBJECT (object, "subtitle encoding set to %s",
+          GST_STR_NULL (subparse->encoding));
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);