summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2017-12-01 16:53:34 -0500
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2017-12-06 13:34:19 -0500
commitd33aff0fa0c369b1a46253577eacee33a32dd3d7 (patch)
tree15682bf5d2530059fa5437f02a4f296296c23be4 /sys
parent02e4d92cbf781a5d3c19b34d81f2fee812acd6bf (diff)
downloadgstreamer-plugins-bad-d33aff0fa0c369b1a46253577eacee33a32dd3d7.tar.gz
kmssink: Enforce pixel aspect ratio when we cannot scale
When we cannot scale, we need to enforce the pixel aspect ratio. This was partly implemented in the previous patch. Doing this simplify some of the code. https://bugzilla.gnome.org/show_bug.cgi?id=784599
Diffstat (limited to 'sys')
-rw-r--r--sys/kms/gstkmssink.c104
1 files changed, 58 insertions, 46 deletions
diff --git a/sys/kms/gstkmssink.c b/sys/kms/gstkmssink.c
index c3c57a7f8..fec6c2828 100644
--- a/sys/kms/gstkmssink.c
+++ b/sys/kms/gstkmssink.c
@@ -99,6 +99,11 @@ gst_kms_sink_set_render_rectangle (GstVideoOverlay * overlay,
{
GstKMSSink *self = GST_KMS_SINK (overlay);
+ GST_DEBUG_OBJECT (self, "Setting render rectangle to (%d,%d) %dx%d", x, y,
+ width, height);
+
+ GST_OBJECT_LOCK (self);
+
if (width == -1 && height == -1) {
x = 0;
y = 0;
@@ -106,41 +111,23 @@ gst_kms_sink_set_render_rectangle (GstVideoOverlay * overlay,
height = self->vdisplay;
}
- if (width <= 0 || height <= 0) {
- return;
- }
+ if (width <= 0 || height <= 0)
+ goto done;
- GST_OBJECT_LOCK (self);
- if (self->can_scale) {
- self->render_rect.x = x;
- self->render_rect.y = y;
- self->render_rect.w = width;
- self->render_rect.h = height;
- } else {
- GstVideoRectangle src = { 0, };
- GstVideoRectangle dst = { 0, };
- GstVideoRectangle result;
+ self->pending_rect.x = x;
+ self->pending_rect.y = y;
+ self->pending_rect.w = width;
+ self->pending_rect.h = height;
- src.w = GST_VIDEO_INFO_WIDTH (&self->vinfo);
- src.h = GST_VIDEO_INFO_HEIGHT (&self->vinfo);
-
- dst.w = width;
- dst.h = height;
-
- if (src.w != dst.w || src.h != dst.h)
- self->reconfigure = TRUE;
-
- gst_video_sink_center_rect (src, dst, &result, TRUE);
-
- self->pending_rect.x = x + result.x;
- self->pending_rect.y = y + result.y;
- self->pending_rect.w = result.w;
- self->pending_rect.h = result.h;
-
- GST_DEBUG_OBJECT (self, "pending resize to (%d,%d)-(%dx%d)",
- self->pending_rect.x, self->pending_rect.y,
- self->pending_rect.w, self->pending_rect.h);
+ if (self->can_scale ||
+ (self->render_rect.w == width && self->render_rect.h == height)) {
+ self->render_rect = self->pending_rect;
+ } else {
+ self->reconfigure = TRUE;
+ GST_DEBUG_OBJECT (self, "Waiting for new caps to apply render rectangle");
}
+
+done:
GST_OBJECT_UNLOCK (self);
}
@@ -149,18 +136,23 @@ gst_kms_sink_expose (GstVideoOverlay * overlay)
{
GstKMSSink *self = GST_KMS_SINK (overlay);
+ GST_DEBUG_OBJECT (overlay, "Expose called by application");
+
if (!self->can_scale) {
GST_OBJECT_LOCK (self);
if (self->reconfigure) {
GST_OBJECT_UNLOCK (self);
+ GST_DEBUG_OBJECT (overlay, "Sending a reconfigure event");
gst_pad_push_event (GST_BASE_SINK_PAD (self),
gst_event_new_reconfigure ());
} else {
+ GST_DEBUG_OBJECT (overlay, "Applying new render rectangle");
/* size of the rectangle does not change, only the (x,y) position changes */
self->render_rect = self->pending_rect;
GST_OBJECT_UNLOCK (self);
}
}
+
gst_kms_sink_show_frame (GST_VIDEO_SINK (self), NULL);
}
@@ -659,12 +651,12 @@ retry_find_plane:
GST_INFO_OBJECT (self, "connector id = %d / crtc id = %d / plane id = %d",
self->conn_id, self->crtc_id, self->plane_id);
+ GST_OBJECT_LOCK (self);
self->render_rect.x = 0;
self->render_rect.y = 0;
-
- GST_OBJECT_LOCK (self);
self->hdisplay = self->render_rect.w = crtc->mode.hdisplay;
self->vdisplay = self->render_rect.h = crtc->mode.vdisplay;
+ self->pending_rect = self->render_rect;
GST_OBJECT_UNLOCK (self);
self->buffer_id = crtc->buffer_id;
@@ -797,6 +789,11 @@ gst_kms_sink_stop (GstBaseSink * bsink)
GST_OBJECT_LOCK (bsink);
self->hdisplay = 0;
self->vdisplay = 0;
+ self->pending_rect.x = 0;
+ self->pending_rect.y = 0;
+ self->pending_rect.w = 0;
+ self->pending_rect.h = 0;
+ self->render_rect = self->pending_rect;
GST_OBJECT_UNLOCK (bsink);
g_object_notify_by_pspec (G_OBJECT (self), g_properties[PROP_DISPLAY_WIDTH]);
@@ -818,35 +815,50 @@ gst_kms_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
{
GstKMSSink *self;
GstCaps *caps, *out_caps;
+ GstStructure *s;
+ guint dpy_par_n, dpy_par_d;
self = GST_KMS_SINK (bsink);
caps = gst_kms_sink_get_allowed_caps (self);
+ if (!caps)
+ return NULL;
GST_OBJECT_LOCK (self);
- if (caps && self->reconfigure) {
- GstStructure *s0, *s1;
- guint dpy_par_n, dpy_par_d;
+ if (!self->can_scale) {
+ out_caps = gst_caps_new_empty ();
gst_video_calculate_device_ratio (self->hdisplay, self->vdisplay,
self->mm_width, self->mm_height, &dpy_par_n, &dpy_par_d);
- caps = gst_caps_make_writable (caps);
- s0 = gst_caps_get_structure (caps, 0);
- s1 = gst_structure_copy (gst_caps_get_structure (caps, 0));
+ s = gst_structure_copy (gst_caps_get_structure (caps, 0));
+ gst_structure_set (s, "width", G_TYPE_INT, self->pending_rect.w,
+ "height", G_TYPE_INT, self->pending_rect.h,
+ "pixel-aspect-ratio", GST_TYPE_FRACTION, dpy_par_n, dpy_par_d, NULL);
+
+ gst_caps_append_structure (out_caps, s);
- gst_structure_set (s0, "width", G_TYPE_INT, self->pending_rect.w,
- "height", G_TYPE_INT, self->pending_rect.h, NULL);
- gst_caps_append_structure (caps, s1);
+ out_caps = gst_caps_merge (out_caps, caps);
+ caps = NULL;
+
+ /* enforce our display aspect ratio */
+ gst_caps_set_simple (out_caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
+ dpy_par_n, dpy_par_d, NULL);
+ } else {
+ out_caps = gst_caps_make_writable (caps);
+ caps = NULL;
}
+
GST_OBJECT_UNLOCK (self);
- if (caps && filter) {
+ GST_DEBUG_OBJECT (self, "Proposing caps %" GST_PTR_FORMAT, out_caps);
+
+ if (filter) {
+ caps = out_caps;
out_caps = gst_caps_intersect_full (caps, filter, GST_CAPS_INTERSECT_FIRST);
gst_caps_unref (caps);
- } else {
- out_caps = caps;
}
+
return out_caps;
}