[PATCH 2/2] clients: teach simple-dmabuf-v4l to deal with flipped input

Micah Fedke micah.fedke at collabora.co.uk
Wed Feb 1 20:28:24 UTC 2017


The v4l2 API can be queried to detect if the input video image is
horizontally or vertically flipped. If the image is y-flipped, we can
set the ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT flag to notify the
compositor.  If the image is h-flipped, we can only print a warning
since linux_buffer_params_v1 does not support horizontal flipping.
---
 clients/simple-dmabuf-v4l.c | 54 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 46 insertions(+), 8 deletions(-)

diff --git a/clients/simple-dmabuf-v4l.c b/clients/simple-dmabuf-v4l.c
index af25d0ea..e4e2d7c7 100644
--- a/clients/simple-dmabuf-v4l.c
+++ b/clients/simple-dmabuf-v4l.c
@@ -351,21 +351,59 @@ static const struct zwp_linux_buffer_params_v1_listener params_listener = {
 	create_failed
 };
 
+static bool
+check_v4l2_control(const int fd,
+                   const struct v4l2_query_ext_ctrl *qectrl,
+                   const char *control_name,
+                   const int len,
+                   const int expected_value)
+{
+	struct v4l2_control ctrl;
+
+	memset(&ctrl, 0, sizeof(ctrl));
+	ctrl.id = qectrl->id;
+
+	if (!(qectrl->flags & V4L2_CTRL_FLAG_DISABLED) &&
+            (qectrl->type == V4L2_CTRL_TYPE_BOOLEAN) &&
+            !strncmp(qectrl->name, control_name, len) &&
+            !xioctl(fd, VIDIOC_G_CTRL, &ctrl) &&
+            (ctrl.value == expected_value))
+		return true;
+	else
+		return false;
+}
+
 static void
 create_dmabuf_buffer(struct display *display, struct buffer *buffer)
 {
 	struct zwp_linux_buffer_params_v1 *params;
 	uint64_t modifier;
-	uint32_t flags;
+	uint32_t lbp_flags;
 	unsigned i;
+	struct v4l2_query_ext_ctrl qectrl;
+	const unsigned int v4l2_qec_flags =
+                           V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
+	const char *vflip_ctrl = "Vertical Flip";
+	const char *hflip_ctrl = "Horizontal Flip";
 
 	modifier = 0;
-	flags = 0;
-
-	/* XXX: apparently some webcams may actually provide y-inverted images,
-	 * in which case we should set
-	 * flags = ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT
-	 */
+	lbp_flags = 0;
+
+	/* handle relevant v4l2 controls */
+	memset(&qectrl, 0, sizeof(qectrl));
+	qectrl.id |= v4l2_qec_flags;
+	while (!xioctl(display->v4l_fd, VIDIOC_QUERY_EXT_CTRL, &qectrl)) {
+		if (check_v4l2_control(display->v4l_fd, &qectrl, vflip_ctrl,
+                                       strlen(vflip_ctrl), 0x1)) {
+			lbp_flags = ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT;
+			printf ("\"%s\" control is set, inverting Y\n",vflip_ctrl);
+		} else if (check_v4l2_control(display->v4l_fd, &qectrl,hflip_ctrl,
+                                              strlen(hflip_ctrl), 0x1)) {
+			printf ("\"%s\" control is set, but dmabuf output cannot"
+                                "be flipped horizontally\n", hflip_ctrl);
+		}
+		qectrl.id |= v4l2_qec_flags;
+	}
 
 	params = zwp_linux_dmabuf_v1_create_params(display->dmabuf);
 	for (i = 0; i < display->format.num_planes; ++i)
@@ -382,7 +420,7 @@ create_dmabuf_buffer(struct display *display, struct buffer *buffer)
 	                                  display->format.width,
 	                                  display->format.height,
 	                                  display->drm_format,
-	                                  flags);
+	                                  lbp_flags);
 }
 
 static int
-- 
2.11.0



More information about the wayland-devel mailing list