encodebin: Add a way to disable caps renegotiation for output stream format
authorThibault Saunier <tsaunier@gnome.org>
Sun, 16 Nov 2014 14:54:56 +0000 (15:54 +0100)
committerThibault Saunier <tsaunier@gnome.org>
Fri, 28 Nov 2014 15:56:32 +0000 (16:56 +0100)
In some cases, the user might want the stream outputted by encodebin to
be in the exact same format during all the stream. We should let the
user specify when this is the case. This commit add some API in the
GstEncodingProfile to determine whether the format can be renegotiated
after the encoding started or not.

API:
    gst_encoding_profile_set_allow_dynamic_output
    gst_encoding_profile_get_allow_dynamic_output

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

docs/libs/gst-plugins-base-libs-sections.txt
gst-libs/gst/pbutils/encoding-profile.c
gst-libs/gst/pbutils/encoding-profile.h
gst/encoding/gstencodebin.c
win32/common/libgstpbutils.def

index c6f757e12e45ec90ee8d1bd96db4e7ca855a4a25..0fff111c4a8d4beef9db9c460ba3b2c2c50fa546 100644 (file)
@@ -2112,6 +2112,7 @@ gst_encoding_profile_from_discoverer
 gst_encoding_profile_get_name
 gst_encoding_profile_get_description
 gst_encoding_profile_get_format
+gst_encoding_profile_get_allow_renegotiation
 gst_encoding_profile_get_preset
 gst_encoding_profile_get_preset_name
 gst_encoding_profile_get_presence
@@ -2120,6 +2121,7 @@ gst_encoding_profile_get_file_extension
 gst_encoding_profile_set_name
 gst_encoding_profile_set_description
 gst_encoding_profile_set_format
+gst_encoding_profile_set_allow_renegotiation
 gst_encoding_profile_set_preset
 gst_encoding_profile_set_preset_name
 gst_encoding_profile_set_restriction
index ac564365922c48bad09fe4e96071119e6c62ae3f..770e2ce36eadd4ee8544256fc81276c49285b8ef 100644 (file)
@@ -188,6 +188,7 @@ struct _GstEncodingProfile
   gchar *preset_name;
   guint presence;
   GstCaps *restriction;
+  gboolean allow_dynamic_output;
 };
 
 struct _GstEncodingProfileClass
@@ -464,6 +465,35 @@ gst_encoding_profile_set_format (GstEncodingProfile * profile, GstCaps * format)
   profile->format = gst_caps_ref (format);
 }
 
+/**
+ * gst_encoding_profile_get_allow_dynamic_output:
+ * @profile: a #GstEncodingProfile
+ *
+ * Get whether the format that has been negotiated in at some point can be renegotiated
+ * later during the encoding.
+ */
+gboolean
+gst_encoding_profile_get_allow_dynamic_output (GstEncodingProfile * profile)
+{
+  return profile->allow_dynamic_output;
+}
+
+/**
+ * gst_encoding_profile_set_allow_dynamic_output:
+ * @profile: a #GstEncodingProfile
+ * @allow_dynamic_output: Whether the format that has been negotiated first can be renegotiated
+ * during the encoding
+ *
+ * Sets whether the format that has been negotiated in at some point can be renegotiated
+ * later during the encoding.
+ */
+void
+gst_encoding_profile_set_allow_dynamic_output (GstEncodingProfile * profile,
+    gboolean allow_dynamic_output)
+{
+  profile->allow_dynamic_output = allow_dynamic_output;
+}
+
 /**
  * gst_encoding_profile_set_preset:
  * @profile: a #GstEncodingProfile
@@ -837,6 +867,7 @@ common_creation (GType objtype, GstCaps * format, const gchar * preset,
     prof->restriction = gst_caps_ref (restriction);
   prof->presence = presence;
   prof->preset_name = NULL;
+  prof->allow_dynamic_output = TRUE;
 
   return prof;
 }
index 60e148d9cc53be2700360487cde39fea0a5fdecc..401c547f0a16948d84cb1f11fc56c7bc92844d0c 100644 (file)
@@ -125,6 +125,9 @@ void            gst_encoding_profile_set_description    (GstEncodingProfile *pro
 GstCaps *       gst_encoding_profile_get_format         (GstEncodingProfile *profile);
 void            gst_encoding_profile_set_format         (GstEncodingProfile *profile,
                                                          GstCaps *format);
+gboolean  gst_encoding_profile_get_allow_dynamic_output (GstEncodingProfile *profile);
+void      gst_encoding_profile_set_allow_dynamic_output (GstEncodingProfile *profile,
+                                                         gboolean allow_dynamic_output);
 const gchar *   gst_encoding_profile_get_preset         (GstEncodingProfile *profile);
 const gchar *   gst_encoding_profile_get_preset_name    (GstEncodingProfile *profile);
 void            gst_encoding_profile_set_preset         (GstEncodingProfile *profile,
index 3a88603548f837ba83c3721cdbe9e599d0bd404f..b98c0f6f27c7ab41f7f6c4ee746bfed03cdfacf6 100644 (file)
@@ -220,6 +220,7 @@ struct _StreamGroup
   GstElement *parser;
   GstElement *smartencoder;
   GstElement *outfilter;        /* Output capsfilter (streamprofile.format) */
