mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-06 07:28:53 +00:00
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
This commit is contained in:
parent
4af7637012
commit
71ab97cba6
2 changed files with 114 additions and 0 deletions
|
@ -88,6 +88,7 @@ enum
|
||||||
PROP_CAN_SCALE,
|
PROP_CAN_SCALE,
|
||||||
PROP_DISPLAY_WIDTH,
|
PROP_DISPLAY_WIDTH,
|
||||||
PROP_DISPLAY_HEIGHT,
|
PROP_DISPLAY_HEIGHT,
|
||||||
|
PROP_CONNECTOR_PROPS,
|
||||||
PROP_N
|
PROP_N
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -559,6 +560,89 @@ ensure_allowed_caps (GstKMSSink * self, drmModeConnector * conn,
|
||||||
return (self->allowed_caps && !gst_caps_is_empty (self->allowed_caps));
|
return (self->allowed_caps && !gst_caps_is_empty (self->allowed_caps));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static gboolean
|
||||||
gst_kms_sink_start (GstBaseSink * bsink)
|
gst_kms_sink_start (GstBaseSink * bsink)
|
||||||
{
|
{
|
||||||
|
@ -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_WIDTH]);
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), g_properties[PROP_DISPLAY_HEIGHT]);
|
g_object_notify_by_pspec (G_OBJECT (self), g_properties[PROP_DISPLAY_HEIGHT]);
|
||||||
|
|
||||||
|
gst_kms_sink_update_connector_properties (self);
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
|
@ -1595,6 +1681,16 @@ gst_kms_sink_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_CAN_SCALE:
|
case PROP_CAN_SCALE:
|
||||||
sink->can_scale = g_value_get_boolean (value);
|
sink->can_scale = g_value_get_boolean (value);
|
||||||
break;
|
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:
|
default:
|
||||||
if (!gst_video_overlay_set_property (object, PROP_N, prop_id, value))
|
if (!gst_video_overlay_set_property (object, PROP_N, prop_id, value))
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
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);
|
g_value_set_int (value, sink->vdisplay);
|
||||||
GST_OBJECT_UNLOCK (sink);
|
GST_OBJECT_UNLOCK (sink);
|
||||||
break;
|
break;
|
||||||
|
case PROP_CONNECTOR_PROPS:
|
||||||
|
gst_value_set_structure (value, sink->connector_props);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -1654,6 +1753,7 @@ gst_kms_sink_finalize (GObject * object)
|
||||||
g_clear_pointer (&sink->devname, g_free);
|
g_clear_pointer (&sink->devname, g_free);
|
||||||
g_clear_pointer (&sink->bus_id, g_free);
|
g_clear_pointer (&sink->bus_id, g_free);
|
||||||
gst_poll_free (sink->poll);
|
gst_poll_free (sink->poll);
|
||||||
|
g_clear_pointer (&sink->connector_props, gst_structure_free);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
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,
|
"Height of the display surface in pixels", 0, G_MAXINT, 0,
|
||||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
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);
|
g_object_class_install_properties (gobject_class, PROP_N, g_properties);
|
||||||
|
|
||||||
gst_video_overlay_install_properties (gobject_class, PROP_N);
|
gst_video_overlay_install_properties (gobject_class, PROP_N);
|
||||||
|
|
|
@ -65,6 +65,7 @@ struct _GstKMSSink {
|
||||||
gboolean can_scale;
|
gboolean can_scale;
|
||||||
|
|
||||||
gboolean modesetting_enabled;
|
gboolean modesetting_enabled;
|
||||||
|
GstStructure *connector_props;
|
||||||
|
|
||||||
GstVideoInfo vinfo;
|
GstVideoInfo vinfo;
|
||||||
GstCaps *allowed_caps;
|
GstCaps *allowed_caps;
|
||||||
|
|
Loading…
Reference in a new issue