1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
From 7ec008222fcb4682fa2cfdbb62e657bf98950ec5 Mon Sep 17 00:00:00 2001
From: Naushir Patuck <naush@raspberrypi.com>
Date: Tue, 19 May 2020 15:56:47 +0100
Subject: [PATCH] staging: vc04_services: isp: Fixup g/s_selection
implementation
Add V4L2_SEL_TGT_CROP_DEFAULT and V4L2_SEL_TGT_CROP_BOUND targets.
Disable the appropriate ioctls for the meta capture nodes - this now
passes v4l2-compliance tests.
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
---
.../bcm2835-isp/bcm2835-v4l2-isp.c | 84 ++++++++++++-------
1 file changed, 55 insertions(+), 29 deletions(-)
--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
+++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
@@ -1006,15 +1006,32 @@ static int bcm2835_isp_node_s_selection(
if (!s->r.width || !s->r.height)
return -EINVAL;
- /* Adjust the crop window if goes outside the frame dimensions. */
- s->r.left = min((unsigned int)max(s->r.left, 0),
- node->q_data.width - MIN_DIM);
- s->r.top = min((unsigned int)max(s->r.top, 0),
- node->q_data.height - MIN_DIM);
- s->r.width = max(min(s->r.width, node->q_data.width - s->r.left),
- MIN_DIM);
- s->r.height = max(min(s->r.height, node->q_data.height - s->r.top),
- MIN_DIM);
+ /* We can only set crop on the input. */
+ switch (s->target) {
+ case V4L2_SEL_TGT_CROP:
+ /*
+ * Adjust the crop window if it goes outside of the frame
+ * dimensions.
+ */
+ s->r.left = min((unsigned int)max(s->r.left, 0),
+ node->q_data.width - MIN_DIM);
+ s->r.top = min((unsigned int)max(s->r.top, 0),
+ node->q_data.height - MIN_DIM);
+ s->r.width = max(min(s->r.width,
+ node->q_data.width - s->r.left), MIN_DIM);
+ s->r.height = max(min(s->r.height,
+ node->q_data.height - s->r.top), MIN_DIM);
+ break;
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ /* Default (i.e. no) crop window. */
+ s->r.left = 0;
+ s->r.top = 0;
+ s->r.width = node->q_data.width;
+ s->r.height = node->q_data.height;
+ break;
+ default:
+ return -EINVAL;
+ }
crop.rect.x = s->r.left;
crop.rect.y = s->r.top;
@@ -1029,33 +1046,40 @@ static int bcm2835_isp_node_s_selection(
static int bcm2835_isp_node_g_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
+ struct mmal_parameter_crop crop;
struct bcm2835_isp_node *node = video_drvdata(file);
- struct bcm2835_isp_dev *dev = node_get_dev(node);
struct vchiq_mmal_port *port = get_port_data(node);
- struct mmal_parameter_crop crop;
+ struct bcm2835_isp_dev *dev = node_get_dev(node);
u32 crop_size = sizeof(crop);
int ret;
- /* This return value is required for V4L2 compliance. */
- if (node_is_stats(node))
- return -ENOTTY;
-
/* We can only return out an input crop. */
- if (s->target != V4L2_SEL_TGT_CROP)
- return -EINVAL;
-
- ret = vchiq_mmal_port_parameter_get(dev->mmal_instance, port,
- MMAL_PARAMETER_CROP,
- &crop, &crop_size);
- if (!ret)
- return -EINVAL;
-
- s->r.left = crop.rect.x;
- s->r.top = crop.rect.y;
- s->r.width = crop.rect.width;
- s->r.height = crop.rect.height;
+ switch (s->target) {
+ case V4L2_SEL_TGT_CROP:
+ ret = vchiq_mmal_port_parameter_get(dev->mmal_instance, port,
+ MMAL_PARAMETER_CROP,
+ &crop, &crop_size);
+ if (!ret) {
+ s->r.left = crop.rect.x;
+ s->r.top = crop.rect.y;
+ s->r.width = crop.rect.width;
+ s->r.height = crop.rect.height;
+ }
+ break;
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ /* Default (i.e. no) crop window. */
+ s->r.left = 0;
+ s->r.top = 0;
+ s->r.width = node->q_data.width;
+ s->r.height = node->q_data.height;
+ ret = 0;
+ break;
+ default:
+ ret = -EINVAL;
+ }
- return 0;
+ return ret;
}
static int bcm3285_isp_subscribe_event(struct v4l2_fh *fh,
@@ -1218,6 +1242,8 @@ static int register_node(struct bcm2835_
node->vfl_dir = VFL_DIR_RX;
node->name = "stats";
v4l2_disable_ioctl(&node->vfd, VIDIOC_S_CTRL);
+ v4l2_disable_ioctl(&node->vfd, VIDIOC_S_SELECTION);
+ v4l2_disable_ioctl(&node->vfd, VIDIOC_G_SELECTION);
break;
}
|