encodebin: Handle changes in encoding_profile::restriction during playback
authorThibault Saunier <thibault.saunier@collabora.com>
Mon, 7 Oct 2013 17:52:00 +0000 (14:52 -0300)
committerThibault Saunier <thibault.saunier@collabora.com>
Wed, 9 Oct 2013 18:25:19 +0000 (15:25 -0300)
There are cases where we want to change the restrictions caps during
playback, handle that in encodebin.

https://bugzilla.gnome.org/show_bug.cgi?id=709588

gst-libs/gst/pbutils/encoding-profile.c
gst/encoding/gstencodebin.c

index 330bf4e..f3aaddc 100644 (file)
@@ -150,6 +150,15 @@ struct _GstEncodingProfileClass
   GObjectClass parent_class;
 };
 
+enum
+{
+  FIRST_PROPERTY,
+  PROP_RESTRICTION_CAPS,
+  LAST_PROPERTY
+};
+
+static GParamSpec *_properties[LAST_PROPERTY];
+
 static void string_to_profile_transform (const GValue * src_value,
     GValue * dest_value);
 static gboolean gst_encoding_profile_deserialize_valfunc (GValue * value,
@@ -198,6 +207,42 @@ gst_encoding_profile_get_type (void)
   return g_define_type_id__volatile;
 }
 
+
+static void
+_encoding_profile_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstEncodingProfile *prof = (GstEncodingProfile *) object;
+
+  switch (prop_id) {
+    case PROP_RESTRICTION_CAPS:
+    {
+      gst_value_set_caps (value, prof->restriction);
+      break;
+    }
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+_encoding_profile_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstEncodingProfile *prof = (GstEncodingProfile *) object;
+
+  switch (prop_id) {
+    case PROP_RESTRICTION_CAPS:
+      gst_encoding_profile_set_restriction (prof, gst_caps_copy
+          (gst_value_get_caps (value)));
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
 static void
 gst_encoding_profile_finalize (GObject * object)
 {
@@ -220,6 +265,18 @@ gst_encoding_profile_class_init (GstEncodingProfileClass * klass)
   GObjectClass *gobject_class = (GObjectClass *) klass;
 
   gobject_class->finalize = gst_encoding_profile_finalize;
+
+  gobject_class->set_property = _encoding_profile_set_property;
+  gobject_class->get_property = _encoding_profile_get_property;
+
+  _properties[PROP_RESTRICTION_CAPS] =
+      g_param_spec_boxed ("restriction-caps", "Restriction caps",
+      "The restriction caps to use", GST_TYPE_CAPS,
+      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+  g_object_class_install_property (gobject_class,
+      PROP_RESTRICTION_CAPS, _properties[PROP_RESTRICTION_CAPS]);
+
 }
 
 /**
@@ -426,6 +483,9 @@ gst_encoding_profile_set_restriction (GstEncodingProfile * profile,
   if (profile->restriction)
     gst_caps_unref (profile->restriction);
   profile->restriction = restriction;
+
+  g_object_notify_by_pspec (G_OBJECT (profile),
+      _properties[PROP_RESTRICTION_CAPS]);
 }
 
 /* Container profiles */
index b567fc2..a8e9052 100644 (file)
@@ -221,6 +221,7 @@ struct _StreamGroup
   GstElement *outfilter;        /* Output capsfilter (streamprofile.format) */
   GstElement *formatter;
   GstElement *outqueue;         /* Queue just before the muxer */
+  gulong restriction_sid;
 };
 
 /* Default for queues (same defaults as queue element) */
@@ -1064,6 +1065,15 @@ _has_class (GstElement * element, const gchar * classname)
   return strstr (value, classname) != NULL;
 }
 
+static void
+_profile_restriction_caps_cb (GstEncodingProfile * profile,
+    GParamSpec * arg G_GNUC_UNUSED, StreamGroup * group)
+{
+  GstCaps *restriction = gst_encoding_profile_get_restriction (profile);
+
+  g_object_set (group->capsfilter, "caps", restriction, NULL);
+}
+
 /* FIXME : Add handling of streams that don't need encoding  */
 /* FIXME : Add handling of streams that don't require conversion elements */
 /*
@@ -1292,16 +1302,17 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
 
   /* 3. Create the conversion/restriction elements */
   /* 3.1. capsfilter */
-  if (restriction && !gst_caps_is_any (restriction)) {
-    GST_LOG ("Adding capsfilter for restriction caps : %" GST_PTR_FORMAT,
-        restriction);
+  GST_LOG ("Adding capsfilter for restriction caps : %" GST_PTR_FORMAT,
+      restriction);
 
-    last = sgroup->capsfilter = gst_element_factory_make ("capsfilter", NULL);
+  last = sgroup->capsfilter = gst_element_factory_make ("capsfilter", NULL);
+  if (restriction && !gst_caps_is_any (restriction))
     g_object_set (sgroup->capsfilter, "caps", restriction, NULL);
-    gst_bin_add ((GstBin *) ebin, sgroup->capsfilter);
-    tosync = g_list_append (tosync, sgroup->capsfilter);
-    fast_element_link (sgroup->capsfilter, sgroup->encoder);
-  }
+  gst_bin_add ((GstBin *) ebin, sgroup->capsfilter);
+  tosync = g_list_append (tosync, sgroup->capsfilter);
+  fast_element_link (sgroup->capsfilter, sgroup->encoder);
+  sgroup->restriction_sid = g_signal_connect (sprof, "notify::restriction-caps",
+      G_CALLBACK (_profile_restriction_caps_cb), sgroup);
 
   /* 3.2. restriction elements */
   /* FIXME : Once we have properties for specific converters, use those */
@@ -1870,6 +1881,8 @@ stream_group_free (GstEncodeBin * ebin, StreamGroup * sgroup)
 
   GST_DEBUG_OBJECT (ebin, "Freeing StreamGroup %p", sgroup);
 
+  g_signal_handler_disconnect (sgroup->profile, sgroup->restriction_sid);
+
   if (ebin->muxer) {
     /* outqueue - Muxer */
     tmppad = gst_element_get_static_pad (sgroup->outqueue, "src");