From 4305e1c33e256caadae2bdbe2b8f7567b0a05abd Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Mon, 7 Oct 2013 14:52:00 -0300 Subject: [PATCH] encodebin: Handle changes in encoding_profile::restriction during playback 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 | 60 +++++++++++++++++++++++++++++++++ gst/encoding/gstencodebin.c | 29 +++++++++++----- 2 files changed, 81 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/pbutils/encoding-profile.c b/gst-libs/gst/pbutils/encoding-profile.c index 330bf4e..f3aaddc 100644 --- a/gst-libs/gst/pbutils/encoding-profile.c +++ b/gst-libs/gst/pbutils/encoding-profile.c @@ -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 */ diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index b567fc2..a8e9052 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -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"); -- 2.7.4