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
This commit is contained in:
Thibault Saunier 2014-11-16 15:54:56 +01:00
parent b03cfdffb1
commit 72c05d1cbb
5 changed files with 88 additions and 2 deletions

View 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

View 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;
}

View 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,

View 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;
}

View 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