kmssink: add fd property
This allows an application to provide their own opened DRM device fd handle to kmssink. For example, an application can lease multiple fd's from a DRM master to display on different CRTC outputs at the same time with multiple kmssink instances. Specifying the fd property is not allowed when driver-name and/or bus-id properties are specified. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2807>
This commit is contained in:
parent
7bcfccd0bd
commit
135edee484
@ -30367,6 +30367,20 @@
|
|||||||
"type": "gchararray",
|
"type": "gchararray",
|
||||||
"writable": true
|
"writable": true
|
||||||
},
|
},
|
||||||
|
"fd": {
|
||||||
|
"blurb": "DRM file descriptor",
|
||||||
|
"conditionally-available": false,
|
||||||
|
"construct": true,
|
||||||
|
"construct-only": false,
|
||||||
|
"controllable": false,
|
||||||
|
"default": "-1",
|
||||||
|
"max": "2147483647",
|
||||||
|
"min": "-1",
|
||||||
|
"mutable": "null",
|
||||||
|
"readable": true,
|
||||||
|
"type": "gint",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
"force-modesetting": {
|
"force-modesetting": {
|
||||||
"blurb": "When enabled, the sink try to configure the display mode",
|
"blurb": "When enabled, the sink try to configure the display mode",
|
||||||
"conditionally-available": false,
|
"conditionally-available": false,
|
||||||
|
@ -97,6 +97,7 @@ enum
|
|||||||
PROP_DISPLAY_HEIGHT,
|
PROP_DISPLAY_HEIGHT,
|
||||||
PROP_CONNECTOR_PROPS,
|
PROP_CONNECTOR_PROPS,
|
||||||
PROP_PLANE_PROPS,
|
PROP_PLANE_PROPS,
|
||||||
|
PROP_FD,
|
||||||
PROP_N,
|
PROP_N,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -729,10 +730,14 @@ gst_kms_sink_start (GstBaseSink * bsink)
|
|||||||
pres = NULL;
|
pres = NULL;
|
||||||
plane = NULL;
|
plane = NULL;
|
||||||
|
|
||||||
if (self->devname || self->bus_id)
|
/* open our own internal device fd if application did not supply its own */
|
||||||
self->fd = drmOpen (self->devname, self->bus_id);
|
if (self->is_internal_fd) {
|
||||||
else
|
if (self->devname || self->bus_id)
|
||||||
self->fd = kms_open (&self->devname);
|
self->fd = drmOpen (self->devname, self->bus_id);
|
||||||
|
else
|
||||||
|
self->fd = kms_open (&self->devname);
|
||||||
|
}
|
||||||
|
|
||||||
if (self->fd < 0)
|
if (self->fd < 0)
|
||||||
goto open_failed;
|
goto open_failed;
|
||||||
|
|
||||||
@ -838,7 +843,8 @@ bail:
|
|||||||
drmModeFreeResources (res);
|
drmModeFreeResources (res);
|
||||||
|
|
||||||
if (!ret && self->fd >= 0) {
|
if (!ret && self->fd >= 0) {
|
||||||
drmClose (self->fd);
|
if (self->is_internal_fd)
|
||||||
|
drmClose (self->fd);
|
||||||
self->fd = -1;
|
self->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -945,7 +951,8 @@ gst_kms_sink_stop (GstBaseSink * bsink)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (self->fd >= 0) {
|
if (self->fd >= 0) {
|
||||||
drmClose (self->fd);
|
if (self->is_internal_fd)
|
||||||
|
drmClose (self->fd);
|
||||||
self->fd = -1;
|
self->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1775,6 +1782,51 @@ gst_kms_sink_query (GstBaseSink * bsink, GstQuery * query)
|
|||||||
return GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
|
return GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_validate_and_set_external_fd (GstKMSSink * self, gint fd)
|
||||||
|
{
|
||||||
|
if (self->devname) {
|
||||||
|
GST_WARNING_OBJECT (self, "Can't set fd... %s already set.",
|
||||||
|
g_param_spec_get_name (g_properties[PROP_DRIVER_NAME]));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->bus_id) {
|
||||||
|
GST_WARNING_OBJECT (self, "Can't set fd... %s already set.",
|
||||||
|
g_param_spec_get_name (g_properties[PROP_BUS_ID]));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->fd >= 0) {
|
||||||
|
GST_WARNING_OBJECT (self, "Can't set fd... it is already set.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd >= 0) {
|
||||||
|
self->devname = drmGetDeviceNameFromFd (fd);
|
||||||
|
if (!self->devname) {
|
||||||
|
GST_WARNING_OBJECT (self, "Failed to verify fd is a DRM fd.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->fd = fd;
|
||||||
|
self->is_internal_fd = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_invalidate_external_fd (GstKMSSink * self, GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
if (self->is_internal_fd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GST_WARNING_OBJECT (self, "Unsetting fd... %s has priority.",
|
||||||
|
g_param_spec_get_name (pspec));
|
||||||
|
|
||||||
|
self->fd = -1;
|
||||||
|
self->is_internal_fd = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_kms_sink_set_property (GObject * object, guint prop_id,
|
gst_kms_sink_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec)
|
const GValue * value, GParamSpec * pspec)
|
||||||
@ -1785,10 +1837,12 @@ gst_kms_sink_set_property (GObject * object, guint prop_id,
|
|||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_DRIVER_NAME:
|
case PROP_DRIVER_NAME:
|
||||||
|
_invalidate_external_fd (sink, pspec);
|
||||||
g_free (sink->devname);
|
g_free (sink->devname);
|
||||||
sink->devname = g_value_dup_string (value);
|
sink->devname = g_value_dup_string (value);
|
||||||
break;
|
break;
|
||||||
case PROP_BUS_ID:
|
case PROP_BUS_ID:
|
||||||
|
_invalidate_external_fd (sink, pspec);
|
||||||
g_free (sink->bus_id);
|
g_free (sink->bus_id);
|
||||||
sink->bus_id = g_value_dup_string (value);
|
sink->bus_id = g_value_dup_string (value);
|
||||||
break;
|
break;
|
||||||
@ -1827,6 +1881,9 @@ gst_kms_sink_set_property (GObject * object, guint prop_id,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PROP_FD:
|
||||||
|
_validate_and_set_external_fd (sink, g_value_get_int (value));
|
||||||
|
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);
|
||||||
@ -1880,6 +1937,9 @@ gst_kms_sink_get_property (GObject * object, guint prop_id,
|
|||||||
case PROP_PLANE_PROPS:
|
case PROP_PLANE_PROPS:
|
||||||
gst_value_set_structure (value, sink->plane_props);
|
gst_value_set_structure (value, sink->plane_props);
|
||||||
break;
|
break;
|
||||||
|
case PROP_FD:
|
||||||
|
g_value_set_int (value, sink->fd);
|
||||||
|
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;
|
||||||
@ -1906,6 +1966,7 @@ static void
|
|||||||
gst_kms_sink_init (GstKMSSink * sink)
|
gst_kms_sink_init (GstKMSSink * sink)
|
||||||
{
|
{
|
||||||
sink->fd = -1;
|
sink->fd = -1;
|
||||||
|
sink->is_internal_fd = TRUE;
|
||||||
sink->conn_id = -1;
|
sink->conn_id = -1;
|
||||||
sink->plane_id = -1;
|
sink->plane_id = -1;
|
||||||
sink->can_scale = TRUE;
|
sink->can_scale = TRUE;
|
||||||
@ -2078,6 +2139,19 @@ gst_kms_sink_class_init (GstKMSSinkClass * klass)
|
|||||||
"Additional properties for the plane",
|
"Additional properties for the plane",
|
||||||
GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kmssink:fd:
|
||||||
|
*
|
||||||
|
* You can supply your own DRM file descriptor. By default, the sink will
|
||||||
|
* open its own DRM file descriptor.
|
||||||
|
*
|
||||||
|
* Since: 1.22
|
||||||
|
*/
|
||||||
|
g_properties[PROP_FD] =
|
||||||
|
g_param_spec_int ("fd", "File Descriptor",
|
||||||
|
"DRM file descriptor", -1, G_MAXINT, -1,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
|
||||||
|
|
||||||
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);
|
||||||
|
@ -93,6 +93,8 @@ struct _GstKMSSink {
|
|||||||
/* reconfigure info if driver doesn't scale */
|
/* reconfigure info if driver doesn't scale */
|
||||||
GstVideoRectangle pending_rect;
|
GstVideoRectangle pending_rect;
|
||||||
gboolean reconfigure;
|
gboolean reconfigure;
|
||||||
|
|
||||||
|
gboolean is_internal_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstKMSSinkClass {
|
struct _GstKMSSinkClass {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user