diff options
author | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2018-08-23 14:29:37 +0200 |
---|---|---|
committer | Nicolas Dufresne <nicolas.dufresne@collabora.com> | 2018-08-29 11:55:19 -0400 |
commit | 71ab97cba64f2ce128d1cf08ba9f34b439c8c47c (patch) | |
tree | f4b9bbb74e3ba7c112d9d5946c580d3434ef76ce | |
parent | 4af7637012413209ce728ec377b265acbbaadc08 (diff) |
kmssink: add 'connector-properties' prop
Can be used to pass custom connector properties to DRM. Properties can
be enumerated using modetest tool. These properties can then be applied
with the following gst-launch-1.0 syntax. Note that the name of the
structure is ignored.
... ! kmssink connector-properties="s,props1=value,props2=value"
https://bugzilla.gnome.org/show_bug.cgi?id=797027
-rw-r--r-- | sys/kms/gstkmssink.c | 113 | ||||
-rw-r--r-- | sys/kms/gstkmssink.h | 1 |
2 files changed, 114 insertions, 0 deletions
diff --git a/sys/kms/gstkmssink.c b/sys/kms/gstkmssink.c index 3400d3244..075efc9bb 100644 --- a/sys/kms/gstkmssink.c +++ b/sys/kms/gstkmssink.c @@ -88,6 +88,7 @@ enum PROP_CAN_SCALE, PROP_DISPLAY_WIDTH, PROP_DISPLAY_HEIGHT, + PROP_CONNECTOR_PROPS, PROP_N }; @@ -560,6 +561,89 @@ ensure_allowed_caps (GstKMSSink * self, drmModeConnector * conn, } static gboolean +set_drm_property (gint fd, guint32 object, guint32 object_type, + drmModeObjectPropertiesPtr properties, const gchar * prop_name, + guint64 value) +{ + guint i; + gboolean ret = FALSE; + + for (i = 0; i < properties->count_props && !ret; i++) { + drmModePropertyPtr property; + + property = drmModeGetProperty (fd, properties->props[i]); + if (!strcmp (property->name, prop_name)) { + drmModeObjectSetProperty (fd, object, object_type, + property->prop_id, value); + ret = TRUE; + } + drmModeFreeProperty (property); + } + + return ret; +} + +typedef struct +{ + GstKMSSink *self; + drmModeObjectPropertiesPtr properties; +} SetPropsIter; + +static gboolean +set_connector_prop (GQuark field_id, const GValue * value, gpointer user_data) +{ + SetPropsIter *iter = user_data; + GstKMSSink *self = iter->self; + const gchar *name; + guint64 v; + + name = g_quark_to_string (field_id); + + if (G_VALUE_HOLDS (value, G_TYPE_INT)) + v = g_value_get_int (value); + else if (G_VALUE_HOLDS (value, G_TYPE_UINT)) + v = g_value_get_uint (value); + else if (G_VALUE_HOLDS (value, G_TYPE_INT64)) + v = g_value_get_int64 (value); + else if (G_VALUE_HOLDS (value, G_TYPE_UINT64)) + v = g_value_get_uint64 (value); + else { + GST_WARNING_OBJECT (self, + "'uint64' value expected for control '%s'.", name); + return TRUE; + } + + if (set_drm_property (self->fd, self->conn_id, DRM_MODE_OBJECT_CONNECTOR, + iter->properties, name, v)) { + GST_DEBUG_OBJECT (self, + "Set connector property '%s' to %" G_GUINT64_FORMAT, name, v); + } else { + GST_WARNING_OBJECT (self, + "Failed to set connector property '%s' to %" G_GUINT64_FORMAT, name, v); + } + + return TRUE; +} + +static void +gst_kms_sink_update_connector_properties (GstKMSSink * self) +{ + SetPropsIter iter; + + if (!self->connector_props) + return; + + iter.self = self; + iter.properties = + drmModeObjectGetProperties (self->fd, self->conn_id, + DRM_MODE_OBJECT_CONNECTOR); + + gst_structure_foreach (self->connector_props, set_connector_prop, &iter); + + drmModeFreeObjectProperties (iter.properties); +} + +static gboolean gst_kms_sink_start (GstBaseSink * bsink) { GstKMSSink *self; @@ -667,6 +751,8 @@ retry_find_plane: g_object_notify_by_pspec (G_OBJECT (self), g_properties[PROP_DISPLAY_WIDTH]); g_object_notify_by_pspec (G_OBJECT (self), g_properties[PROP_DISPLAY_HEIGHT]); + gst_kms_sink_update_connector_properties (self); + ret = TRUE; bail: @@ -1595,6 +1681,16 @@ gst_kms_sink_set_property (GObject * object, guint prop_id, case PROP_CAN_SCALE: sink->can_scale = g_value_get_boolean (value); break; + case PROP_CONNECTOR_PROPS:{ + const GstStructure *s = gst_value_get_structure (value); + + g_clear_pointer (&sink->connector_props, gst_structure_free); + + if (s) + sink->connector_props = gst_structure_copy (s); + + break; + } default: if (!gst_video_overlay_set_property (object, PROP_N, prop_id, value)) G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1639,6 +1735,9 @@ gst_kms_sink_get_property (GObject * object, guint prop_id, g_value_set_int (value, sink->vdisplay); GST_OBJECT_UNLOCK (sink); break; + case PROP_CONNECTOR_PROPS: + gst_value_set_structure (value, sink->connector_props); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1654,6 +1753,7 @@ gst_kms_sink_finalize (GObject * object) g_clear_pointer (&sink->devname, g_free); g_clear_pointer (&sink->bus_id, g_free); gst_poll_free (sink->poll); + g_clear_pointer (&sink->connector_props, gst_structure_free); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -1795,6 +1895,19 @@ gst_kms_sink_class_init (GstKMSSinkClass * klass) "Height of the display surface in pixels", 0, G_MAXINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + /** + * kmssink:connector-properties: + * + * Additional properties for the connector. Keys are strings and values + * unsigned 64 bits integers. + * + * Since: 1.16 + */ + g_properties[PROP_CONNECTOR_PROPS] = + g_param_spec_boxed ("connector-properties", "Connector Properties", + "Additionnal properties for the connector", + GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (gobject_class, PROP_N, g_properties); gst_video_overlay_install_properties (gobject_class, PROP_N); diff --git a/sys/kms/gstkmssink.h b/sys/kms/gstkmssink.h index a80699c44..bb978bcd4 100644 --- a/sys/kms/gstkmssink.h +++ b/sys/kms/gstkmssink.h @@ -65,6 +65,7 @@ struct _GstKMSSink { gboolean can_scale; gboolean modesetting_enabled; + GstStructure *connector_props; GstVideoInfo vinfo; GstCaps *allowed_caps; |