ges-track: Add the notion of resriction caps to GESTrack
authorSimon Corsin <simoncorsin@gmail.com>
Sat, 17 Aug 2013 12:57:15 +0000 (14:57 +0200)
committerThibault Saunier <thibault.saunier@collabora.com>
Wed, 4 Sep 2013 00:57:30 +0000 (20:57 -0400)
This way we can let the user determine what he want to come out of the
track.

API:
  - ges_track_set_caps (The track caps are now construct only)
  + ges_track_set_restriction_caps
  + ges_track_get_restriction_caps
  + GESTrack.props.restriction_caps

ges/ges-audio-track.c
ges/ges-internal.h
ges/ges-track.c
ges/ges-track.h

index 87a60ab..b9ce484 100644 (file)
@@ -24,6 +24,7 @@
 
 #define DEFAULT_CAPS "audio/x-raw"
 
+#include "ges-internal.h"
 #include "ges-smart-adder.h"
 #include "ges-audio-track.h"
 
index afaa659..06c60dd 100644 (file)
@@ -291,4 +291,6 @@ G_GNUC_INTERNAL void ges_track_element_split_bindings (GESTrackElement *element,
 
 G_GNUC_INTERNAL GstElement *ges_source_create_topbin (const gchar * bin_name, GstElement * sub_element, ...);
 
+G_GNUC_INTERNAL void ges_track_set_caps (GESTrack *track, const GstCaps *caps);
+
 #endif /* __GES_INTERNAL_H__ */
index e95ddf3..e9fd3f4 100644 (file)
@@ -61,6 +61,7 @@ struct _GESTrackPrivate
   guint64 duration;
 
   GstCaps *caps;
+  GstCaps *restriction_caps;
 
   GstElement *composition;      /* The composition associated with this track */
   GstPad *srcpad;               /* The source GhostPad */
@@ -69,6 +70,7 @@ struct _GESTrackPrivate
 
   gboolean mixing;
   GstElement *mixing_operation;
+  GstElement *capsfilter;
 
   /* Virtual method to create GstElement that fill gaps */
   GESCreateElementForGapFunc create_element_for_gaps;
@@ -78,6 +80,7 @@ enum
 {
   ARG_0,
   ARG_CAPS,
+  ARG_RESTRICTION_CAPS,
   ARG_TYPE,
   ARG_DURATION,
   ARG_LAST,
@@ -254,14 +257,19 @@ static void
 pad_added_cb (GstElement * element, GstPad * pad, GESTrack * track)
 {
   GESTrackPrivate *priv = track->priv;
+  GstPad *capsfilter_sink;
+  GstPad *capsfilter_src;
+
+  capsfilter_sink = gst_element_get_static_pad (priv->capsfilter, "sink");
 
   GST_DEBUG ("track:%p, pad %s:%s", track, GST_DEBUG_PAD_NAME (pad));
 
-  /* ghost the pad */
-  priv->srcpad = gst_ghost_pad_new ("src", pad);
+  gst_pad_link (pad, capsfilter_sink);
 
+  capsfilter_src = gst_element_get_static_pad (priv->capsfilter, "src");
+  /* ghost the pad */
+  priv->srcpad = gst_ghost_pad_new ("src", capsfilter_src);
   gst_pad_set_active (priv->srcpad, TRUE);
-
   gst_element_add_pad (GST_ELEMENT (track), priv->srcpad);
 
   GST_DEBUG ("done");
@@ -373,6 +381,9 @@ ges_track_get_property (GObject * object, guint property_id,
     case ARG_DURATION:
       g_value_set_uint64 (value, track->priv->duration);
       break;
+    case ARG_RESTRICTION_CAPS:
+      gst_value_set_caps (value, track->priv->restriction_caps);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
   }
@@ -391,6 +402,9 @@ ges_track_set_property (GObject * object, guint property_id,
     case ARG_TYPE:
       track->type = g_value_get_flags (value);
       break;
+    case ARG_RESTRICTION_CAPS:
+      ges_track_set_restriction_caps (track, gst_value_get_caps (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
   }
@@ -436,6 +450,9 @@ ges_track_constructed (GObject * object)
   if (!gst_bin_add (GST_BIN (self), self->priv->composition))
     GST_ERROR ("Couldn't add composition to bin !");
 
+  if (!gst_bin_add (GST_BIN (self), self->priv->capsfilter))
+    GST_ERROR ("Couldn't add capsfilter to bin !");
+
   if (GES_TRACK_GET_CLASS (self)->get_mixing_element) {
     GstElement *gnlobject;
     GstElement *mixer = GES_TRACK_GET_CLASS (self)->get_mixing_element (self);
@@ -492,11 +509,25 @@ ges_track_class_init (GESTrackClass * klass)
    */
   properties[ARG_CAPS] = g_param_spec_boxed ("caps", "Caps",
       "Caps used to filter/choose the output stream",
-      GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+      GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
   g_object_class_install_property (object_class, ARG_CAPS,
       properties[ARG_CAPS]);
 
   /**
+   * GESTrack:restriction-caps:
+   *
+   * Caps used to filter/choose the output stream.
+   *
+   * Default value: #GST_CAPS_ANY.
+   */
+  properties[ARG_RESTRICTION_CAPS] =
+      g_param_spec_boxed ("restriction-caps", "Restriction caps",
+      "Caps used to filter/choose the output stream", GST_TYPE_CAPS,
+      G_PARAM_READWRITE);
+  g_object_class_install_property (object_class, ARG_RESTRICTION_CAPS,
+      properties[ARG_RESTRICTION_CAPS]);
+
+  /**
    * GESTrack:duration:
    *
    * Current duration of the track
@@ -564,6 +595,7 @@ ges_track_init (GESTrack * self)
       GES_TYPE_TRACK, GESTrackPrivate);
 
   self->priv->composition = gst_element_factory_make ("gnlcomposition", NULL);
+  self->priv->capsfilter = gst_element_factory_make ("capsfilter", NULL);
   self->priv->updating = TRUE;
   self->priv->trackelements_by_start = g_sequence_new (NULL);
   self->priv->trackelements_iter =
@@ -571,6 +603,7 @@ ges_track_init (GESTrack * self)
   self->priv->create_element_for_gaps = NULL;
   self->priv->gaps = NULL;
   self->priv->mixing = TRUE;
+  self->priv->restriction_caps = NULL;
 
   g_signal_connect (G_OBJECT (self->priv->composition), "notify::duration",
       G_CALLBACK (composition_duration_cb), self);
@@ -675,6 +708,34 @@ ges_track_set_caps (GESTrack * track, const GstCaps * caps)
 }
 
 /**
+ * ges_track_set_restriction_caps:
+ * @track: a #GESTrack
+ * @caps: the #GstCaps to set
+ *
+ * Sets the given @caps as the caps the track has to output.
+ */
+void
+ges_track_set_restriction_caps (GESTrack * track, const GstCaps * caps)
+{
+  GESTrackPrivate *priv;
+
+  g_return_if_fail (GES_IS_TRACK (track));
+
+  GST_DEBUG ("track:%p, restriction caps:%" GST_PTR_FORMAT, track, caps);
+  g_return_if_fail (GST_IS_CAPS (caps));
+
+  priv = track->priv;
+
+  if (priv->restriction_caps)
+    gst_caps_unref (priv->restriction_caps);
+  priv->restriction_caps = gst_caps_copy (caps);
+
+  g_object_set (priv->capsfilter, "caps", caps, NULL);
+
+  g_object_notify (G_OBJECT (track), "restriction-caps");
+}
+
+/**
  * ges_track_set_mixing:
  * @track: a #GESTrack
  * @mixing: TRUE if the track should be mixing, FALSE otherwise.
index 6a19c23..6670b11 100644 (file)
@@ -85,13 +85,13 @@ const GstCaps*     ges_track_get_caps                        (GESTrack *track);
 GList*             ges_track_get_elements                    (GESTrack *track);
 const GESTimeline* ges_track_get_timeline                    (GESTrack *track);
 gboolean           ges_track_commit                          (GESTrack *track);
-void               ges_track_set_caps                        (GESTrack *track, const GstCaps *caps);
 void               ges_track_set_timeline                    (GESTrack *track, GESTimeline *timeline);
 gboolean           ges_track_add_element                     (GESTrack *track, GESTrackElement *object);
 gboolean           ges_track_remove_element                  (GESTrack *track, GESTrackElement *object);
 void               ges_track_set_create_element_for_gap_func (GESTrack *track, GESCreateElementForGapFunc func);
 void               ges_track_set_mixing                      (GESTrack *track, gboolean mixing);
 gboolean           ges_track_get_mixing                      (GESTrack *track);
+void               ges_track_set_restriction_caps            (GESTrack *track, const GstCaps *caps);
 
 /* standard methods */
 GType              ges_track_get_type                        (void);