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 c6f757e..0fff111 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 ac56436..770e2ce 100644 (file)
@@ -188,6 +188,7 @@ struct _GstEncodingProfile
   gchar *preset_name;
   guint presence;
   GstCaps *restriction;
+  gboolean allow_dynamic_output;
 };
 
 struct _GstEncodingProfileClass
@@ -465,6 +466,35 @@ gst_encoding_profile_set_format (GstEncodingProfile * profile, GstCaps * 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
  * @preset: the element preset to use
@@ -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 60e148d..401c547 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 3a88603..b98c0f6 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;
@@ -1079,6 +1080,34 @@ _profile_restriction_caps_cb (GstEncodingProfile * profile,
 }
 
 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)
 {
   GstCaps *format;
@@ -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 d7f365e..81504cc 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