gst/playback/: Implement group-switch signal for use in apps to clear metadata cache...
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Tue, 11 Jan 2005 12:03:24 +0000 (12:03 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Tue, 11 Jan 2005 12:03:24 +0000 (12:03 +0000)
Original commit message from CVS:
* gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init),
(gst_play_base_bin_init), (gst_play_base_bin_dispose),
(probe_triggered), (new_decoded_pad), (gen_source_element),
(gst_play_base_bin_set_property), (gst_play_base_bin_get_property):
* gst/playback/gstplaybasebin.h:
* gst/playback/gstplaybin.c: (gst_play_bin_class_init),
(gst_play_bin_init), (group_switch), (remove_sinks), (setup_sinks),
(gst_play_bin_change_state):
Implement group-switch signal for use in apps to clear metadata
cache, clean up subtitle, add suburi property instead of # hack,
some error-out fixes.

ChangeLog
gst/playback/gstplaybasebin.c
gst/playback/gstplaybasebin.h
gst/playback/gstplaybin.c

index deb05c0..8ef2237 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2005-01-11  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
 
+       * gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init),
+       (gst_play_base_bin_init), (gst_play_base_bin_dispose),
+       (probe_triggered), (new_decoded_pad), (gen_source_element),
+       (gst_play_base_bin_set_property), (gst_play_base_bin_get_property):
+       * gst/playback/gstplaybasebin.h:
+       * gst/playback/gstplaybin.c: (gst_play_bin_class_init),
+       (gst_play_bin_init), (group_switch), (remove_sinks), (setup_sinks),
+       (gst_play_bin_change_state):
+         Implement group-switch signal for use in apps to clear metadata
+         cache, clean up subtitle, add suburi property instead of # hack,
+         some error-out fixes.
+
+2005-01-11  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
+
        * ext/vorbis/vorbisdec.c: (vorbis_dec_chain):
          Debug.
        * sys/v4l/v4lsrc_calls.c: (gst_v4lsrc_grab_frame):
