playback: Register playsink as an element.
authorEdward Hervey <bilboed@bilboed.com>
Tue, 8 Sep 2009 09:35:20 +0000 (11:35 +0200)
committerEdward Hervey <bilboed@bilboed.com>
Mon, 14 Sep 2009 08:39:59 +0000 (10:39 +0200)
This allows using playsink from outside the playback plugin.

Add code to be able to request the sink pads using standard GStreamer API.

TODO : expose GObject properties/signals.

gst/playback/gstplayback.c
gst/playback/gstplaysink.c
gst/playback/gstplaysink.h

index aa98edb2dfbdcf7f09871539847b5991ad74af7d..3a445aecd02546917ba07e8b3be0665066a55eaa 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "gststreamselector.h"
 #include "gststreaminfo.h"
+#include "gstplaysink.h"
 
 gboolean gst_play_bin_plugin_init (GstPlugin * plugin);
 gboolean gst_play_bin2_plugin_init (GstPlugin * plugin);
@@ -54,6 +55,7 @@ plugin_init (GstPlugin * plugin)
 
   res = gst_play_bin_plugin_init (plugin);
   res &= gst_play_bin2_plugin_init (plugin);
+  res &= gst_play_sink_plugin_init (plugin);
 
   return res;
 }
index fbda43153dee841a9f0cbe6ab2d047f4d1f3bbd5..e242680d3695a6fcf384930caf29f825ba70a536 100644 (file)
@@ -171,6 +171,37 @@ struct _GstPlaySinkClass
   GstBinClass parent_class;
 };
 
+static GstStaticPadTemplate audiorawtemplate =
+GST_STATIC_PAD_TEMPLATE ("audio_raw_sink",
+    GST_PAD_SINK,
+    GST_PAD_REQUEST,
+    GST_STATIC_CAPS_ANY);
+static GstStaticPadTemplate audiotemplate =
+GST_STATIC_PAD_TEMPLATE ("audio_sink",
+    GST_PAD_SINK,
+    GST_PAD_REQUEST,
+    GST_STATIC_CAPS_ANY);
+static GstStaticPadTemplate videorawtemplate =
+GST_STATIC_PAD_TEMPLATE ("video_raw_sink",
+    GST_PAD_SINK,
+    GST_PAD_REQUEST,
+    GST_STATIC_CAPS_ANY);
+static GstStaticPadTemplate videotemplate =
+GST_STATIC_PAD_TEMPLATE ("video_sink",
+    GST_PAD_SINK,
+    GST_PAD_REQUEST,
+    GST_STATIC_CAPS_ANY);
+static GstStaticPadTemplate texttemplate = GST_STATIC_PAD_TEMPLATE ("text_sink",
+    GST_PAD_SINK,
+    GST_PAD_REQUEST,
+    GST_STATIC_CAPS_ANY);
+static GstStaticPadTemplate subpictemplate =
+GST_STATIC_PAD_TEMPLATE ("subpic_sink",
+    GST_PAD_SINK,
+    GST_PAD_REQUEST,
+    GST_STATIC_CAPS_ANY);
+
+
 
 /* props */
 enum
@@ -190,6 +221,10 @@ static void gst_play_sink_init (GstPlaySink * playsink);
 static void gst_play_sink_dispose (GObject * object);
 static void gst_play_sink_finalize (GObject * object);
 
+static GstPad *gst_play_sink_request_new_pad (GstElement * element,
+    GstPadTemplate * templ, const gchar * name);
+static void gst_play_sink_release_request_pad (GstElement * element,
+    GstPad * pad);
 static gboolean gst_play_sink_send_event (GstElement * element,
     GstEvent * event);
 static GstStateChangeReturn gst_play_sink_change_state (GstElement * element,
@@ -201,8 +236,8 @@ static void gst_play_sink_handle_message (GstBin * bin, GstMessage * message);
 
 static const GstElementDetails gst_play_sink_details =
 GST_ELEMENT_DETAILS ("Player Sink",
-    "Generic/Bin/Player",
-    "Autoplug and play media from an uri",
+    "Generic/Bin/Sink",
+    "Convenience sink for multiple streams",
     "Wim Taymans <wim.taymans@gmail.com>");
 
 G_DEFINE_TYPE (GstPlaySink, gst_play_sink, GST_TYPE_BIN);
@@ -221,16 +256,30 @@ gst_play_sink_class_init (GstPlaySinkClass * klass)
   gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_play_sink_dispose);
   gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_play_sink_finalize);
 
+  gst_element_class_add_pad_template (gstelement_klass,
+      gst_static_pad_template_get (&audiorawtemplate));
+  gst_element_class_add_pad_template (gstelement_klass,
+      gst_static_pad_template_get (&audiotemplate));
+  gst_element_class_add_pad_template (gstelement_klass,
+      gst_static_pad_template_get (&videorawtemplate));
+  gst_element_class_add_pad_template (gstelement_klass,
+      gst_static_pad_template_get (&videotemplate));
+  gst_element_class_add_pad_template (gstelement_klass,
+      gst_static_pad_template_get (&texttemplate));
+  gst_element_class_add_pad_template (gstelement_klass,
+      gst_static_pad_template_get (&subpictemplate));
   gst_element_class_set_details (gstelement_klass, &gst_play_sink_details);
 
   gstelement_klass->change_state =
       GST_DEBUG_FUNCPTR (gst_play_sink_change_state);
   gstelement_klass->send_event = GST_DEBUG_FUNCPTR (gst_play_sink_send_event);
+  gstelement_klass->request_new_pad =
+      GST_DEBUG_FUNCPTR (gst_play_sink_request_new_pad);
+  gstelement_klass->release_pad =
+      GST_DEBUG_FUNCPTR (gst_play_sink_release_request_pad);
 
   gstbin_klass->handle_message =
       GST_DEBUG_FUNCPTR (gst_play_sink_handle_message);