+  gulong outputfilter_caps_sid;
   GstElement *formatter;
   GstElement *outqueue;         /* Queue just before the muxer */
   gulong restriction_sid;
@@ -1078,6 +1079,34 @@ _profile_restriction_caps_cb (GstEncodingProfile * profile,
   g_object_set (group->capsfilter, "caps", restriction, NULL);
 }
 
+static void
+_outfilter_caps_set_cb (GstPad * outfilter_sinkpad,
+    GParamSpec * arg G_GNUC_UNUSED, StreamGroup * group)
+{
+  GstCaps *caps;
+
+  g_object_get (outfilter_sinkpad, "caps", &caps, NULL);
+  GST_INFO_OBJECT (group->ebin, "Forcing caps to %" GST_PTR_FORMAT, caps);
+  g_object_set (group->outfilter, "caps", caps, NULL);
+  g_signal_handler_disconnect (outfilter_sinkpad, group->outputfilter_caps_sid);
+  group->outputfilter_caps_sid = 0;
+}
+
+static void
+_set_group_caps_format (StreamGroup * sgroup, GstEncodingProfile * prof,
+    GstCaps * format)
+{
+  g_object_set (sgroup->outfilter, "caps", format, NULL);
+
+  if (!gst_encoding_profile_get_allow_dynamic_output (prof)) {
+    if (!sgroup->outputfilter_caps_sid) {
+      sgroup->outputfilter_caps_sid =
+          g_signal_connect (sgroup->outfilter->sinkpads->data,
+          "notify::caps", G_CALLBACK (_outfilter_caps_set_cb), sgroup);
+    }
+  }
+}
+
 static void
 _post_missing_plugin_message (GstEncodeBin * ebin, GstEncodingProfile * prof)
 {
@@ -1211,7 +1240,7 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
    * This will receive the format caps from the streamprofile */
   GST_DEBUG ("Adding output capsfilter for %" GST_PTR_FORMAT, format);
   sgroup->outfilter = gst_element_factory_make ("capsfilter", NULL);
-  g_object_set (sgroup->outfilter, "caps", format, NULL);
+  _set_group_caps_format (sgroup, sprof, format);
 
   gst_bin_add (GST_BIN (ebin), sgroup->outfilter);
   tosync = g_list_append (tosync, sgroup->outfilter);
@@ -1989,8 +2018,15 @@ stream_group_free (GstEncodeBin * ebin, StreamGroup * sgroup)
     gst_element_set_state (sgroup->encoder, GST_STATE_NULL);
   if (sgroup->fakesink)
     gst_element_set_state (sgroup->fakesink, GST_STATE_NULL);
-  if (sgroup->outfilter)
+  if (sgroup->outfilter) {
     gst_element_set_state (sgroup->outfilter, GST_STATE_NULL);
+
+    if (sgroup->outputfilter_caps_sid) {
+      g_signal_handler_disconnect (sgroup->outfilter->sinkpads->data,
+          sgroup->outputfilter_caps_sid);
+      sgroup->outputfilter_caps_sid = 0;
+    }
+  }
   if (sgroup->smartencoder)
     gst_element_set_state (sgroup->smartencoder, GST_STATE_NULL);
 
@@ -2148,6 +2184,18 @@ gst_encode_bin_activate (GstEncodeBin * ebin)
 static void
 gst_encode_bin_deactivate (GstEncodeBin * ebin)
 {
+  GList *tmp;
+
+  for (tmp = ebin->streams; tmp; tmp = tmp->next) {
+    StreamGroup *sgroup = tmp->data;
+    GstCaps *format = gst_encoding_profile_get_format (sgroup->profile);
+
+    _set_group_caps_format (sgroup, sgroup->profile, format);
+
+    if (format)
+      gst_caps_unref (format);
+  }
+
   ebin->active = FALSE;
 }
 
index d7f365e1e9b28eeff6d318a6f898d63db012acd1..81504cc7ef447b103f8bb733debcb4821af8a55d 100644 (file)
@@ -84,6 +84,7 @@ EXPORTS
        gst_encoding_list_available_categories
        gst_encoding_profile_find
        gst_encoding_profile_from_discoverer
+       gst_encoding_profile_get_allow_dynamic_output
        gst_encoding_profile_get_description
        gst_encoding_profile_get_file_extension
        gst_encoding_profile_get_format
@@ -96,6 +97,7 @@ EXPORTS
        gst_encoding_profile_get_type
        gst_encoding_profile_get_type_nick
        gst_encoding_profile_is_equal
+       gst_encoding_profile_set_allow_dynamic_output
        gst_encoding_profile_set_description
        gst_encoding_profile_set_format
        gst_encoding_profile_set_name