waylandsink: Add force-aspect-ratio property
Similar to and inspired by glimagesink, xvimagesink and others. The waylandsink never transform the buffer in any way but delegates this to the Wayland compositor with the Wayland buffer transform API. Rotation and window size are already supported, so this just changes the video surface geometry that is communicated to the Wayland compositor. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9210>
This commit is contained in:
parent
9363054e63
commit
31f3e73066
@ -255902,6 +255902,18 @@
|
||||
"type": "gchararray",
|
||||
"writable": true
|
||||
},
|
||||
"force-aspect-ratio": {
|
||||
"blurb": "When enabled, scaling will respect original aspect ratio",
|
||||
"conditionally-available": false,
|
||||
"construct": false,
|
||||
"construct-only": false,
|
||||
"controllable": false,
|
||||
"default": "true",
|
||||
"mutable": "playing",
|
||||
"readable": true,
|
||||
"type": "gboolean",
|
||||
"writable": true
|
||||
},
|
||||
"fullscreen": {
|
||||
"blurb": "Whether the surface should be made fullscreen ",
|
||||
"conditionally-available": false,
|
||||
|
@ -63,6 +63,7 @@ enum
|
||||
PROP_FULLSCREEN,
|
||||
PROP_ROTATE_METHOD,
|
||||
PROP_DRM_DEVICE,
|
||||
PROP_FORCE_ASPECT_RATIO,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
@ -184,6 +185,18 @@ gst_wayland_sink_class_init (GstWaylandSinkClass * klass)
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
/**
|
||||
* waylandsink:force-aspect-ratio:
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO,
|
||||
g_param_spec_boolean ("force-aspect-ratio", "Force aspect ratio",
|
||||
"When enabled, scaling will respect original aspect ratio",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
|
||||
/**
|
||||
* waylandsink:render-rectangle:
|
||||
@ -201,6 +214,7 @@ gst_wayland_sink_init (GstWaylandSink * self)
|
||||
{
|
||||
g_mutex_init (&self->display_lock);
|
||||
g_mutex_init (&self->render_lock);
|
||||
self->force_aspect_ratio = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -252,6 +266,23 @@ gst_wayland_sink_set_rotate_method (GstWaylandSink * self,
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
}
|
||||
|
||||
/* must be called with the OBJECT_LOCK */
|
||||
static void
|
||||
gst_wayland_sink_set_force_aspect_ratio (GstWaylandSink * self,
|
||||
gboolean force_aspect_ratio)
|
||||
{
|
||||
if (force_aspect_ratio == self->force_aspect_ratio)
|
||||
return;
|
||||
|
||||
self->force_aspect_ratio = force_aspect_ratio;
|
||||
if (self->window) {
|
||||
g_mutex_lock (&self->render_lock);
|
||||
gst_wl_window_set_force_aspect_ratio (self->window,
|
||||
self->force_aspect_ratio);
|
||||
g_mutex_unlock (&self->render_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_wayland_sink_get_property (GObject * object,
|
||||
guint prop_id, GValue * value, GParamSpec * pspec)
|
||||
@ -279,6 +310,11 @@ gst_wayland_sink_get_property (GObject * object,
|
||||
g_value_set_string (value, self->drm_device);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
break;
|
||||
case PROP_FORCE_ASPECT_RATIO:
|
||||
GST_OBJECT_LOCK (self);
|
||||
g_value_set_boolean (value, self->force_aspect_ratio);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -313,6 +349,12 @@ gst_wayland_sink_set_property (GObject * object,
|
||||
self->drm_device = g_value_dup_string (value);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
break;
|
||||
case PROP_FORCE_ASPECT_RATIO:
|
||||
GST_OBJECT_LOCK (self);
|
||||
gst_wayland_sink_set_force_aspect_ratio (self,
|
||||
g_value_get_boolean (value));
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
break;
|
||||
default:
|
||||
if (!gst_video_overlay_set_property (object, PROP_LAST, prop_id, value))
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
@ -866,6 +908,8 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
|
||||
G_CALLBACK (on_window_closed), self, 0);
|
||||
gst_wl_window_set_rotate_method (self->window,
|
||||
self->current_rotate_method);
|
||||
gst_wl_window_set_force_aspect_ratio (self->window,
|
||||
self->force_aspect_ratio);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1134,6 +1178,8 @@ gst_wayland_sink_set_window_handle (GstVideoOverlay * overlay, guintptr handle)
|
||||
&self->render_lock);
|
||||
gst_wl_window_set_rotate_method (self->window,
|
||||
self->current_rotate_method);
|
||||
gst_wl_window_set_force_aspect_ratio (self->window,
|
||||
self->force_aspect_ratio);
|
||||
}
|
||||
} else {
|
||||
GST_ERROR_OBJECT (self, "Failed to find display handle, "
|
||||
|
@ -69,6 +69,7 @@ struct _GstWaylandSink
|
||||
|
||||
gchar *drm_device;
|
||||
gboolean skip_dumb_buffer_copy;
|
||||
gboolean force_aspect_ratio;
|
||||
};
|
||||
|
||||
struct _GstWaylandSinkClass
|
||||
|
@ -73,6 +73,8 @@ typedef struct _GstWlWindowPrivate
|
||||
|
||||
enum wl_output_transform buffer_transform;
|
||||
|
||||
gboolean force_aspect_ratio;
|
||||
|
||||
/* when this is not set both the area_surface and the video_surface are not
|
||||
* visible and certain steps should be skipped */
|
||||
gboolean is_area_surface_mapped;
|
||||
@ -257,6 +259,7 @@ gst_wl_window_new_internal (GstWlDisplay * display, GMutex * render_lock)
|
||||
priv->display = g_object_ref (display);
|
||||
priv->render_lock = render_lock;
|
||||
g_cond_init (&priv->configure_cond);
|
||||
priv->force_aspect_ratio = TRUE;
|
||||
|
||||
compositor = gst_wl_display_get_compositor (display);
|
||||
priv->area_surface = wl_compositor_create_surface (compositor);
|
||||
@ -502,7 +505,10 @@ gst_wl_window_resize_video_surface (GstWlWindow * self, gboolean commit)
|
||||
|
||||
/* center the video_subsurface inside area_subsurface */
|
||||
if (priv->video_viewport) {
|
||||
gst_video_center_rect (&src, &dst, &res, TRUE);
|
||||
if (!priv->force_aspect_ratio)
|
||||
res = dst;
|
||||
else
|
||||
gst_video_center_rect (&src, &dst, &res, TRUE);
|
||||
wp_viewport_set_source (priv->video_viewport, wl_fixed_from_int (0),
|
||||
wl_fixed_from_int (0), wl_fixed_from_int (wp_src_width),
|
||||
wl_fixed_from_int (wp_src_height));
|
||||
@ -1103,3 +1109,14 @@ gst_wl_window_set_colorimetry (GstWlWindow * self,
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
}
|
||||
|
||||
void
|
||||
gst_wl_window_set_force_aspect_ratio (GstWlWindow * self,
|
||||
gboolean force_aspect_ratio)
|
||||
{
|
||||
GstWlWindowPrivate *priv = gst_wl_window_get_instance_private (self);
|
||||
|
||||
priv->force_aspect_ratio = force_aspect_ratio;
|
||||
|
||||
gst_wl_window_update_geometry (self);
|
||||
}
|
||||
|
@ -74,4 +74,8 @@ GST_WL_API
|
||||
void gst_wl_window_set_rotate_method (GstWlWindow *self,
|
||||
GstVideoOrientationMethod rotate_method);
|
||||
|
||||
GST_WL_API
|
||||
void gst_wl_window_set_force_aspect_ratio (GstWlWindow * self,
|
||||
gboolean force_aspect_ratio);
|
||||
|
||||
G_END_DECLS
|
||||
|
Loading…
x
Reference in New Issue
Block a user