mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
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
3 changed files with 96 additions and 6 deletions
|
@ -30367,6 +30367,20 @@
|
|||
"type": "gchararray",
|
||||
"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": {
|
||||
"blurb": "When enabled, the sink try to configure the display mode",
|
||||
"conditionally-available": false,
|
||||
|
|
|
@ -97,6 +97,7 @@ enum
|
|||
PROP_DISPLAY_HEIGHT,
|
||||
PROP_CONNECTOR_PROPS,
|
||||
PROP_PLANE_PROPS,
|
||||
PROP_FD,
|
||||
PROP_N,
|
||||
};
|
||||
|
||||
|
@ -729,10 +730,14 @@ gst_kms_sink_start (GstBaseSink * bsink)
|
|||
pres = NULL;
|
||||
plane = NULL;
|
||||
|
||||
if (self->devname || self->bus_id)
|
||||
self->fd = drmOpen (self->devname, self->bus_id);
|
||||
else
|
||||
self->fd = kms_open (&self->devname);
|
||||
/* open our own internal device fd if application did not supply its own */
|
||||
if (self->is_internal_fd) {
|
||||
if (self->devname || self->bus_id)
|
||||
self->fd = drmOpen (self->devname, self->bus_id);
|
||||
else
|
||||
self->fd = kms_open (&self->devname);
|
||||
}
|
||||
|
||||
if (self->fd < 0)
|
||||
goto open_failed;
|
||||
|
||||
|
@ -838,7 +843,8 @@ bail:
|
|||
drmModeFreeResources (res);
|
||||
|
||||
if (!ret && self->fd >= 0) {
|
||||
drmClose (self->fd);
|
||||
if (self->is_internal_fd)
|
||||
drmClose (self->fd);
|
||||
self->fd = -1;
|
||||
}
|
||||
|
||||
|
@ -945,7 +951,8 @@ gst_kms_sink_stop (GstBaseSink * bsink)
|
|||
}
|
||||
|
||||
if (self->fd >= 0) {
|
||||
drmClose (self->fd);
|
||||
if (self->is_internal_fd)
|
||||
drmClose (self->fd);
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
gst_kms_sink_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
|
@ -1785,10 +1837,12 @@ gst_kms_sink_set_property (GObject * object, guint prop_id,
|
|||
|
||||
switch (prop_id) {
|
||||
case PROP_DRIVER_NAME:
|
||||
_invalidate_external_fd (sink, pspec);
|
||||
g_free (sink->devname);
|
||||
sink->devname = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_BUS_ID:
|
||||
_invalidate_external_fd (sink, pspec);
|
||||
g_free (sink->bus_id);
|
||||
sink->bus_id = g_value_dup_string (value);
|
||||
break;
|
||||
|
@ -1827,6 +1881,9 @@ gst_kms_sink_set_property (GObject * object, guint prop_id,
|
|||
|
||||
break;
|
||||
}
|
||||
case PROP_FD:
|
||||
_validate_and_set_external_fd (sink, g_value_get_int (value));
|
||||
break;
|
||||
default:
|
||||
if (!gst_video_overlay_set_property (object, PROP_N, prop_id, value))
|
||||
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:
|
||||
gst_value_set_structure (value, sink->plane_props);
|
||||
break;
|
||||
case PROP_FD:
|
||||
g_value_set_int (value, sink->fd);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1906,6 +1966,7 @@ static void
|
|||
gst_kms_sink_init (GstKMSSink * sink)
|
||||
{
|
||||
sink->fd = -1;
|
||||
sink->is_internal_fd = TRUE;
|
||||
sink->conn_id = -1;
|
||||
sink->plane_id = -1;
|
||||
sink->can_scale = TRUE;
|
||||
|
@ -2078,6 +2139,19 @@ gst_kms_sink_class_init (GstKMSSinkClass * klass)
|
|||
"Additional properties for the plane",
|
||||
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);
|
||||
|
||||
gst_video_overlay_install_properties (gobject_class, PROP_N);
|
||||
|
|
|
@ -93,6 +93,8 @@ struct _GstKMSSink {
|
|||
/* reconfigure info if driver doesn't scale */
|
||||
GstVideoRectangle pending_rect;
|
||||
gboolean reconfigure;
|
||||
|
||||
gboolean is_internal_fd;
|
||||
};
|
||||
|
||||
struct _GstKMSSinkClass {
|
||||
|
|
Loading…
Reference in a new issue