From: Thibault Saunier Date: Sun, 16 Nov 2014 14:54:56 +0000 (+0100) Subject: encodebin: Add a way to disable caps renegotiation for output stream format X-Git-Tag: 1.6.0~751 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=72c05d1cbb94f06e0340cf5578d6582322344f77;p=platform%2Fupstream%2Fgst-plugins-base.git encodebin: Add a way to disable caps renegotiation for output stream format 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 --- diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index c6f757e12..0fff111c4 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -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 diff --git a/gst-libs/gst/pbutils/encoding-profile.c b/gst-libs/gst/pbutils/encoding-profile.c index ac5643659..770e2ce36 100644 --- a/gst-libs/gst/pbutils/encoding-profile.c +++ b/gst-libs/gst/pbutils/encoding-profile.c @@ -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; } diff --git a/gst-libs/gst/pbutils/encoding-profile.h b/gst-libs/gst/pbutils/encoding-profile.h index 60e148d9c..401c547f0 100644 --- a/gst-libs/gst/pbutils/encoding-profile.h +++ b/gst-libs/gst/pbutils/encoding-profile.h @@ -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, diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index 3a8860354..b98c0f6f2 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -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; } diff --git a/win32/common/libgstpbutils.def b/win32/common/libgstpbutils.def index d7f365e1e..81504cc7e 100644 --- a/win32/common/libgstpbutils.def +++ b/win32/common/libgstpbutils.def @@ -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