-
-  GST_DEBUG_CATEGORY_INIT (gst_play_sink_debug, "playsink", 0, "play bin");
 }
 
 static void
@@ -2207,14 +2256,18 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type)
   gboolean created = FALSE;
   gboolean raw = FALSE;
   gboolean activate = TRUE;
+  const gchar *pad_name = NULL;
 
   GST_DEBUG_OBJECT (playsink, "request pad type %d", type);
 
   GST_PLAY_SINK_LOCK (playsink);
   switch (type) {
     case GST_PLAY_SINK_TYPE_AUDIO_RAW:
+      pad_name = "audio_raw_sink";
       raw = TRUE;
     case GST_PLAY_SINK_TYPE_AUDIO:
+      if (pad_name == NULL)
+        pad_name = "audio_sink";
       if (!playsink->audio_tee) {
         GST_LOG_OBJECT (playsink, "creating tee");
         /* create tee when needed. This element will feed the audio sink chain
@@ -2230,19 +2283,22 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type)
       if (!playsink->audio_pad) {
         GST_LOG_OBJECT (playsink, "ghosting tee sinkpad");
         playsink->audio_pad =
-            gst_ghost_pad_new ("audio_sink", playsink->audio_tee_sink);
+            gst_ghost_pad_new (pad_name, playsink->audio_tee_sink);
         created = TRUE;
       }
       playsink->audio_pad_raw = raw;
       res = playsink->audio_pad;
       break;
     case GST_PLAY_SINK_TYPE_VIDEO_RAW:
+      pad_name = "video_raw_sink";
       raw = TRUE;
     case GST_PLAY_SINK_TYPE_VIDEO:
+      if (pad_name == NULL)
+        pad_name = "video_sink";
       if (!playsink->video_pad) {
         GST_LOG_OBJECT (playsink, "ghosting videosink");
         playsink->video_pad =
-            gst_ghost_pad_new_no_target ("video_sink", GST_PAD_SINK);
+            gst_ghost_pad_new_no_target (pad_name, GST_PAD_SINK);
         created = TRUE;
       }
       playsink->video_pad_raw = raw;
@@ -2297,6 +2353,48 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type)
   return res;
 }
 
+static GstPad *
+gst_play_sink_request_new_pad (GstElement * element, GstPadTemplate * templ,
+    const gchar * name)
+{
+  GstPlaySink *psink;
+  GstPad *pad;
+  GstElementClass *klass;
+  GstPlaySinkType type;
+  const gchar *tplname;
+
+  g_return_val_if_fail (templ != NULL, NULL);
+
+  GST_DEBUG_OBJECT (element, "name:%s", name);
+
+  psink = GST_PLAY_SINK (element);
+  klass = GST_ELEMENT_GET_CLASS (element);
+  tplname = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ);
+
+  /* Figure out the GstPlaySinkType based on the template */
+  if (!strcmp (tplname, "audio_sink"))
+    type = GST_PLAY_SINK_TYPE_AUDIO;
+  else if (!strcmp (tplname, "aduio_raw_sink"))
+    type = GST_PLAY_SINK_TYPE_AUDIO_RAW;
+  else if (!strcmp (tplname, "video_sink"))
+    type = GST_PLAY_SINK_TYPE_VIDEO;
+  else if (!strcmp (tplname, "video_raw_sink"))
+    type = GST_PLAY_SINK_TYPE_VIDEO_RAW;
+  else if (!strcmp (tplname, "text_sink"))
+    type = GST_PLAY_SINK_TYPE_TEXT;
+  else if (!strcmp (tplname, "subpicsink"))
+    type = GST_PLAY_SINK_TYPE_SUBPIC;
+  else
+    goto unknown_template;
+
+  pad = gst_play_sink_request_pad (psink, type);
+  return pad;
+
+unknown_template:
+  GST_WARNING_OBJECT (element, "Unknown pad template");
+  return NULL;
+}
+
 void
 gst_play_sink_release_pad (GstPlaySink * playsink, GstPad * pad)
 {
@@ -2333,6 +2431,13 @@ gst_play_sink_release_pad (GstPlaySink * playsink, GstPad * pad)
     *res = NULL;
   }
 }
+static void
+gst_play_sink_release_request_pad (GstElement * element, GstPad * pad)
+{
+  GstPlaySink *psink = GST_PLAY_SINK (element);
+
+  gst_play_sink_release_pad (psink, pad);
+}
 
 static void
 gst_play_sink_handle_message (GstBin * bin, GstMessage * message)
@@ -2577,3 +2682,12 @@ activate_failed:
     return GST_STATE_CHANGE_FAILURE;
   }
 }
+
+gboolean
+gst_play_sink_plugin_init (GstPlugin * plugin)
+{
+  GST_DEBUG_CATEGORY_INIT (gst_play_sink_debug, "playsink", 0, "play bin");
+
+  return gst_element_register (plugin, "playsink", GST_RANK_NONE,
+      GST_TYPE_PLAY_SINK);
+}
index 4de6207cab0294777c8a891c44292fe168ef57bd..208f500d43ef0e57aafc6835996f65ebaa6f6a77 100644 (file)
@@ -95,6 +95,8 @@ GstBuffer *      gst_play_sink_get_last_frame (GstPlaySink * playsink);
 
 gboolean         gst_play_sink_reconfigure    (GstPlaySink * playsink);
 
+gboolean         gst_play_sink_plugin_init    (GstPlugin * plugin);
+
 G_END_DECLS
 
 #endif /* __GST_PLAY_SINK_H__ */