index f296ceb..48b112d 100644 (file)
@@ -36,6 +36,7 @@ enum
 {
   ARG_0,
   ARG_URI,
+  ARG_SUBURI,
   ARG_THREADED,
   ARG_NSTREAMS,
   ARG_QUEUE_SIZE,
@@ -52,6 +53,7 @@ enum
   SETUP_OUTPUT_PADS_SIGNAL,
   REMOVED_OUTPUT_PAD_SIGNAL,
   BUFFERING_SIGNAL,
+  GROUP_SWITCH_SIGNAL,
   LINK_STREAM_SIGNAL,
   UNLINK_STREAM_SIGNAL,
   LAST_SIGNAL
@@ -136,6 +138,9 @@ gst_play_base_bin_class_init (GstPlayBaseBinClass * klass)
   g_object_class_install_property (gobject_klass, ARG_URI,
       g_param_spec_string ("uri", "URI", "URI of the media to play",
           NULL, G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_klass, ARG_SUBURI,
+      g_param_spec_string ("suburi", ".sub-URI", "Optional URI of a subtitle",
+          NULL, G_PARAM_READWRITE));
   g_object_class_install_property (gobject_klass, ARG_NSTREAMS,
       g_param_spec_int ("nstreams", "NStreams", "number of streams",
           0, G_MAXINT, 0, G_PARAM_READABLE));
@@ -182,6 +187,11 @@ gst_play_base_bin_class_init (GstPlayBaseBinClass * klass)
       G_SIGNAL_RUN_LAST,
       G_STRUCT_OFFSET (GstPlayBaseBinClass, buffering),
       NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+  gst_play_base_bin_signals[GROUP_SWITCH_SIGNAL] =
+      g_signal_new ("group-switch", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST,
+      G_STRUCT_OFFSET (GstPlayBaseBinClass, group_switch),
+      NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
 
   /* action signals */
   gst_play_base_bin_signals[LINK_STREAM_SIGNAL] =
@@ -215,6 +225,7 @@ static void
 gst_play_base_bin_init (GstPlayBaseBin * play_base_bin)
 {
   play_base_bin->uri = NULL;
+  play_base_bin->suburi = NULL;
   play_base_bin->need_rebuild = TRUE;
   play_base_bin->source = NULL;
   play_base_bin->decoder = NULL;
@@ -239,6 +250,8 @@ gst_play_base_bin_dispose (GObject * object)
   play_base_bin = GST_PLAY_BASE_BIN (object);
   g_free (play_base_bin->uri);
   play_base_bin->uri = NULL;
+  g_free (play_base_bin->suburi);
+  play_base_bin->suburi = NULL;
 
   if (G_OBJECT_CLASS (parent_class)->dispose) {
     G_OBJECT_CLASS (parent_class)->dispose (object);
@@ -639,6 +652,8 @@ probe_triggered (GstProbe * probe, GstData ** data, gpointer user_data)
         gst_element_set_state (play_base_bin->thread, GST_STATE_PAUSED);
         /* ok, get rid of the current group then */
         group_destroy (group);
+        g_signal_emit (play_base_bin,
+            gst_play_base_bin_signals[GROUP_SWITCH_SIGNAL], 0);
         /* removing the current group brings the next group
          * active */
         play_base_bin->queued_groups =
@@ -764,8 +779,9 @@ new_decoded_pad (GstElement * element, GstPad * pad, gboolean last,
 
   /* first see if this pad has interesting caps */
   caps = gst_pad_get_caps (pad);
-  if (caps == NULL || gst_caps_is_empty (caps)) {
-    g_warning ("no type on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+  if (caps == NULL || gst_caps_is_empty (caps) || gst_caps_is_any (caps)) {
+    g_warning ("no type on pad %s:%s",
+        GST_DEBUG_PAD_NAME (GST_PAD_REALIZE (pad)));
     if (caps)
       gst_caps_free (caps);
     return;
@@ -964,24 +980,20 @@ gen_source_element (GstPlayBaseBin * play_base_bin, GstElement ** subbin)
   GstElement *source, *queue, *bin;
   GstProbe *probe;
   gboolean is_stream;
-  gchar **src, *uri;
 
   /* stip subtitle from uri */
-  src = g_strsplit (play_base_bin->uri, "#", 2);
-  if (!src[0])
+  if (!play_base_bin->uri)
     return NULL;
-  if (src[1]) {
+  if (play_base_bin->suburi) {
     /* subtitle specified */
-    *subbin = setup_subtitle (play_base_bin, src[1]);
+    *subbin = setup_subtitle (play_base_bin, play_base_bin->suburi);
   } else {
     /* no subtitle specified */
     *subbin = NULL;
   }
-  uri = src[0];
-  src[0] = NULL;
-  g_strfreev (src);
 
-  source = gst_element_make_from_uri (GST_URI_SRC, uri, "source");
+  source = gst_element_make_from_uri (GST_URI_SRC, play_base_bin->uri,
+      "source");
   if (!source)
     return NULL;
 
@@ -1399,6 +1411,19 @@ gst_play_base_bin_set_property (GObject * object, guint prop_id,
       }
       break;
     }
+    case ARG_SUBURI:{
+      const gchar *suburi = g_value_get_string (value);
+
+      if ((!suburi && !play_base_bin->suburi) ||
+          (suburi && play_base_bin->suburi &&
+              !strcmp (play_base_bin->suburi, suburi)))
+        return;
+      g_free (play_base_bin->suburi);
+      play_base_bin->suburi = g_strdup (suburi);
+      GST_DEBUG ("setting new .sub uri to %s", suburi);
+      play_base_bin->need_rebuild = TRUE;
+      break;
+    }
     case ARG_QUEUE_SIZE:
       play_base_bin->queue_size = g_value_get_uint64 (value);
       break;
@@ -1434,6 +1459,9 @@ gst_play_base_bin_get_property (GObject * object, guint prop_id, GValue * value,
     case ARG_URI:
       g_value_set_string (value, play_base_bin->uri);
       break;
+    case ARG_SUBURI:
+      g_value_set_string (value, play_base_bin->suburi);
+      break;
     case ARG_NSTREAMS:
     {
       GstPlayBaseGroup *group = get_active_group (play_base_bin);
index f6f49b6..37ca17b 100644 (file)
@@ -72,7 +72,7 @@ struct _GstPlayBaseBin {
 
   /* internal thread */
   GstElement   *thread;
-  gchar        *uri;
+  gchar        *uri, *suburi;
   GstElement   *source;
   GstElement   *decoder;
   GstElement   *subtitle; /* additional filesrc ! subparse bin */
@@ -100,6 +100,7 @@ struct _GstPlayBaseBinClass {
    * 100: buf=full (overrun) - will flush head of cache (latency) */
   void (*buffering)            (GstPlayBaseBin *play_base_bin,
                                 gint            percentage);
+  void (*group_switch)         (GstPlayBaseBin *play_base_bin);
 
   /* action signals */
   gboolean (*link_stream)      (GstPlayBaseBin *play_base_bin, 
index 26ebb1d..89becb7 100644 (file)
@@ -62,6 +62,9 @@ struct _GstPlayBin
 
   /* our cache for the sinks */
   GHashTable *cache;
+
+  /* boolean to see if we're currently switching groups */
+  gboolean group_switch;
 };
 
 struct _GstPlayBinClass
@@ -90,6 +93,7 @@ static void gst_play_bin_class_init (GstPlayBinClass * klass);
 static void gst_play_bin_init (GstPlayBin * play_bin);
 static void gst_play_bin_dispose (GObject * object);
 
+static void group_switch (GstPlayBaseBin * play_base_bin);
 static void setup_sinks (GstPlayBaseBin * play_base_bin);
 static void remove_sinks (GstPlayBin * play_bin);
 
@@ -202,6 +206,7 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
   gstelement_klass->query = GST_DEBUG_FUNCPTR (gst_play_bin_query);
 
   playbasebin_klass->setup_output_pads = setup_sinks;
+  playbasebin_klass->group_switch = group_switch;
 }
 
 static void
@@ -217,6 +222,7 @@ gst_play_bin_init (GstPlayBin * play_bin)
   play_bin->frame = NULL;
   play_bin->cache = g_hash_table_new_full (g_str_hash, g_str_equal,
       NULL, (GDestroyNotify) gst_object_unref);
+  play_bin->group_switch = FALSE;
 
   /* no iterate is needed */
   GST_FLAG_SET (play_bin, GST_BIN_SELF_SCHEDULABLE);
@@ -615,6 +621,13 @@ gen_vis_element (GstPlayBin * play_bin)
   return element;
 }
 
+/* set for group switch */
+static void
+group_switch (GstPlayBaseBin * play_base_bin)
+{
+  GST_PLAY_BIN (play_base_bin)->group_switch = TRUE;
+}
+
 /* get rid of all installed sinks */
 static void
 remove_sinks (GstPlayBin * play_bin)
@@ -624,6 +637,7 @@ remove_sinks (GstPlayBin * play_bin)
   GstElement *element;
 
   GST_DEBUG ("removesinks");
+  play_bin->group_switch = FALSE;
   element = g_hash_table_lookup (play_bin->cache, "abin");
   if (element != NULL) {
     parent = gst_element_get_parent (element);
@@ -755,7 +769,6 @@ setup_sinks (GstPlayBaseBin * play_base_bin)
     } else {
       sink = gen_audio_element (play_bin);
     }
-    //gst_element_link (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll, sink);
     add_sink (play_bin, sink,
         gst_element_get_pad (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll,
             "src"));
@@ -776,7 +789,6 @@ setup_sinks (GstPlayBaseBin * play_base_bin)
     } else {
       sink = gen_video_element (play_bin);
     }
-    //gst_element_link (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll, sink);
     add_sink (play_bin, sink,
         gst_element_get_pad (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll,
             "src"));
@@ -802,7 +814,7 @@ gst_play_bin_change_state (GstElement * element)
     case GST_STATE_PLAYING_TO_PAUSED:
       /* Set audio sink state to NULL to release the sound device,
        * but only if we own it (else we might be in chain-transition). */
-      if (play_bin->audio_sink != NULL &&
+      if (play_bin->audio_sink != NULL && !play_bin->group_switch &&
           GST_STATE (play_bin->audio_sink) == GST_STATE_PAUSED) {
         gst_element_set_state (play_bin->audio_sink, GST_STATE_NULL);
       }