diff options
author | Micah Fedke <micah.fedke@collabora.co.uk> | 2017-02-06 12:57:41 -0500 |
---|---|---|
committer | Pekka Paalanen <pekka.paalanen@collabora.co.uk> | 2017-02-07 11:47:10 +0200 |
commit | 0fee977c46423e496a6eda6418c31bfe09a1f27b (patch) | |
tree | 2c821fef7c1bd07858c3d5ae8a65cf795996e6f9 | |
parent | 9a200d7559f936e1f9334f4f2ad9c9e7d0f41e04 (diff) |
clients: teach simple-dmabuf-v4l to deal with flipped input
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.
Signed-off-by: Micah Fedke <micah.fedke@collabora.co.uk>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
-rw-r--r-- | clients/simple-dmabuf-v4l.c | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/clients/simple-dmabuf-v4l.c b/clients/simple-dmabuf-v4l.c index af25d0ea..6f41b2a7 100644 --- a/clients/simple-dmabuf-v4l.c +++ b/clients/simple-dmabuf-v4l.c @@ -351,21 +351,67 @@ static const struct zwp_linux_buffer_params_v1_listener params_listener = { create_failed }; +static bool +check_v4l2_control_bool(const int fd, + const struct v4l2_query_ext_ctrl *qectrl, + const char *control_name, + const int expected_value) +{ + struct v4l2_control ctrl; + + memset(&ctrl, 0, sizeof(ctrl)); + ctrl.id = qectrl->id; + + if (qectrl->flags & V4L2_CTRL_FLAG_DISABLED) + return false; + + if (!(qectrl->type == V4L2_CTRL_TYPE_BOOLEAN)) + return false; + + if (strcmp(qectrl->name, control_name)) + return false; + + /* with the early-outs out of the way, do the actual check */ + if (xioctl(fd, VIDIOC_G_CTRL, &ctrl)) + return false; + + if (ctrl.value != expected_value) + return false; + + return true; +} + 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_bool(display->v4l_fd, &qectrl, + 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_bool(display->v4l_fd, &qectrl, + 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 +428,7 @@ create_dmabuf_buffer(struct display *display, struct buffer *buffer) display->format.width, display->format.height, display->drm_format, - flags); + lbp_flags); } static int |