summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2018-08-23 14:29:37 +0200
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2018-08-29 11:55:19 -0400
commit71ab97cba64f2ce128d1cf08ba9f34b439c8c47c (patch)
treef4b9bbb74e3ba7c112d9d5946c580d3434ef76ce
parent4af7637012413209ce728ec377b265acbbaadc08 (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.c113
-rw-r--r--sys/kms/gstkmssink.h1
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;